Blueforce-Linux/docs/05-ONE-CLICK-INSTALLER.md
emirhanmamak-blueforce e28783e563 feat(offline-repo): build the APT index so installs work without network
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.
2026-09-16 21:42:27 +03:00

18 KiB
Raw Blame History

05 — Tek-Tık Kurucu (One-Click Installer)

Kısa özet: Sahadaki tek giriş noktası grafik operatör uygulamasıdır: sudo bf → Kurulum sekmesi → "Bu cihazı kur". Bayi no doğrulaması, 18 modül, idempotent yeniden-koşu ve final-check kapısı blueforce-install.sh'ın işidir. Paketler git deposunda taşınır; kurulum internetsizdir. Terminal yedeği: sudo bf --tui.

  • Dosya: docs/05-ONE-CLICK-INSTALLER.md
  • İlgili kararlar: 24-DECISION-LOG.md#K-09 (tek kurucu), K-11 (update kapalı), K-12 (kimlik formatı), K-03 (bf-gui), K-10 (Docker disiplini), K-16 (offline)
  • İlgili dokümanlar: 33-OPERATOR-CONSOLE.md (arayüz rehberi), 27-OFFLINE-PROVISIONING.md (paket deposu sözleşmesi)
  • Durum: [ ] Taslak

1. Amaç

Saha teknisyeninin uzmanlık gerektirmeden cihazı standarda getirmesi: tek giriş noktası (sudo bf), tek girdi (8 haneli bayi no), net sonuç (PROVISIONED_OFFLINE / hata + neden). Yarım kalan veya hatalı kurulumun güvenli tekrarı.

Teknisyen terminal komutu, bayrak veya dosya yolu ezberlemez: kurulum grafik arayüzdeki düğmeyle başlatılır, komut arayüzde gösterilir ve onay alınmadan çalıştırılmaz.

2. Kapsam

  • Kapsam içi: grafik uygulama üzerinden kurulum akışı, kurucu betiğin komut yüzeyi, bayi-no doğrulama, 18 modül listesi ve sırası, paket deposu keşfi ve hata durumları, idempotency kuralları, log/çıkış kodları.
  • Kapsam dışı: modül iç kodları (repo scripts/install/installer/modules/), imaj üretim yöntemi (04), filo-side yapılandırma (09), arayüzün tüm ekranları (33).

3. Kararlar

KARAR:    Saha kurulumunun tek giriş noktası grafik operatör uygulamasıdır: `sudo bf` → Kurulum sekmesi → "Bu cihazı kur". Kurucu betik (`scripts/install/blueforce-install.sh`) bu düğmenin çağırdığı motordur ve aynı akış terminalden `sudo bf --tui` ile de yürütülebilir. Eski bash menü (`admin/bf-menu`) yedek yoldur, ana yol değildir.
GEREKÇE:  Tek giriş noktası ve tek düğme teknisyen hatasını en aza indirir; grafik arayüz komutu çalıştırmadan önce gösterir ve onay ister, böylece görünmez komut kalmaz. Bayi no `^[0-9]{8}$` ile doğrulanır; format kapısı yanlış kimliğin 9 sisteme yayılmasını baştan engeller (K-12).
ALTERNATİF: Yalnız bash menülü kurulum (`admin/bf-menu`) — grafik arayüz yoksa çalışır ama sahadaki ana yolu oluşturmaz; yedek olarak korundu. Çok scriptli kurulum (ağ.sh, gui.sh, …) — sıra hatası ve atlanan adım riski nedeniyle elendi.
RİSK:     Tek dosya büyüdükçe bakımı zorlaşır; azaltma: 18 bağımsız modül + ana orkestratör ayrımı. Grafik arayüz `python3-tk` gerektirir; azaltma: paket offline depoda pinlidir ve ekransız/paketsiz ortamda uygulama Türkçe yönlendirme yapıp `--tui` önerir.
MALİYET:  Ücretsiz.
LİSANS:   Yok (şirket içi script + standart kütüphane ile yazılmış Python arayüz).
KARAR:    Kurucu 18 modülden oluşur (`01-precheck` … `18-final-check`); her modül idempotenttir — yeniden koşu güvenli ve kaldığı yerden tamamlayıcıdır. Paketler yerel paket deposundan gelir ve depo otomatik bulunur; `--offline` bayrağı zorunlu değildir.
GEREKÇE:  Saha elektriği/kesintisi yarım kurulum üretir; idempotency olmadan her kesinti temiz-kurulum demektir. Final-check kapısı (modül 18) exit 0 vermeden cihaz kurulu sayılmaz; offline akışta sonuç `PROVISIONED_OFFLINE`, token sonrası `ENROLLED`, yalnız merkezi kanallar doğrulanınca `READY` olur (27/29). Depoyu kuran kişinin hatırlaması gereken bayrak sayısı sıfırdır.
ALTERNATİF: Tek seferlik (non-idempotent) script — kesinti durumunda belirsiz ara durum nedeniyle elendi. `--offline` bayrağını zorunlu tutmak — operatör bayrağı unuttuğunda kurulum durur; bayrak geriye uyumluluk için korundu.
RİSK:     Modülün idempotent yazılmaması (çift kayıt, çift key); azaltma: §10'daki çift-koşu testi her modül için zorunlu.
MALİYET:  Ücretsiz.
LİSANS:   Yok.

