Blueforce-Linux/docs/27-OFFLINE-PROVISIONING.md
emirhanmamak-blueforce da460519e8 feat(install): internet-free install flow, auto-discovered local packages
The operator no longer answers an "offline?" question and no longer needs
network access: the installer finds the package set that ships with the
checkout, so the only input left is the dealer number.

Installer
- Auto-discover the local APT repository (BF_OFFLINE_REPO, then
  provisioning/offline-repo/built, then /opt/blueforce/offline-repo) and
  enter offline mode on its own; --offline stays for compatibility.
- Fail closed with an explicit Turkish message when nothing is found: the
  searched locations, what to do, and a named exit reason -- no state touched.
- Distinguish "repository absent" (operator error, actionable) from
  "repository present but invalid" (OFFLINE BLOCKED, verification gate).
- Network is informational only in precheck/network modules; no probe runs in
  offline mode and archive.ubuntu.com is no longer mandatory.

ISO builder
- Look for built/ first, which is what build-index.sh produces, and accept
  build/ as a warned legacy path. The two disagreed, so a medium could be
  built without the package set and fail only at install time.

Docs
- docs/27, scripts/install/README, provisioning/offline-repo/README and
  provisioning/firstboot/README describe the discovered flow, the two failure
  modes, and that the installer downloads nothing.

Tests
- check-admin-static exercised the "console missing from the clone" branch by
  deleting a tracked file; git clone restored it from history, so the branch
  never ran and the warning was effectively untested. Build the stripped
  source as a real commit instead; verified by mutation.
2026-09-16 16:53:24 +03:00

10 KiB
Raw Blame History

27 — Offline Provisioning

Kısa özet: İnternet yokken Field OS kurulumu ve yerel paket yüklemesi yapılabilir. Bu yol yalnız PROVISIONED_OFFLINE durumuna getirir; cihaz, tek kullanımlık enrollment token ve merkezi kanallar doğrulanmadan ENROLLED veya READY olmaz.

  • Dosya: docs/27-OFFLINE-PROVISIONING.md

Uygulama sözleşmesi: Kurucu, paket setini kendi kendine bulur ve varsayılan olarak yerel depodan kurar; --offline bayrağı artık gerekmez (geriye uyumluluk için kabul edilir, yalnız yerel depoyu zorlar). Arama sırası: (1) BF_OFFLINE_REPO ortam değişkeni, (2) <depo>/provisioning/offline-repo/built, (3) /opt/blueforce/offline-repo; ilk eksiksiz aday kazanır. Yerel file: APT kaynağı dışında hiçbir kaynak kullanılmaz: uzak APT source, curl, wget, anahtar indirme veya apt download çağrılmaz. İnternet kurulum için gerekmez. İki farklı başarısızlık vardır: depo hiç yoksa kurulum Türkçe bir hata ve ÇIKIŞ NEDENİ: yerel paket deposu bulunamadı. ile durur; depo bulunup da doğrulanamazsa (eksik Packages, Packages.gz, packages.lock.tsv, SHA256SUMS; checksum uyuşmazlığı; boş/bozuk kilit; eksik pin) OFFLINE BLOCKED: <sebep> ile durur. Her iki durumda da paket modüllerinden önce durulur, kurulum başlamaz ve sistemde hiçbir değişiklik yapılmaz. Paketler bu git deposunda taşınır ve repo sorumlusu tarafından add-packages.sh + build-index.sh ile bu depoya konur; kuran kişi hiçbir şey indirmez. Yalnız geliştirme/test için --online vardır ve üretim cihazlarında kullanılmaz.

  • İlgili kararlar: 24-DECISION-LOG.md#K-16, #K-09, #K-11, #K-12
  • Durum: [ ] Taslak

1. Amaç

Saha interneti kesik veya güvenilmezken tekrarlanabilir, denetlenebilir ve secretsiz ilk kurulumu tanımlamak.

2. Kapsam

  • Kapsam içi: seed USB veya git checkout, offline APT repository/snapshot, kurucunun yerel depoyu otomatik bulması, durum damgası ve sonradan enrollment.
  • Kapsam dışı: merkezi peer atama ve token doğrulama (29), release imzalama (30).

3. Kararlar

