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

170 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```text
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ı):
```bash
# 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:
```text
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:
```text
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:
```text
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ışı
```mermaid
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"]
```