4. Neden Bu Karar?

700 cihaz × teknisyen başına değişen beceri = kurulumun "tek düğme + tek soru" olması şarttır. Grafik arayüz bu düğmeyi verir; 18 modül ise her kararın (update-kapalı, Docker-disiplini, GUI-anahtarı, kimlik, servisler) ayrı denetlenebilir adımıdır. Modül numarası log satırında görünür, arıza hangi adımda kaldıysa oradan devam edilir; arayüz aynı durumu "Kurulum modül durumu" işlemiyle salt-okunur gösterir.

5. Alternatifler

Alternatif Artı Eksi Sonuç
Grafik arayüz + tek kurucu betik Tek giriş, komut ezberi yok, onay görünür Grafik katman gerekir (python3-tk, ekran) Seçildi
Yalnız bash menülü kurulum (admin/bf-menu) Grafik katman gerekmez Ana yol olarak terminal bilgisi ister; ekran yok Yedek yol
Çok scriptli kurulum Küçük dosyalar Sıra/atlama hatası Elendi
Non-idempotent tek script Daha basit kod Kesintide temiz-kurulum zorunluluğu Elendi
İnteraktif sihirbaz (çok sorulu) Esnek Teknisyen hatası, otomasyona kapalı Elendi

6. Avantajlar

  • Tek giriş noktası (sudo bf) = eğitim maliyeti minimum, runbook tek sayfa.
  • Idempotency = kesinti korkusu yok, "bir daha koş" her sorunun ilk cevabı.
  • Final-check = kurulum sonucu ölçülebilir, dalga kapılarına bağlanır.
  • İnternetsiz çalışır: paketler repoda gelir, kuran kişi hiçbir şey indirmez.

7. Dezavantajlar

  • 18 modülün her biri için idempotency testi yazma maliyeti.
  • Tek giriş noktası, modül-atlama (debug) ihtiyacında --from/--only/--resume bayraklarını zorunlu kılar.
  • Grafik arayüz python3-tk paketine ve bir grafik oturuma bağlıdır; bu ikisi yoksa operatör terminal konsoluna (sudo bf --tui) düşer.

8. Riskler

Risk Olasılık Etki Azaltma
Modül idempotent değil (çift kayıt) Orta Orta Çift-koşu testi (§10) + code review kuralı
Teknisyen yanlış no girer Orta Orta Format kapısı (^[0-9]{8}$) + onay ekranı (BF-12010193, onaylıyor musunuz?)
Kurucu yarıda kesilir, cihaz ara durumda sahaya alınır Düşük Yüksek Final-check exit 0 olmadan kurulum tamamlanmaz; arayüzdeki "Kurulum modül durumu" ve bf-status bunu gösterir
Grafik arayüz açılmaz (başsız oturum) Orta Düşük Uygulama Türkçe hata + sudo bf --tui önerir (19 §T-10)
python3-tk eksik kalır Düşük Orta Paket offline depoda pinli; 18-final-check tkinter'ı denetler ve eksikse WARN yazar

9. Uygulama Planı

1. Giriş noktası — grafik operatör uygulaması (ana yol)

sudo bf            # grafik arayüz (bfos paketi, bfos/ui_gui.py, Tkinter)

