The package pool was committed but the installer still stopped at "no local package repository": it requires the compiled bundle (Packages, Packages.gz, packages.lock.tsv, SHA256SUMS), and building that had never run. The bundle - 1321 packages, 884 MiB, Ubuntu 26.04 amd64, built with apt-ftparchive on the fleet's own release so the closure matches the devices. - built/pool/ is gitignored: those .deb files are already tracked once under provisioning/offline-repo/packages/, and the same ~890 MB does not need a second path. What the installer reads from the bundle is the index. - The output directory is chmod 0755: mktemp -d created it 0700 and left it so, which made a valid bundle unreadable to the installer's probe. dpkg-deb output was parsed wrong in four places - `dpkg-deb -f <file> Package Version` prints "<Field>: <value>", and the callers kept the whole line, so the value carried its label. build-index.sh therefore accepted no package at all and reported an empty pool; add-packages.sh rejected every real .deb as an invalid name, missed version conflicts, and copied a duplicate; build-offline-repo.sh never matched a pin. - The test suite could not see any of this: its dpkg-deb stub emitted bare values. The stub now prints the labels exactly as the real tool does, which is what surfaced the remaining three sites. Tests - The secret scan covers the files we author, not apt-ftparchive's index over third-party packages: polkit's own description reads "...asked for their password:", which is prose in the packages, not a leak. Any secret reaching a manifest, README or tool is still caught. - The "test build must not touch the bundle" assertion now compares the directory before and after instead of demanding it be empty, so a maintainer's real build is not reported as test spill.
213 lines
16 KiB
Markdown
213 lines
16 KiB
Markdown
# 27 — Offline Provisioning
|
||
|
||
> Kısa özet: Paketler **git deposunun içindedir** (`provisioning/offline-repo/packages/`, 1321 `.deb`, ~888 MB, Git LFS ile takip edilir). Saha kurulumu internet **gerektirmez** ve kuran kişi **hiçbir şey indirmez**: `sudo bf` → Kurulum sekmesi → "Bu cihazı kur" → 8 haneli bayi no → onay. 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, aranan yollar 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**. Grafik arayüz `python3-tk` paketine bağlıdır; bu paket offline depoda bilinçli olarak pinlidir (`manifests/base-packages.txt`).
|
||
> - İlgili kararlar: `24-DECISION-LOG.md#K-16`, `#K-09`, `#K-11`, `#K-12`
|
||
> - İlgili dokümanlar: `05-ONE-CLICK-INSTALLER.md` (kurucu), `33-OPERATOR-CONSOLE.md` (arayüz), `provisioning/offline-repo/README.md` (paket hazırlama)
|
||
> - Durum: [ ] Taslak
|
||
|
||
---
|
||
|
||
## 1. Amaç
|
||
|
||
Saha interneti kesik veya güvenilmezken tekrarlanabilir, denetlenebilir ve secretsiz ilk kurulumu tanımlamak. Kuran kişi paket aramaz, indirmez, bayrak ezberlemez: paket seti depoyla birlikte gelir.
|
||
|
||
## 2. Kapsam
|
||
|
||
- Kapsam içi: git checkout (paketler dahil) veya kurulmuş `/opt/blueforce/offline-repo`, offline APT bundle (`built/`), kurucunun yerel depoyu otomatik bulması, iki hata durumu, grafik arayüz üzerinden kurulum, `python3-tk` pini, durum damgası ve sonradan enrollment.
|
||
- Kapsam dışı: merkezi peer atama ve token doğrulama (29), release imzalama (30), paket setinin nasıl üretildiği (repo sorumlusunun işi, `provisioning/offline-repo/README.md`).
|
||
|
||
## 3. Kararlar
|
||
|
||
```text
|
||
KARAR: Paket seti git deposunda taşınır ve cihaz grafik arayüzden (`sudo bf` → Kurulum → "Bu cihazı kur") internetsiz kurulur; paket deposu 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. Kuran kişinin indirme yapmaması ve bayrak hatırlamaması saha hatasını ortadan kaldırır: yerel depo varsayılan ve tek 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. Grafik arayüzün `python3-tk` paketine bağımlılığı; paketin offline depoda pinlenmesi ve eksikliğinde `sudo bf --tui` yedeği ile azaltılır.
|
||
MALİYET: Ücretsiz (depo boyutu git tarafında ~888 MB).
|
||
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?
|
||
|
||
**Paketler artık ayrı bir medyada değil, bu git deposunda taşınır:** `provisioning/offline-repo/packages/` altında 1321 `.deb` (~888 MB) durur ve `.gitattributes` ile **Git LFS** üzerinden takip edilir (`*.deb filter=lfs ...`). Bu yüzden sahada "hangi paket nereden geldi?" sorusu ne internete ne de dış medyaya bağlıdır; aynı soru `packages.lock.tsv` ve `repo-manifest.yaml` ile yanıtlanır. Kuran kişi paket aramaz ve **indirmez**; klonladığı depo seti zaten taşır.
|
||
|
||
Durum makinesi, "kuruldu" ile "merkezce güvenildi" arasındaki farkı görünür yapar: offline kurulum yalnız `PROVISIONED_OFFLINE` üretir.
|
||
|
||
## 5. Alternatifler
|
||
|
||
| Alternatif | Artı | Eksi | Sonuç |
|
||
|---|---|---|---|
|
||
| Sürümlü offline APT bundle + repoda taşınan paketler | Tekrarlanabilir, indirme yok, medya lojistiği yok | Git deposu ~888 MB büyür (LFS) | **Seçildi** |
|
||
| Ayrı fiziksel seed USB medyası | Depo küçük kalır | Medya zimmeti/sürüm takibi, kaybolma riski | Yedek/geri dönüş yolu |
|
||
| 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; **kuran kişi hiçbir indirme yapmaz** ve bayrak ezberlemez.
|
||
- Paket manifesti ve kilit dosyası ile hangi sürümün yüklendiği kanıtlanır.
|
||
- Nesil farkı yoktur: repo sorumlusu paketleri bir kez commit eder, 700 cihaz aynı setten kurulur.
|
||
- Kurulum akışı grafik arayüzde tek düğmedir; terminal bilgisi gerekmez.
|
||
|
||
## 7. Dezavantajlar
|
||
|
||
- Git deposu paket setiyle birlikte büyür (LFS clone/pull maliyeti); derin clone sahada zaman alabilir.
|
||
- Offline cihaz merkezi izleme ve erişim kanalları doğrulanana kadar operasyonel olarak hazır değildir.
|
||
- Paket snapshot'ı yenilenmediği sürece güvenlik güncellemeleri geride kalır (onaysız update zaten yasak, K-11).
|
||
|
||
## 8. Riskler
|
||
|
||
| Risk | Olasılık | Etki | Azaltma |
|
||
|---|---|---|---|
|
||
| Eski güvenlik paketi | Orta | Orta | Süre sonu olan release medyası/repo sürümü, hızlı enrollment kuyruğu |
|
||
| Secret repoda kalır | Düşük | Yüksek | Secret taraması (test), 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, `BF_OFFLINE_REPO` ile açıkça yönlendirilebilir |
|
||
| Paketler var ama indeks (`built/`) yok | Orta | Yüksek | Kurucu fail-closed durur ("yerel paket deposu yok"); repo sorumlusu `build-index.sh` koşup `built/` dizinini commit eder |
|
||
| Grafik arayüz açılamıyor | Orta | Düşük | `python3-tk` offline depoda pinli; ekransız ortamda `sudo bf --tui` |
|
||
|
||
## 9. Uygulama Planı
|
||
|
||
1. Medya/repo manifesti: Field OS release, ISO checksum, offline APT snapshot kimliği, kurucu commit'i.
|
||
2. Paket setini **repo sorumlusu** hazırlar: `.deb` dosyalarını `add-packages.sh` ile `provisioning/offline-repo/packages/` altına koyar (Git LFS), pinleri `manifests/*.txt` içinde `package=version` olarak doldurur, `build-index.sh` ile `provisioning/offline-repo/built/` indeksini (`Packages`, `Packages.gz`, `packages.lock.tsv`, `SHA256SUMS`, `pool/`) üretir. 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 akışı (grafik arayüz — ana yol)
|
||
|
||
1. Depoyu getir: `git clone <repo>` (paketler Git LFS ile gelir) — veya repo sorumlusunun bıraktığı kopyada `/opt/blueforce/offline-repo` hazırdır.
|
||
2. `sudo bf` — pencere açılır: **Blueforce Field OS — Yönetim**.
|
||
3. Üst çubuk **Hedef > Bayi no (8 hane)** alanına numarayı yaz (örn. `12010193`).
|
||
4. **Kurulum** sekmesi → **`Bu cihazı kur`** (hiçbir şey yazmayan ön kontrol için: `Kurulum ön kontrolü (--check)`).
|
||
5. Komut ekranda gösterilir, onay istenir; onaylandıktan sonra kurulum çalışır. `--offline` işaretlemek **zorunlu değildir** (varsayılan kaynak zaten yerel depodur).
|
||
6. Sonuç: `PROVISIONED_OFFLINE`. Arayüzdeki **Kurulum modül durumu** ve `bf-status` ile doğrulanır.
|
||
|
||
```bash
|
||
# Ana yol (grafik arayüz)
|
||
sudo bf
|
||
# → Hedef: Bayi no (8 hane) → Kurulum sekmesi → "Bu cihazı kur"
|
||
|
||
# Yedek yol (grafik ekran yoksa veya python3-tk yoksa): aynı uygulamanın terminal arayüzü
|
||
sudo bf --tui
|
||
|
||
# Doğrudan kurucu ile (otomasyon / teşhis)
|
||
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 keşfi ve iki hata durumu
|
||
|
||
Sıra (ilk eksiksiz aday kazanır): `BF_OFFLINE_REPO` → `<repo>/provisioning/offline-repo/built` → `/opt/blueforce/offline-repo`. Bir aday "eksiksiz" sayılmak için `Packages`, `Packages.gz`, `packages.lock.tsv` ve `SHA256SUMS` dosyalarının hepsini içermelidir; yalnız `packages/` (ham `.deb` havuzu) yeterli **değildir** — indeksin `build-index.sh` ile üretilmiş olması gerekir.
|
||
|
||
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
|
||
|
||
Aranan yerler:
|
||
- depodaki hazır paket seti — yok: <repo>/provisioning/offline-repo/built
|
||
- cihazdaki kurulu paket deposu — yok: /opt/blueforce/offline-repo
|
||
|
||
Ne yapmalı:
|
||
1) Paket setini git ile tam olarak getirin ... ya da /opt/blueforce/offline-repo altına koyun.
|
||
2) Kurulumu yeniden çalıştırın.
|
||
|
||
Kuruluma hiç başlanmadı; sistemde hiçbir değişiklik yapılmadı.
|
||
Ç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.
|
||
|
||
### `python3-tk` neden offline depoda pinli?
|
||
|
||
Grafik operatör uygulaması Tkinter ile yazılmıştır ve tkinter Ubuntu'da **ayrı bir pakettir** (`python3-tk`); minimal Ubuntu Server kurulumunda Python vardır ama tkinter yoktur. İnternetsiz sahada `apt install python3-tk` **çalışmaz**, bu yüzden paket ve bağımlılık kümesi (`python3-tk`, `python3.14-tk`, `libtk8.6`) `provisioning/offline-repo/manifests/base-packages.txt` içinde pinlidir ve depodan gelir. Kurulum sonu kapısı `scripts/install/installer/modules/18-final-check.sh` tkinter'ı denetler; eksikse **WARN** yazar ve kurulumu düşürmez (cihaz yine kurulur, operatör terminal konsoluna `sudo bf --tui` ile devam eder).
|
||
|
||
## 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) |
|
||
| Grafik arayüzden kurulum | `sudo bf` → Kurulum → "Bu cihazı kur" ile `PROVISIONED_OFFLINE` | LAB(2) masaüstü oturumu |
|
||
| `BF_OFFLINE_REPO` ile başka dizin | Verilen dizin kullanılır; geçersizse durur | LAB(2) |
|
||
| Depo hiç yok | Türkçe hata + aranan yollar + `Ç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) |
|
||
| Yalnız `packages/` var, `built/` yok | Depo "yok" sayılır, kurulum başlamaz (fail-closed) | LAB(2) |
|
||
| `python3-tk` eksik imaj | `sudo bf` Türkçe hata + ipucu, exit 3; `18-final-check` WARN yazar, kurulum düş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ış repo sürümü geri çekilir; önceki onaylı manifestle 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.
|
||
5. Arayüz sorunuysa (ekran/tkinter) rollback gerekmez: `sudo bf --tui` ile aynı akış yürütülür.
|
||
|
||
## 12. Kontrol Listesi
|
||
|
||
- [ ] Paket seti repoda: `provisioning/offline-repo/packages/` (1321 `.deb`, Git LFS ile takip ediliyor).
|
||
- [ ] Bundle indeksi 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.
|
||
- [ ] Depoda/repoda cihaz kimliği, private key veya kalıcı token yok.
|
||
- [ ] `python3-tk` ve bağımlılıkları `manifests/base-packages.txt` içinde pinli; `18-final-check` tkinter'ı denetliyor.
|
||
- [ ] Kuran kişinin komutu `--offline` bayrağı istemiyor; depo otomatik bulunuyor.
|
||
- [ ] Grafik arayüz akışı (bayi no → Kurulum → "Bu cihazı kur") yazılı ve ekransız ortam için `sudo bf --tui` belgeli.
|
||
- [ ] İ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 paket seti yenileme sıklığı ve Git LFS bant genişliği/kotaysa sahaya taşıma yöntemi — sahibi: release yöneticisi.
|
||
- [ ] Paketlerin sahaya taşınmasında git clone mu, hazır `/opt/blueforce/offline-repo` kopyası mı birincil — sahibi: saha operasyonu + 05 yazarı.
|
||
- [ ] `--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["git checkout (paketler LFS ile)<br/>veya /opt/blueforce/offline-repo"] --> G["sudo bf → Kurulum → 'Bu cihazı kur'"]
|
||
G --> 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/>aranan yollar + ÇIKIŞ NEDENİ · 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"]
|
||
```
|