KARAR:    Offline kurulum, imzalı/sürümlü medya ya da git checkout ve ayrı offline APT kaynağıyla yapılır; paket seti kurucu tarafından otomatik bulunur ve sonuç durumu yalnızca PROVISIONED_OFFLINE'dır.
GEREKÇE:  Paket indirme veya merkezi API'ye erişim yokken cihaz standarda getirilebilir; fakat merkezde doğrulanmamış kimlik ve kanallar READY iddiası yapamaz. Operatörün hatırlaması gereken bayrak sayısı azaldıkça saha hatası azalır: yerel depo varsayılan kaynaktır.
ALTERNATİF: İnternet gelene kadar kurulum yapmama — saha ziyareti ve bekleme maliyeti nedeniyle elendi. Kurulumu `--offline` bayrağına bağlamak — operatör bayrağı unuttuğunda kurulum durur; otomatik keşif seçildi, bayrak geriye uyumluluk için korundu.
RİSK:     Eski veya karışık paket snapshot'ı; manifest, checksum ve release kimliği ile azaltılır. Yanlış/eski depo bulunması; arama sırası ve her adayda eksiksizlik denetimi ile azaltılır.
MALİYET:  Ücretsiz.
LİSANS:   APT — https://manpages.ubuntu.com/manpages/noble/en/man8/apt.8.html ; dpkg — https://manpages.ubuntu.com/manpages/noble/en/man1/dpkg.1.html ; Ubuntu offline kurulum ayrıntısı 26.04 için LAB doğrulamalıdır.

4. Neden Bu Karar?

Offline medya ve git deposu, işletim sistemi ve zorunlu paketleri taşır; merkezi sırları taşımamalıdır. Durum makinesi, "kuruldu" ile "merkezce güvenildi" arasındaki farkı görünür yapar. Paket setini repo sorumlusu hazırlayıp sürümlediği için sahada "hangi paket nereden geldi?" sorusu packages.lock.tsv ve repo-manifest.yaml ile yanıtlanır; kuran kişi paket aramaz ve indirmez.

5. Alternatifler

Alternatif Artı Eksi Sonuç
Sürümlü offline APT repo Tekrarlanabilir Medya yönetimi Seçildi
Rastgele .deb dosyaları İlk anda kolay Bağımlılık/sürüm belirsiz Elendi
İnternet bekleme Basit Saha blokajı Elendi
Yerel depoyu operatörün --offline bayrağıyla göstermesi Basit Bayrak unutulunca kurulum durur, saha hatası üretir Elendi (bayrak geriye uyumluluk için korundu)

6. Avantajlar

  • Bağlantısız sahada standarda yakın kurulum.
  • Paket manifesti ile hangi sürümün yüklendiği kanıtlanır.
  • Kurulum yapan kişi hiçbir indirme yapmaz ve bayrak ezberlemez: paketler zaten deponun içindedir, kurucu depoyu kendisi bulur.

7. Dezavantajlar

  • Medya sürümü ve paket snapshot'ı düzenli yenilenmelidir.
  • Offline cihaz merkezi izleme ve erişim kanalları doğrulanana kadar operasyonel olarak hazır değildir.

8. Riskler

Risk Olasılık Etki Azaltma
Eski güvenlik paketi Orta Orta Süre sonu olan release medyası, hızlı enrollment kuyruğu
Secret USB'ye yazılır Düşük Yüksek Secret taraması; token yalnız bir kez ve cihazda girilir
Yarım paket işlemi Orta Orta dpkg --configure -a, idempotent kurucu
Kurucu yanlış/eski depoyu bulur Düşük Orta Arama sırası sabittir; aday eksiksiz değilse kullanılmaz, en son BF_OFFLINE_REPO ile açıkça yönlendirilebilir

9. Uygulama Planı

  1. Medya manifesti: Field OS release, ISO checksum, seed checksum, offline APT snapshot kimliği, kurucu commit'i.
  2. Paket setini repo sorumlusu hazırlar: .deb dosyalarını add-packages.sh ile depoya koyar, build-index.sh ile provisioning/offline-repo/built indeksini üretir, packages.lock.tsv / SHA256SUMS / repo-manifest.yaml ile birlikte commit eder. Kuran kişi yalnız git tarafını çeker.
  3. Kurulumda yalnız genel paketler kullanılır; kurucu yerel depoyu otomatik bulur ve --offline gerekmez.
  4. Kurucu yerel durum dosyasına PROVISIONED_OFFLINE yazar; READY yazması yasaktır.
  5. İnternet geldiğinde 29'daki tek-kullanımlık token ile enrollment başlatılır; sonra merkezi kanallar test edilir.

Kuran kişinin komutu (bayrak yok, tek zorunlu bilgi bayi numarası):

# Konsoldan (önerilen): Python operatör konsolu; bash yedek yolu sudo bf-menu
sudo bf

# Doğrudan kurucu ile
sudo ./scripts/install/blueforce-install.sh --dealer-id 12010193

# Bilinçli olarak başka bir depo dizinini göstermek (nadir, repo sorumlusu isterse)
BF_OFFLINE_REPO=/mnt/blueforce-repo/built \
  sudo ./scripts/install/blueforce-install.sh --dealer-id 12010193

Depo bulunduğunda ekranda şu duyuru çıkar:

Yerel paket deposu bulundu: <N> paket, <boyut>
   Depo    : <dizin>
   Kaynak  : <bulunduğu yer>
   Kip     : yerel kurulum. İnternet, paket indirme ve ek anahtar gerekmez.

Depo hiçbir yerde yoksa kurulum başlamadan durur:

HATA: Yerel paket deposu yok. Repo sorumlusuna başvurun: provisioning/offline-repo/README.md
...
ÇIKIŞ NEDENİ: yerel paket deposu bulunamadı.

Depo bulundu ama doğrulanamadıysa (bozuk/eksik içerik) kurulum yine başlamaz:

OFFLINE BLOCKED: <sebep>
   Depo       : <dizin>
   Ne yapmalı : paket setini yeniden üretip git ile getirin (provisioning/offline-repo/README.md)
   ÇIKIŞ NEDENİ: yerel paket deposu doğrulanamadı; kurulum başlamadı ve
                 sistemde hiçbir değişiklik yapılmadı.

--online yalnız geliştirme/test makinesi içindir; paketleri internetten çeker ve üretim cihazlarında kullanılmaz.

10. Test Planı

Test Beklenen sonuç Ortam
İnternetsiz kurulum Paketler manifestten kurulur, dış indirme yok LAB(2) air-gapped
Depo yolu verilmeden kurulum Kurucu depoyu otomatik bulur (repo/built), duyuru satırını yazar LAB(2)
BF_OFFLINE_REPO ile başka dizin Verilen dizin kullanılır; geçersizse durur LAB(2)
Depo hiç yok Türkçe hata + ÇIKIŞ NEDENİ: yerel paket deposu bulunamadı., exit 1, sistem değişmez LAB(2)
Depo var ama bozuk (checksum/pin) OFFLINE BLOCKED: <sebep> + Türkçe çıkış nedeni, exit 1, sistem değişmez LAB(2)
DNS/WAN kesik Kurucu dış indirme istemez; 01-precheck ağı yalnız bilgi olarak yazar, 05-network DNS zorunlu tutmaz LAB(2)
--online üretimde denenmez Yalnız geliştirme/test; kurucu uyarı yazar LAB(2)
bf-status PROVISIONED_OFFLINE; READY değil LAB(2)
Bağlantı sonrası enrollment ENROLLED → READY kapıları çalışır LAB(2)

11. Rollback

  1. Paket işlemi bozuksa aynı onaylı snapshot ile dpkg --configure -a ve kurucu yeniden çalıştırılır.
  2. Yanlış medya sürümü geri çekilir; önceki onaylı medya manifestiyle yeniden kurulur.
  3. Yerel depo bozuksa sahada onarılmaz: repo sorumlusu depoyu yeniden üretip commit eder (add-packages.sh + build-index.sh), kurulum yapan kişi güncel git tarafını çekip komutu tekrarlar.
  4. Kimlik/token hatasında cihaz resetlenmez; 29'daki token iptal/yenileme prosedürü uygulanır.

12. Kontrol Listesi

  • Offline medya/git manifesti ve checksum'ları var.
  • Paket seti repoda: provisioning/offline-repo/built (Packages, Packages.gz, packages.lock.tsv, SHA256SUMS, pool/).
  • repo-manifest.yaml güncel; pin listesi ile paket havuzu uyuşuyor.
  • Medyada/depoda cihaz kimliği, private key veya kalıcı token yok.
  • Kuran kişinin komutu --offline bayrağı istemiyor; depo otomatik bulunuyor.
  • İnternet kapalıyken kurulum tamamlanıyor; dış indirme çağrısı yok.
  • PROVISIONED_OFFLINE görünür ve READY kapısı kapalı.
  • Sonradan enrollment sahibi/kuyruğu kayıtlı.

13. Açık Sorular

  • Offline APT snapshot yenileme sıklığı — sahibi: release yöneticisi.
  • Medyanın fiziksel zimmet ve imha süreci — sahibi: saha operasyonu.
  • Git checkout ile ISO/medya yolundan hangisinin birincil olduğu ve --online geliştirme yolunun hangi ortamlarda serbest olduğu — sahibi: yönetim + 26/33 yazarları.

Ek: Keşif ve durum akışı

flowchart LR
  M["ISO/seed veya git checkout<br/>+ repodaki offline APT"] --> D{"Kurucu yerel depoyu arar<br/>BF_OFFLINE_REPO → repo/built → /opt/blueforce/offline-repo"}
  D -->|"hiçbiri yok / eksik"| X["HATA: Yerel paket deposu yok<br/>ÇIKIŞ NEDENİ: bulunamadı · exit 1<br/>sistem değişmez"]
  D -->|"eksiksiz aday bulundu"| V{"Doğrulama katmanı:<br/>dosya listesi, SHA256SUMS, kilit, pin ↔ pool"}
  V -->|"başarısız"| B["OFFLINE BLOCKED: sebep<br/>ÇIKIŞ NEDENİ: doğrulanamadı · exit 1"]
  V -->|"geçti"| P["PROVISIONED_OFFLINE"]
  P --> T["Tek kullanımlık token"]
  T --> E["ENROLLED"]
  E --> C["WG + erişim + izleme doğrulama"]
  C --> R["READY"]