Akış:

  1. Pencere açılır: başlık Blueforce Field OS — Yönetim.
  2. Basit modda üç düğme vardır: Kur, Durum, Çıkış. Üstteki Detaylı mod ile 5 sekme açılır: Kurulum, Cihaz işlemleri, Merkez hazırlığı, Araçlar, Cihaz bilgisi.
  3. Üst çubuktaki Hedef > Bayi no (8 hane) alanına numara yazılır (örn. 12010193); format geçersizse arayüz uyarır ve komut üretilmez.
  4. Kurulum sekmesinde Bu cihazı kur (veya hiçbir şey yazmayan ön kontrol Kurulum ön kontrolü (--check)) seçilir.
  5. Arayüz komutu önce ekranda gösterir, sonra onay ister; onaylanmadan çalıştırılmaz. Yıkıcı işlemler ikinci kez sorar; production kapsamı ayrı onay ister.
  6. Kurulum çıktısı ekranda akar; bitince sonuç ve çıkış kodu görünür.

Bu cihazı kur işleminin iki opsiyonel seçeneği vardır: Yerel çevrimdışı depodan kur (--offline) ve Zaten OK olan modülleri atla (--resume). --offline işaretlenmese de varsayılan kaynak yerel depodur; bayrak yalnız niyeti sabitler.

2. Yedek yol — terminal konsolu

sudo bf --tui      # aynı uygulamanın terminal arayüzü (grafik ekran yoksa / tkinter yoksa)
  • DISPLAY ve WAYLAND_DISPLAY tanımlı değilse (SSH, başsız kurulum) uygulama Türkçe açıklama yazar ve çıkış kodu 3 ile sudo bf --tui önerir.
  • python3-tk kurulu değilse (tkinter import edilemiyor) aynı şekilde Türkçe hata + python3-tk kurulum ipucu verir ve çıkış kodu 3 ile terminal konsolunu önerir.
  • Eski bash menü sudo admin/bf-menu yalnız yedek yoldur; dokümanlarda ve iş akışında ana yol olarak kullanılmaz.

3. Yetki

  • sudo bf = tam yetki (kurulum, servis, firewall, Ansible).
  • Root değilse uygulama başlangıçta uyarır ve yalnız salt-okunur raporları çalıştırır: "Yönetici yetkisi yok: salt-okunur raporlar çalışır, kurulum ve değişiklik gerektiren işlemler kapalıdır. Tam yetki için: sudo bf". Yazma işlemleri hem arayüzde kapalıdır hem de çalıştırma katmanında reddedilir (onaylansa bile komut çalışmaz).

4. Bayi-no doğrulama

^[0-9]{8}$; uymazsa arayüz geçersiz numarayı reddeder ve kurucu komut üretilmez (doğrudan CLI kullanımında exit 2 + kullanım mesajı). Geçerliyse onay ekranında BF-12010193 + hostname bf-12010193 gösterilir.

5. 18 modül (sıra sözleşmedir, yeri scripts/install/installer/modules/)

# Modül İşlev
01 01-precheck Root, Ubuntu sürümü, RAM/disk ön kontrolü; ağ yalnız bilgi (kapı değil)
02 02-system Temel APT kaynakları, unattended-upgrades kapatma, saat dilimi (K-11)
03 03-user blueforce bakım kullanıcısı, kısıtlı sudoers, zorunlu yönetici anahtarı (K-13)
04 04-hostname Doğrulanmış bayi no'dan hostname bf-<no> (K-12)
05 05-network Ağ raporu: yerel bağlantı, rota/DNS (DNS zorunlu tutulmaz — offline kurulum)
06 06-wireguard Cihaz anahtar çifti; wg0.conf enrollment'ın işidir (K-05/K-17)
07 07-ssh Yönetici anahtarı doğrulandıktan sonra sshd sertleştirme
08 08-rdp xRDP + GNOME oturumu, terminale boot varsayılanı, multi-user (K-03/K-22)
09 09-rustdesk Yalnız pinli/sağlanan paketten RustDesk istemci (K-04)
10 10-docker Docker CE + rotasyonlu daemon.json + enable (K-10)
11 11-meg MEG yer tutucusu: vendor .deb varsa kurar, yoksa SKIP + kabul listesi
12 12-monitoring Node Exporter + textfile collector dizini (K-07)
13 13-firewall UFW deny-in tabanı + Docker yayın-portu politikasının kalıcılığı (K-05/K-10)
14 14-update-policy APT hold'ları + otomatik update zamanlayıcılarını kapatma (K-11)
15 15-logrotate journald tavanları + uygulama logrotate politikası (K-14)
16 16-gui GNOME minimal + bakım araçları; terminale boot varsayılanı (K-03)
17 17-healthcheck Teşhis ve enrollment komutlarını kurar; enrollment'ı çalıştırmaz
18 18-final-check Son yaşam döngüsü kapısı: offline yerelde tamamlanır, READY merkez kanıtı ister; tkinter denetimi (yoksa WARN)

Modül çıkış kodları: 0 OK, 3 SKIP (opsiyonel adım, yapılacak bir şey yok), diğer ≠ 0 FAIL.

6. Paket deposu — otomatik keşif, iki hata durumu, sıfır indirme

Installer paket deposunu kendi bulur; --offline bayrağı gerekmez (geriye uyumluluk için kabul edilir, yalnız yerel depoyu zorlar). Arama sırası (ilk eksiksiz aday kazanır):

  1. BF_OFFLINE_REPO ortam değişkeni (operatör/repo sorumlusu override'ı),
  2. <repo>/provisioning/offline-repo/built (git deposuyla gelen paket seti),
  3. /opt/blueforce/offline-repo (cihaza kurulmuş paket deposu).

Depo bulunduğunda ekrana Türkçe duyuru yazılır: Yerel paket deposu bulundu: <N> paket, <boyut> + Depo, Kaynak, Kip satırları. İki farklı başarısızlık vardır ve ikisinde de paket modüllerinden önce durulur, sistemde hiçbir değişiklik yapılmaz:

Durum Ekran Sonuç
Depo hiçbir yerde yok HATA: Yerel paket deposu yok. Repo sorumlusuna başvurun: provisioning/offline-repo/README.md + aranan yollar + ÇIKIŞ NEDENİ: yerel paket deposu bulunamadı. exit 1
Depo bulundu ama bozuk/eksik OFFLINE BLOCKED: <sebep> + Türkçe çıkış nedeni (ör. checksum uyuşmazlığı, eksik Packages/packages.lock.tsv, eksik pin) exit 1

Uzak APT kaynağı, curl, wget, anahtar indirme veya apt download çağrılmaz. Yalnız geliştirme/test için --online vardır ve üretim cihazlarında kullanılmaz (DİKKAT uyarısı yazar).

7. Kurucu betiğin komut yüzeyi (yedek/otomasyon)

sudo ./scripts/install/blueforce-install.sh --dealer-id 12010193 [--from 07] [--only 18-final-check] [--resume] [--check] [--yes]
# --check : değişiklik yapmadan denetim (final-check + modül durumları)
# --from  : belirtilen modülden devam et | --only: tek modül koş | --resume: OK modülleri atla
# --yes   : onay sormadan başla (otomasyon; GUI bu bayrağı kullanmaz)
# --offline: yerel depoyu zorla (varsayılan zaten yerel) | --online: yalnız geliştirme/test

8. Idempotency kuralları (her modül için zorunlu)

  • Varlık kontrolü önce (id blueforce, dpkg -l, systemctl is-enabled): varsa atla, yoksa kur.
  • Dosya yazımları atomik (tmp + rename) ve tekrarlanabilir (aynı girdi → aynı çıktı).
  • Anahtar/secret üretimi bir kez; --force olmadan yeniden üretilmez.
  • Her modül /var/log/blueforce-install.log dosyasına modül no + OK/SKIP/FAIL satırı yazar.

9. Çıkış kodları ve sonuç durumu

Kurucu betik: 0 başarı (offline akışta PROVISIONED_OFFLINE), 1 engellendi veya modül hatası (no logda), 2 argüman/format hatası. Grafik/terminal arayüz: 3 grafik katman yok (ekran veya python3-tk), 2 kullanım hatası (--tui + --gui birlikte verilemez), 0 normal kapanış.

READY bir kurucu çıkış kodu değildir: offline akış PROVISIONED_OFFLINE yazar, READY yalnız merkezi kanallar doğrulandığında (29/30) yazılır.

10. Test Planı

Test Beklenen sonuç Ortam
Geçersiz no (7/9 hane, harf, boş) Arayüz reddeder / CLI exit 2, kurulum başlamaz LAB(2)
sudo bf ile kurulum (grafik) Komut önce gösterilir, onay ister, kurulum PROVISIONED_OFFLINE ile biter LAB(2) masaüstü oturumu
DISPLAY yokken sudo bf Türkçe yönlendirme + sudo bf --tui önerisi, exit 3, sistem değişmez LAB(2) SSH
python3-tk yokken sudo bf Türkçe "tkinter bulunamadı" + paket ipucu, exit 3 LAB(2) minimal imaj
Her modülün çift-koşusu İkinci koşu exit 0, durum değişmez (diff boş) LAB(2)
Elektrik-kesintisi simülasyonu (modül 09 ortasında kill) --from 09 veya arayüzdeki --resume ile tamamlanır, final exit 0 LAB(2)
18-final-check tüm kapıları Eksik adımda FAIL + modül nosu, başarı damgası yok LAB(2)
--check kuru koşusu (GUI ön kontrol / CLI) Değişiklik yapmaz, rapor üretir P1(5)
Depo yokken kurulum denemesi Türkçe hata + aranan yollar + çıkış nedeni, exit 1, sistem değişmez LAB(2)
Depo bozukken kurulum denemesi OFFLINE BLOCKED: <sebep> + Türkçe çıkış nedeni, exit 1 LAB(2)

11. Rollback

  1. Modül hatası: arayüzdeki "Kurulum modül durumu"/log ile modül nosu bulunur; --from <no> veya arayüzdeki Başarısız kuruluma devam et (--resume) ile sürdürülür.
  2. Yanlış no: doğru no ile tam yeniden koşu (idempotent, hostname modülü üzerine yazar).
  3. Düzelmeyen cihaz: 17-RECOVERY LEVEL 9 (temiz imaj + kurucu).
  4. Paket deposu bozuksa sahada onarılmaz: repo sorumlusu depoyu yeniden üretip commit eder, güncel git tarafı çekilir ve komut tekrarlanır (27 §11).

12. Kontrol Listesi

  • 18 modül dosyası scripts/install/installer/modules/ altında numaralı ve çalışır durumda.
  • Grafik arayüzde Kurulum sekmesi ve Bu cihazı kur işlemi bayi-no kapısına bağlı.
  • Uygulama ekransız ortamda ve tkinter yokken Türkçe yönlendirme + --tui önerisi verip exit 3 ile çıkıyor.
  • Her modülde varlık-kontrolü + log satırı var.
  • Format regex'i 02 ile aynı (^[0-9]{8}$).
  • 18-final-check K-10/K-11 kapılarını ve tkinter denetimini içeriyor.
  • Depo keşif sırası ve iki hata durumu (yok / bozuk) ekranda Türkçe ve fail-closed.
  • --check/--from/--only/--resume bayrakları çalışıyor; --offline zorunlu değil.

13. Açık Sorular

  • Paket setinin sahaya taşınması: git clone (Git LFS) mı, repo sorumlusunun hazırladığı /opt/blueforce/offline-repo kopyası mı birincil? (sahibi: Faz 3, 04/27 yazarları ile ortak)
  • MEG sabit tag'inin kim tarafından, hangi onay ile güncelleneceği (sahibi: 10-UPDATE / 12-DOCKER yazarları).
  • Arayüzün grafik ekran gerektirmeyen cihazlarda varsayılan modu (--tui mi, grafik mi) — saha ölçümü ile karar (sahibi: 33 + saha operasyonu).

Ek: Kurulum Akışı (grafik arayüz)

flowchart TB
    CMD["sudo bf<br/>(grafik operatör uygulaması)"] --> EKRAN{"Grafik ekran +<br/>python3-tk var mı?"}
    EKRAN -->|Hayır| TUI["Türkçe yönlendirme + exit 3<br/>sudo bf --tui"]
    EKRAN -->|Evet| HEDEF["Hedef: Bayi no (8 hane)"]
    HEDEF --> FMT{"^[0-9]{8}$ ?"}
    FMT -->|Hayır| UYARI["Arayüz uyarır<br/>komut üretilmez"]
    FMT -->|Evet| KUR["Kurulum sekmesi<br/>'Bu cihazı kur'"]
    KUR --> ONAY["Komut gösterilir + onay<br/>(yıkıcı: ikinci onay)"]
    ONAY --> DEPO{"Yerel paket deposu aranır<br/>BF_OFFLINE_REPO → built → /opt/blueforce/offline-repo"}
    DEPO -->|"hiçbiri yok"| YOK["Türkçe hata + aranan yollar<br/>ÇIKIŞ NEDENİ: bulunamadı · exit 1"]
    DEPO -->|"bozuk/eksik"| BOZ["OFFLINE BLOCKED: sebep<br/>exit 1 · sistem değişmez"]
    DEPO -->|"eksiksiz"| M01["01-precheck … 17-healthcheck<br/>(idempotent modüller)"]
    M01 --> M18["18-final-check"]
    M18 -->|Hepsi OK| OFFLINE["PROVISIONED_OFFLINE"]
    M18 -->|FAIL| LOG["modül nosu + log yolu<br/>--from / --resume ile devam"]
    OFFLINE --> ENR["Token → ENROLLED"]
    ENR --> READY["Merkez kanalları doğrulandı → READY"]