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.
This commit is contained in:
parent
1387186b03
commit
da460519e8
9 changed files with 509 additions and 99 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
>
|
>
|
||||||
> - Dosya: `docs/27-OFFLINE-PROVISIONING.md`
|
> - Dosya: `docs/27-OFFLINE-PROVISIONING.md`
|
||||||
>
|
>
|
||||||
> **Uygulama sözleşmesi:** `--offline`, varsayılan `/opt/blueforce/offline-repo` içindeki yalnız yerel `file:` APT kaynağını kullanır; uzak APT source, curl, wget, key download veya `apt download` çağrısı yapmaz. `Packages`, `Packages.gz`, `SHA256SUMS`, `packages.lock.tsv` ve her manifest için somut `package=version` pinleri eksikse paket modüllerinden önce `OFFLINE BLOCKED` ile durur. Bu repoda gerçek paket/pin bulunmadığından üretilen ISO LAB-only'dir ve provision edilmiş olarak temsil edilmez.
|
> **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`
|
> - İlgili kararlar: `24-DECISION-LOG.md#K-16`, `#K-09`, `#K-11`, `#K-12`
|
||||||
> - Durum: [ ] Taslak
|
> - Durum: [ ] Taslak
|
||||||
|
|
||||||
|
|
@ -16,23 +16,23 @@ Saha interneti kesik veya güvenilmezken tekrarlanabilir, denetlenebilir ve secr
|
||||||
|
|
||||||
## 2. Kapsam
|
## 2. Kapsam
|
||||||
|
|
||||||
- Kapsam içi: seed USB, offline APT repository/snapshot, kurucu, durum damgası ve sonradan enrollment.
|
- 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).
|
- Kapsam dışı: merkezi peer atama ve token doğrulama (29), release imzalama (30).
|
||||||
|
|
||||||
## 3. Kararlar
|
## 3. Kararlar
|
||||||
|
|
||||||
```text
|
```text
|
||||||
KARAR: Offline kurulum, imzalı/sürümlü medya ve ayrı offline APT kaynağıyla yapılır; sonuç durumu yalnızca PROVISIONED_OFFLINE'dır.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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?
|
## 4. Neden Bu Karar?
|
||||||
|
|
||||||
Offline medya, 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.
|
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
|
## 5. Alternatifler
|
||||||
|
|
||||||
|
|
@ -41,11 +41,13 @@ Offline medya, işletim sistemi ve zorunlu paketleri taşır; merkezi sırları
|
||||||
| Sürümlü offline APT repo | Tekrarlanabilir | Medya yönetimi | **Seçildi** |
|
| 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 |
|
| Rastgele `.deb` dosyaları | İlk anda kolay | Bağımlılık/sürüm belirsiz | Elendi |
|
||||||
| İnternet bekleme | Basit | Saha blokajı | 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
|
## 6. Avantajlar
|
||||||
|
|
||||||
- Bağlantısız sahada standarda yakın kurulum.
|
- Bağlantısız sahada standarda yakın kurulum.
|
||||||
- Paket manifesti ile hangi sürümün yüklendiği kanıtlanır.
|
- 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
|
## 7. Dezavantajlar
|
||||||
|
|
||||||
|
|
@ -59,28 +61,70 @@ Offline medya, işletim sistemi ve zorunlu paketleri taşır; merkezi sırları
|
||||||
| Eski güvenlik paketi | Orta | Orta | Süre sonu olan release medyası, hızlı enrollment kuyruğu |
|
| 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 |
|
| 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 |
|
| 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ı
|
## 9. Uygulama Planı
|
||||||
|
|
||||||
1. Medya manifesti: Field OS release, ISO checksum, seed checksum, APT snapshot kimliği, kurucu commit'i.
|
1. Medya manifesti: Field OS release, ISO checksum, seed checksum, offline APT snapshot kimliği, kurucu commit'i.
|
||||||
2. Kurulumda yalnız genel paketler ve `blueforce-install.sh --offline` kullanılır.
|
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. Kurucu yerel durum dosyasına `PROVISIONED_OFFLINE` yazar; `READY` yazması yasaktır.
|
3. Kurulumda yalnız genel paketler kullanılır; kurucu yerel depoyu **otomatik bulur** ve `--offline` gerekmez.
|
||||||
4. İnternet geldiğinde 29'daki tek-kullanımlık token ile enrollment başlatılır; sonra merkezi kanallar test edilir.
|
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
|
```bash
|
||||||
sudo mount /dev/sdX1 /mnt/blueforce-repo
|
# Konsoldan (önerilen): Python operatör konsolu; bash yedek yolu sudo bf-menu
|
||||||
sudo apt -o Dir::Etc::sourcelist=/mnt/blueforce-repo/sources.list update
|
sudo bf
|
||||||
sudo dpkg --configure -a
|
|
||||||
sudo ./blueforce-install.sh --offline --dealer-id 12010193
|
# Doğrudan kurucu ile
|
||||||
bf-status # PROVISIONED_OFFLINE beklenir
|
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ı
|
## 10. Test Planı
|
||||||
|
|
||||||
| Test | Beklenen sonuç | Ortam |
|
| Test | Beklenen sonuç | Ortam |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| İnternetsiz kurulum | Paketler manifestten kurulur | LAB(2) air-gapped |
|
| İnternetsiz kurulum | Paketler manifestten kurulur, dış indirme yok | LAB(2) air-gapped |
|
||||||
| DNS/WAN kesik | Kurucu dış indirme istemez | LAB(2) |
|
| 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) |
|
| `bf-status` | `PROVISIONED_OFFLINE`; READY değil | LAB(2) |
|
||||||
| Bağlantı sonrası enrollment | ENROLLED → READY kapıları çalışır | LAB(2) |
|
| Bağlantı sonrası enrollment | ENROLLED → READY kapıları çalışır | LAB(2) |
|
||||||
|
|
||||||
|
|
@ -88,12 +132,17 @@ bf-status # PROVISIONED_OFFLINE beklenir
|
||||||
|
|
||||||
1. Paket işlemi bozuksa aynı onaylı snapshot ile `dpkg --configure -a` ve kurucu yeniden çalıştırılır.
|
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.
|
2. Yanlış medya sürümü geri çekilir; önceki onaylı medya manifestiyle yeniden kurulur.
|
||||||
3. Kimlik/token hatasında cihaz resetlenmez; 29'daki token iptal/yenileme prosedürü uygulanır.
|
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
|
## 12. Kontrol Listesi
|
||||||
|
|
||||||
- [ ] Offline medya manifesti ve checksum'ları var.
|
- [ ] Offline medya/git manifesti ve checksum'ları var.
|
||||||
- [ ] Medyada cihaz kimliği, private key veya kalıcı token yok.
|
- [ ] 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ı.
|
- [ ] `PROVISIONED_OFFLINE` görünür ve READY kapısı kapalı.
|
||||||
- [ ] Sonradan enrollment sahibi/kuyruğu kayıtlı.
|
- [ ] Sonradan enrollment sahibi/kuyruğu kayıtlı.
|
||||||
|
|
||||||
|
|
@ -101,16 +150,21 @@ bf-status # PROVISIONED_OFFLINE beklenir
|
||||||
|
|
||||||
- [ ] Offline APT snapshot yenileme sıklığı — sahibi: release yöneticisi.
|
- [ ] Offline APT snapshot yenileme sıklığı — sahibi: release yöneticisi.
|
||||||
- [ ] Medyanın fiziksel zimmet ve imha süreci — sahibi: saha operasyonu.
|
- [ ] 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: Durum akışı
|
## Ek: Keşif ve durum akışı
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart LR
|
flowchart LR
|
||||||
M["ISO + seed + offline APT"] --> P["PROVISIONED_OFFLINE"]
|
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"]
|
P --> T["Tek kullanımlık token"]
|
||||||
T --> E["ENROLLED"]
|
T --> E["ENROLLED"]
|
||||||
E --> V["WG + erişim + izleme doğrulama"]
|
E --> C["WG + erişim + izleme doğrulama"]
|
||||||
V --> R["READY"]
|
C --> R["READY"]
|
||||||
```
|
```
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Bu dizin, cihazın ilk açılışında sahada çalışan giriş noktasını barındırır:
|
Bu dizin, cihazın ilk açılışında sahada çalışan giriş noktasını barındırır:
|
||||||
|
|
||||||
- `bf-firstboot` — bayi numarasını toplayan/doğrulayan ve yerel offline kurucuyu bir kez çalıştıran script.
|
- `bf-firstboot` — bayi numarasını toplayan/doğrulayan ve yerel offline kurucuyu bir kez çalıştıran script. Kurucu paket deposunu kendisi bulur; internet gerekmez, teknisyen hiçbir şey indirmez.
|
||||||
- `blueforce-firstboot.service` — boot'ta script'i bir kez çalıştıran systemd unit'i.
|
- `blueforce-firstboot.service` — boot'ta script'i bir kez çalıştıran systemd unit'i.
|
||||||
- Bu doküman — gerçek davranış, otomasyon yolu, kimlik değişimi prosedürü ve secret kuralları.
|
- Bu doküman — gerçek davranış, otomasyon yolu, kimlik değişimi prosedürü ve secret kuralları.
|
||||||
|
|
||||||
|
|
@ -89,9 +89,27 @@ Ortam değişkenleri: `BF_FIRSTBOOT_MARKER` (marker yolu), `STATE_DIR` (varsayı
|
||||||
- Marker yalnız kurucu başarıyla bittikten sonra yazılır (`set -euo pipefail` sayesinde hata hâlinde yazılmaz).
|
- Marker yalnız kurucu başarıyla bittikten sonra yazılır (`set -euo pipefail` sayesinde hata hâlinde yazılmaz).
|
||||||
- Önceki koşu yarıda kaldıysa (`$STATE_DIR/install-state` dolu) kurucu `--resume` ile çağrılır:
|
- Önceki koşu yarıda kaldıysa (`$STATE_DIR/install-state` dolu) kurucu `--resume` ile çağrılır:
|
||||||
kurucu `--offline --dealer-id <no> --yes` (+ gerekirse `--resume`) argümanlarıyla koşar.
|
kurucu `--offline --dealer-id <no> --yes` (+ gerekirse `--resume`) argümanlarıyla koşar.
|
||||||
- Script her zaman kurucuyu `--offline` ile çağırır; kurucu `PROVISIONED_OFFLINE` durumuna tamamlar.
|
- Script kurucuyu `--offline` ile çağırır. **Bu bayrak artık zorunlu değildir**: kurucu yerel
|
||||||
|
paket deposunu kendisi bulur (`BF_OFFLINE_REPO` → `<depo>/provisioning/offline-repo/built` →
|
||||||
|
`/opt/blueforce/offline-repo`). firstboot bayrağı geriye uyumluluk için verir; sonuç aynıdır:
|
||||||
|
yerel depodan, internet olmadan kurulum ve `PROVISIONED_OFFLINE` durumu.
|
||||||
- `--check` hiçbir dosya/dizin/log üretmez ve kurucuyu çağırmaz.
|
- `--check` hiçbir dosya/dizin/log üretmez ve kurucuyu çağırmaz.
|
||||||
|
|
||||||
|
### Depo bulunamazsa / doğrulanamazsa
|
||||||
|
|
||||||
|
firstboot kurucuyu çağırır; paket deposuna ilişkin karar ve mesaj **kurucunun** sorumluluğundadır.
|
||||||
|
İki farklı durum vardır ve ikisinde de firstboot marker **yazmaz** (cihaz provision edilmiş sayılmaz):
|
||||||
|
|
||||||
|
| Durum | Kim söyler | Ekranda ne görünür (kısaltılmış) | Sonuç |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Yerel depo hiç yok (üç arama yerinde de yok) | Kurucu | `HATA: Yerel paket deposu yok. Repo sorumlusuna başvurun: provisioning/offline-repo/README.md` … `ÇIKIŞ NEDENİ: yerel paket deposu bulunamadı.` | `exit 1`; hiçbir şey değişmez |
|
||||||
|
| Depo bulundu ama doğrulanamadı (checksum, kilit, eksik pin) | Kurucu | `OFFLINE BLOCKED: <sebep>` … `ÇIKIŞ NEDENİ: yerel paket deposu doğrulanamadı…` | `exit 1`; hiçbir şey değişmez |
|
||||||
|
| Admin public key eksik/geçersiz | firstboot'un kendi kapısı | `OFFLINE BLOCKED: seed-provided BF_ADMIN_PUBLIC_KEY_FILE is required.` (veya anahtar kuralı satırı) | `exit 1`; kurucu hiç çağrılmaz |
|
||||||
|
|
||||||
|
Çözüm sahadaki teknisyenin işi değildir: mesajı repo sorumlusuna iletmek ve depo düzeltildikten
|
||||||
|
sonra kurulumu tekrar çalıştırmak yeterlidir. Kurulumu yapan kişi hiçbir şey indirmez; paketler
|
||||||
|
git deposunda taşınır.
|
||||||
|
|
||||||
## 4. Kimlik değişimi prosedürü (admin / recovery — varsayılan KAPALI)
|
## 4. Kimlik değişimi prosedürü (admin / recovery — varsayılan KAPALI)
|
||||||
|
|
||||||
Bayi numarası değişimi **sıradan kullanıcı yolu değildir**. Wizard ve normal koşu bu yolu içermez.
|
Bayi numarası değişimi **sıradan kullanıcı yolu değildir**. Wizard ve normal koşu bu yolu içermez.
|
||||||
|
|
@ -120,9 +138,15 @@ Değişimden sonra `docs/02-DEVICE-NAMING-AND-INVENTORY.md` §9'daki yeniden-num
|
||||||
- Script secret **loglamaz**: mesajlarda yalnız dosya yolları ve cihaz kimlikleri geçer; anahtar içeriği,
|
- Script secret **loglamaz**: mesajlarda yalnız dosya yolları ve cihaz kimlikleri geçer; anahtar içeriği,
|
||||||
token, parola hiçbir satıra yazılmaz (`--force-reidentity` audit kaydı da yalnız kimlikleri yazar).
|
token, parola hiçbir satıra yazılmaz (`--force-reidentity` audit kaydı da yalnız kimlikleri yazar).
|
||||||
- Wizard girdisi ekrana yankılanır (teknisyen yazar); bu ekran token/parola istemez, yalnız bayi numarası alır.
|
- Wizard girdisi ekrana yankılanır (teknisyen yazar); bu ekran token/parola istemez, yalnız bayi numarası alır.
|
||||||
- ISO'da geçerli yerel APT indeksleri, checksum/lock ve tüm somut pinli paketler yoksa işlem
|
- Kurucu, yerel paket deposunu kendisi bulur (`BF_OFFLINE_REPO` → `<depo>/provisioning/offline-repo/built`
|
||||||
`OFFLINE BLOCKED` ile durur ve cihaz provision edilmiş sayılmaz. Yalnız offline bundle + public-key
|
→ `/opt/blueforce/offline-repo`); `--offline` bayrağı gerekmez. Internet kurulum için gerekmez.
|
||||||
önkoşulları geçerse `PROVISIONED_OFFLINE` yazılır.
|
Public-key önkoşulu geçtikten sonra:
|
||||||
|
* depo hiç yoksa kurucu Türkçe `HATA: Yerel paket deposu yok…` + `ÇIKIŞ NEDENİ: yerel paket deposu bulunamadı.` ile durur;
|
||||||
|
* depo bulunup da doğrulanamazsa (geçerli yerel APT indeksleri, checksum/lock ya da tüm somut
|
||||||
|
pinli paketler eksik/bozuk) kurucu `OFFLINE BLOCKED: <sebep>` ile durur.
|
||||||
|
Her iki durumda cihaz provision edilmiş sayılmaz ve firstboot marker yazmaz. Yalnız yerel depo
|
||||||
|
+ public-key önkoşulları geçerse `PROVISIONED_OFFLINE` yazılır. Ayrıntı: §3 ve
|
||||||
|
`provisioning/offline-repo/README.md` §3.
|
||||||
|
|
||||||
## 6. systemd unit ve boot'u kilitlememe
|
## 6. systemd unit ve boot'u kilitlememe
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,11 @@ AUTOINSTALL_DIR="$PROVISIONING_DIR/autoinstall"
|
||||||
FIRSTBOOT_DIR="$PROVISIONING_DIR/firstboot"
|
FIRSTBOOT_DIR="$PROVISIONING_DIR/firstboot"
|
||||||
RELEASE_DIR="$PROVISIONING_DIR/release"
|
RELEASE_DIR="$PROVISIONING_DIR/release"
|
||||||
OFFLINE_REPO_DIR="$PROVISIONING_DIR/offline-repo"
|
OFFLINE_REPO_DIR="$PROVISIONING_DIR/offline-repo"
|
||||||
OFFLINE_AUTODETECT="$OFFLINE_REPO_DIR/build"
|
OFFLINE_AUTODETECT="$OFFLINE_REPO_DIR/built"
|
||||||
|
# `build-index.sh` writes to built/. Older tooling in this repository used
|
||||||
|
# build/, so accept that as a second candidate rather than silently building a
|
||||||
|
# medium without the package set.
|
||||||
|
OFFLINE_AUTODETECT_LEGACY="$OFFLINE_REPO_DIR/build"
|
||||||
DEFAULT_DIST="$REPO_ROOT/dist"
|
DEFAULT_DIST="$REPO_ROOT/dist"
|
||||||
MEDIA_PREFIX="/blueforce-provisioning"
|
MEDIA_PREFIX="/blueforce-provisioning"
|
||||||
FIRSTBOOT_PATH="$MEDIA_PREFIX/firstboot"
|
FIRSTBOOT_PATH="$MEDIA_PREFIX/firstboot"
|
||||||
|
|
@ -60,7 +64,7 @@ Options:
|
||||||
--version VERSION Field OS version (default: provisioning/iso/field-os-version)
|
--version VERSION Field OS version (default: provisioning/iso/field-os-version)
|
||||||
--offline-repo DIR Built offline APT repository to embed (Packages, Packages.gz,
|
--offline-repo DIR Built offline APT repository to embed (Packages, Packages.gz,
|
||||||
SHA256SUMS, packages.lock.tsv). Default: auto-detect
|
SHA256SUMS, packages.lock.tsv). Default: auto-detect
|
||||||
provisioning/offline-repo/build, else build without it.
|
provisioning/offline-repo/built, else build without it.
|
||||||
--require-offline-repo Fail closed when no built offline repository is available
|
--require-offline-repo Fail closed when no built offline repository is available
|
||||||
--volid LABEL ISO volume label (default: the upstream label, preserved so the
|
--volid LABEL ISO volume label (default: the upstream label, preserved so the
|
||||||
live-media discovery path stays untouched; recorded in the manifest)
|
live-media discovery path stays untouched; recorded in the manifest)
|
||||||
|
|
@ -225,13 +229,16 @@ resolve_offline_repo() {
|
||||||
[[ -d "$OFFLINE_REPO" ]] || die "Offline repository directory not found: $OFFLINE_REPO"
|
[[ -d "$OFFLINE_REPO" ]] || die "Offline repository directory not found: $OFFLINE_REPO"
|
||||||
elif [[ -z "$OFFLINE_REPO" && -d "$OFFLINE_AUTODETECT" ]]; then
|
elif [[ -z "$OFFLINE_REPO" && -d "$OFFLINE_AUTODETECT" ]]; then
|
||||||
OFFLINE_REPO="$OFFLINE_AUTODETECT"
|
OFFLINE_REPO="$OFFLINE_AUTODETECT"
|
||||||
|
elif [[ -z "$OFFLINE_REPO" && -d "$OFFLINE_AUTODETECT_LEGACY" ]]; then
|
||||||
|
OFFLINE_REPO="$OFFLINE_AUTODETECT_LEGACY"
|
||||||
|
warn "Using the legacy offline repository path ${OFFLINE_AUTODETECT_LEGACY#"$REPO_ROOT"/}; build-index.sh writes to built/ instead."
|
||||||
else
|
else
|
||||||
OFFLINE_REPO=""
|
OFFLINE_REPO=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "$OFFLINE_REPO" ]]; then
|
if [[ -z "$OFFLINE_REPO" ]]; then
|
||||||
if [[ "$REQUIRE_OFFLINE" -eq 1 ]]; then
|
if [[ "$REQUIRE_OFFLINE" -eq 1 ]]; then
|
||||||
die "No built offline APT repository found (looked at ${OFFLINE_AUTODETECT#"$REPO_ROOT"/} and --offline-repo). Build one with provisioning/offline-repo/build-offline-repo.sh, then retry."
|
die "No built offline APT repository found (looked at ${OFFLINE_AUTODETECT#"$REPO_ROOT"/} and --offline-repo). Build one with provisioning/offline-repo/build-index.sh, then retry."
|
||||||
fi
|
fi
|
||||||
OFFLINE_MODE="not-included"
|
OFFLINE_MODE="not-included"
|
||||||
warn "No built offline APT repository is embedded: the medium ships the offline tooling and manifests only."
|
warn "No built offline APT repository is embedded: the medium ships the offline tooling and manifests only."
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ paketlerini ve bunların APT indeksini **bu git deposunun içinde** taşır.
|
||||||
| Rol | Kimdir | Ne yapar |
|
| Rol | Kimdir | Ne yapar |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Repo sorumlusu | bu depoyu yöneten kişi | Ubuntu 26.04 makinesinde paketleri toplar, doğrular, indeksi üretir, commit eder |
|
| Repo sorumlusu | bu depoyu yöneten kişi | Ubuntu 26.04 makinesinde paketleri toplar, doğrular, indeksi üretir, commit eder |
|
||||||
| Kuran kişi | sahada cihazı kuran teknisyen | ISO/seed ile kurar, `blueforce-install.sh --offline` çalıştırır; paket aramaz, indirmez |
|
| Kuran kişi | sahada cihazı kuran teknisyen | ISO/seed ile kurar, `blueforce-install.sh --dealer-id <no>` çalıştırır (kurucu yerel depoyu kendisi bulur); paket aramaz, depoyu göstermek veya indirmek zorunda değildir |
|
||||||
|
|
||||||
## Dosya haritası
|
## Dosya haritası
|
||||||
|
|
||||||
|
|
@ -231,47 +231,131 @@ cd built && sha256sum -c SHA256SUMS # OK görmelisiniz
|
||||||
|
|
||||||
* Saha cihazında internet yok (ya da güvenilmez). Bu yüzden kurulumun ihtiyaç
|
* Saha cihazında internet yok (ya da güvenilmez). Bu yüzden kurulumun ihtiyaç
|
||||||
duyduğu her şey **medyanın ve git deposunun içinde** taşınır.
|
duyduğu her şey **medyanın ve git deposunun içinde** taşınır.
|
||||||
* Kurucu `--offline` ile çalıştığında tek kaynak şudur:
|
* Kurucu paket setini **kendi kendine bulur**; `--offline` bayrağı artık
|
||||||
`/opt/blueforce/offline-repo` dizinine konan yerel depo
|
gerekmez (geriye uyumluluk için duruyor ve yalnızca yerel depoyu zorlar).
|
||||||
(`deb [trusted=yes] file:/opt/blueforce/offline-repo ./`). Uzak APT kaynağı,
|
Arama sırası — ilk eksiksiz aday kazanır:
|
||||||
anahtar indirme, `curl`, `wget`, `apt download` kullanılmaz.
|
|
||||||
* Bu dizin (git deposundaki `built/`) ISO ile hedefe taşınır ve kurucu şu
|
| Sıra | Yer | Ne zaman kullanılır |
|
||||||
dosyaları arar ve doğrular: `Packages`, `Packages.gz`, `packages.lock.tsv`,
|
|---|---|---|
|
||||||
`SHA256SUMS` ve `pool/` içinde manifestlerdeki pinlere karşılık gelen `.deb`
|
| 1 | `BF_OFFLINE_REPO` ortam değişkeni | Repo sorumlusu bilinçli olarak başka bir dizin verdiyse |
|
||||||
dosyaları.
|
| 2 | `<depo>/provisioning/offline-repo/built` | Normal durum: git checkout'un içindeki hazır set |
|
||||||
|
| 3 | `/opt/blueforce/offline-repo` | Paket seti cihaza ISO/medya ile kopyalanmışsa |
|
||||||
|
|
||||||
|
* Kurucu yerel depo dışında hiçbir kaynak kullanmaz: uzak APT kaynağı, anahtar
|
||||||
|
indirme, `curl`, `wget`, `apt download` çağrılmaz. Cihazdaki tek APT kaynağı
|
||||||
|
`deb [trusted=yes] file:<depo> ./` satırıdır. İnternet kurulum için gerekmez.
|
||||||
|
* Kurucu şu dosyaları arar ve doğrular: `Packages`, `Packages.gz`,
|
||||||
|
`packages.lock.tsv`, `SHA256SUMS` ve `pool/` içinde manifestlerdeki pinlere
|
||||||
|
karşılık gelen `.deb` dosyaları.
|
||||||
* Kurucu kurulum sonunda cihazı `PROVISIONED_OFFLINE` durumuna getirir. Cihaz,
|
* Kurucu kurulum sonunda cihazı `PROVISIONED_OFFLINE` durumuna getirir. Cihaz,
|
||||||
bir kerelik enrollment ve merkezi kanal doğrulaması yapılmadan `READY` olmaz.
|
bir kerelik enrollment ve merkezi kanal doğrulaması yapılmadan `READY` olmaz.
|
||||||
* Sonuç: kuran kişinin yaptığı tek şey `git`/ISO'dan gelen dosyaları yerine
|
* Sonuç: kuran kişinin yaptığı tek şey `git`/ISO'dan gelen dosyaları yerine
|
||||||
koymak ve kurucuyu çalıştırmaktır. Hangi sürümün kurulduğu
|
koymak ve kurucuyu çalıştırmaktır. **Hiçbir şey indirmez, depoyu elle
|
||||||
`packages.lock.tsv` ve `repo-manifest.yaml` ile kanıtlanır.
|
göstermek zorunda değildir.** Hangi sürümün kurulduğu `packages.lock.tsv` ve
|
||||||
|
`repo-manifest.yaml` ile kanıtlanır.
|
||||||
|
|
||||||
Kuran kişinin komutu:
|
Kuran kişinin komutu (bayrak gerekmez):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo ./scripts/install/blueforce-install.sh --offline --dealer-id <8 haneli numara>
|
sudo ./scripts/install/blueforce-install.sh --dealer-id <8 haneli numara>
|
||||||
|
```
|
||||||
|
|
||||||
|
Konsoldan kullanmak için: `sudo bf` (Python operatör konsolu; bash yedek yolu
|
||||||
|
`sudo bf-menu`).
|
||||||
|
|
||||||
|
Depo bulunduğunda kurucu şu duyuruyu yazar:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Yerel paket deposu bulundu: <N> paket, <boyut>
|
||||||
|
Depo : <dizin>
|
||||||
|
Kaynak : <bulunduğu yer>
|
||||||
|
Kip : yerel kurulum. İnternet, paket indirme ve ek anahtar gerekmez.
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 3. Eksik paket olursa ne olur? (`OFFLINE BLOCKED`)
|
# 3. Eksik paket ya da eksik depo olursa ne olur?
|
||||||
|
|
||||||
Cihazdaki kurucu, paket modüllerinden **önce** yerel depoyu doğrular. Bir şey
|
Cihazdaki kurucu, paket modüllerinden **önce** yerel depoyu arar ve doğrular.
|
||||||
eksik ya da bozuksa kurulum durur ve ekrana `OFFLINE BLOCKED` ile başlayan bir
|
Burada **birbirinden farklı iki durum** vardır; ikisi de kurulumu başlatmadan
|
||||||
satır yazar. `OFFLINE BLOCKED` demek: "cihazda kurulum yapılmadı, depo
|
durdurur ve sistemde hiçbir değişiklik bırakmaz, ama mesajları ve anlamları
|
||||||
tamamlanmadı, sorumluya haber verin".
|
farklıdır.
|
||||||
|
|
||||||
|
## 3.1 Depo hiç yok (kurucu bulamadı)
|
||||||
|
|
||||||
|
Aranan üç yer de yoksa — ya da var ama dizin `Packages`, `Packages.gz`,
|
||||||
|
`packages.lock.tsv`, `SHA256SUMS` dosyalarının hepsini taşımıyorsa — kurucu
|
||||||
|
Türkçe yazar ve `exit 1` verir:
|
||||||
|
|
||||||
|
```text
|
||||||
|
HATA: Yerel paket deposu yok. Repo sorumlusuna başvurun: provisioning/offline-repo/README.md
|
||||||
|
|
||||||
|
Kurulum paketleri yalnız yerel depodan kurar; bu makinede internetten paket
|
||||||
|
alınmaz. Depo olmadığı için paket adımları çalışamaz.
|
||||||
|
|
||||||
|
Aranan yerler:
|
||||||
|
- depodaki hazır paket seti — yok: <depo>/provisioning/offline-repo/built
|
||||||
|
- cihazdaki kurulu paket deposu — yok: /opt/blueforce/offline-repo
|
||||||
|
...
|
||||||
|
ÇIKIŞ NEDENİ: yerel paket deposu bulunamadı.
|
||||||
|
```
|
||||||
|
|
||||||
|
Var olan ama eksiksiz olmayan bir dizin, "Aranan yerler" listesinde şu satırla
|
||||||
|
görünür (yine de kurulum başlamaz):
|
||||||
|
|
||||||
|
```text
|
||||||
|
- depodaki hazır paket seti — eksik/bozuk: <dizin> (Packages, Packages.gz, packages.lock.tsv ve SHA256SUMS dosyalarının hepsi gerekli)
|
||||||
|
```
|
||||||
|
|
||||||
|
Anlamı: **kurucu paket setini bulamadı.** Sistem değişmedi; yapılacak şey depoyu
|
||||||
|
tam olarak getirmektir (git'ten veya repo sorumlusunun verdiği kopyayı
|
||||||
|
`/opt/blueforce/offline-repo` altına koyarak) ve komutu tekrar çalıştırmaktır.
|
||||||
|
|
||||||
|
## 3.2 Depo bulundu ama doğrulanamadı (`OFFLINE BLOCKED`)
|
||||||
|
|
||||||
|
Depo bulunduysa (dört indeks/kilit dosyası da var) kurucu onu baştan sona
|
||||||
|
doğrular. Doğrulama katmanı geçmezse kurulum durur ve ekrana **`OFFLINE BLOCKED`**
|
||||||
|
ile başlayan bir satır yazar. `OFFLINE BLOCKED` demek: "depo bulundu ama
|
||||||
|
güvenilir değil; cihazda kurulum yapılmadı, sorumluya haber verin".
|
||||||
|
|
||||||
|
```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ı.
|
||||||
|
```
|
||||||
|
|
||||||
|
Doğrulama katmanının **gerçek** sebepleri (mesajdaki `<sebep>`):
|
||||||
|
|
||||||
| Ekranda ne yazar (kısaltılmış) | Ne anlama gelir | Sorumlu tarafında çözüm |
|
| Ekranda ne yazar (kısaltılmış) | Ne anlama gelir | Sorumlu tarafında çözüm |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `BF_OFFLINE_REPO must be an existing absolute local directory` | Depo dizini hiç yok: medya ya da kopyalama eksik | `built/` içeriğini `/opt/blueforce/offline-repo` altına koyun |
|
| `BF_OFFLINE_REPO mutlak bir yerel dizin olmalıdır.` | `BF_OFFLINE_REPO` ile verilen yol mutlak bir dizin değil | Doğru yolu verin ya da değişkeni kaldırın; varsayılan keşif kullanılsın |
|
||||||
| `local APT index, lock, or checksums are missing; ISO bundle is incomplete` | `Packages`, `Packages.gz`, `packages.lock.tsv` veya `SHA256SUMS` yok. Genelde indeks üretilmeden commit edilmiştir | `./build-index.sh` çalıştırıp `built/` dizinini commit edin |
|
| `Yerel APT indeksi, kilit dosyası ya da checksum kaydı eksik; paket seti tamamlanmamış.` | `Packages`, `Packages.gz`, `packages.lock.tsv` veya `SHA256SUMS` boş/eksik | `./build-index.sh` çalıştırıp `built/` dizinini commit edin |
|
||||||
| `local APT repository checksum validation failed` | Dosyalar elle değişmiş ya da kopyalama bozulmuş (`sha256sum -c SHA256SUMS` hatası) | Depoyu git'ten yeniden alın; indeksi yeniden üretin |
|
| `Yerel APT deposunun checksum doğrulaması başarısız.` | Dosyalar elle değişmiş ya da kopyalama bozulmuş (`sha256sum -c SHA256SUMS` hatası) | Depoyu git'ten yeniden alın; indeksi yeniden üretin |
|
||||||
| `package lock is empty or invalid` | `packages.lock.tsv` başlığı/kolonları bozuk ya da dosya boş | `./build-index.sh` ile yeniden üretin, elle düzenlemeyin |
|
| `Paket kilidi boş ya da biçimi bozuk.` | `packages.lock.tsv` başlığı/kolonları bozuk ya da dosya boş | `./build-index.sh` ile yeniden üretin, elle düzenlemeyin |
|
||||||
| `pinned package absent from bundle: <paket>` | Manifestteki sürüm depoda yok: pin ile paket eşleşmiyor | `add-packages.sh` ile doğru sürümü ekleyip pini güncelleyin |
|
| `Kilitte yazılı paket depoda yok: <paket> <sürüm> (<kaynak>).` | Kilit dosyasındaki bir satırın `.deb` dosyası `pool/` içinde yok | `add-packages.sh` ile paketi ekleyip indeksi yeniden üretin |
|
||||||
|
| `Gerekli pin manifestosu boş: <ad>.` | `manifests/*.txt` dosyalarından biri boş | Pini doldurun; `requirements.tsv` ile birlikte güncelleyin |
|
||||||
|
| `Gerekli pin manifestosunda paket pini yok: <ad>.` | Manifestte yalnız yorum satırı var, paket pini yok | Manifeste `paket=sürüm` satırlarını yazın |
|
||||||
|
| `Geçersiz paket pini: <ad> içinde '<pin>'.` | Pin biçimi bozuk ya da `placeholder`/`REPLACE` içeriyor | Satırı `paket=sürüm` biçimine getirin |
|
||||||
|
| `Pinlenen paket depoda yok: <paket>=<sürüm>.` | Manifestteki sürüm depoda yok: pin ile paket eşleşmiyor | `add-packages.sh` ile doğru sürümü ekleyip pini güncelleyin |
|
||||||
|
|
||||||
Yani "eksik paket" sahada değil, **commit öncesinde** çözülür:
|
Yani "eksik paket" sahada değil, **commit öncesinde** çözülür:
|
||||||
`./build-index.sh` eksikleri listeler ve yazmadan durur. Sahada `OFFLINE BLOCKED`
|
`./build-index.sh` eksikleri listeler ve yazmadan durur. Sahada `OFFLINE BLOCKED`
|
||||||
görürseniz ISO, bilgi eksik bir depoyla üretilmiş demektir; çözüm depoyu düzeltip
|
görürseniz depo, bilgi eksik ya da bozuk bir hâlde yayınlanmış demektir; çözüm
|
||||||
yeni ISO üretmektir.
|
depoyu düzeltip yeni bir sürüm yayınlamaktır.
|
||||||
|
|
||||||
|
## 3.3 Kuran kişi ne yapar?
|
||||||
|
|
||||||
|
Hiçbir şey indirmez: ne `.deb`, ne anahtar, ne APT listesi. Paketler zaten
|
||||||
|
git deposunun içinde taşınır ve kurucu yerel depoyu kendisi bulur. Depo yoksa
|
||||||
|
veya `OFFLINE BLOCKED` görürse yapılacak tek şey **ekrandaki mesajı repo
|
||||||
|
sorumlusuna iletmektir**; düzeltme sorumlunun işidir. Kurulum yapan kişi yalnız
|
||||||
|
komutu tekrar çalıştırır:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ./scripts/install/blueforce-install.sh --dealer-id <8 haneli numara>
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,174 @@
|
||||||
# Blueforce installer (`scripts/install/`)
|
# Blueforce kurulumu (`scripts/install/`)
|
||||||
|
|
||||||
Single entry point: `sudo ./blueforce-install.sh --dealer-id <8 digits>`.
|
Bu klasör cihazı kuran betiği içerir. Kurulumu yapan kişinin bilmesi gereken
|
||||||
|
her şey bu sayfada.
|
||||||
|
|
||||||
- Orchestrator: `blueforce-install.sh` (dealer-id gate `^[0-9]{8}$`,
|
---
|
||||||
hostname `bf-<no>` + device `BF-<no>`, ordered module runs, `--resume`,
|
|
||||||
results to `/var/log/blueforce-install.log` + `/var/lib/blueforce/install-state`).
|
|
||||||
- Modules: `installer/modules/01-*.sh` … `18-*.sh`. Every module is idempotent
|
|
||||||
and supports `--check` (read-only audit). Exit `0` = OK, `3` = SKIP.
|
|
||||||
- Required remote-channel preconditions: set per-device `WG_ADDRESS`, `WG_ENDPOINT`,
|
|
||||||
and `WG_PEER_PUBKEY`; WireGuard readiness requires a peer handshake no older than
|
|
||||||
`BF_WG_HANDSHAKE_MAX_AGE` seconds (default `180`) unless `REQUIRE_WIREGUARD=false`.
|
|
||||||
Set `RUSTDESK_SERVER` to a real self-hosted endpoint and provide the pinned local
|
|
||||||
`RUSTDESK_DEB`; placeholders are rejected.
|
|
||||||
- Docker published ports default to deny. Add only reviewed `tcp PORT` or `udp PORT`
|
|
||||||
entries to `/etc/blueforce/docker-published-port-allowlist.conf`; the enabled
|
|
||||||
`blueforce-docker-firewall.service` reapplies that policy after Docker starts.
|
|
||||||
- Exit codes: `0` READY · `1` module failure · `2` argument/format error.
|
|
||||||
|
|
||||||
Module map: 01-precheck · 02-system · 03-user · 04-hostname · 05-network ·
|
## 1. Kurulum yapan kişi ne yapar?
|
||||||
06-wireguard · 07-ssh · 08-rdp · 09-rustdesk · 10-docker · 11-meg ·
|
|
||||||
12-monitoring · 13-firewall · 14-update-policy · 15-logrotate · 16-gui ·
|
|
||||||
17-healthcheck · 18-final-check.
|
|
||||||
|
|
||||||
NOTE on AnyDesk: there is deliberately no AnyDesk module. Remote access is
|
**Tek komut:**
|
||||||
covered by SSH-over-WireGuard, xRDP and RustDesk. AnyDesk stays a manual,
|
|
||||||
per-device exception outside this installer.
|
```bash
|
||||||
|
sudo ./scripts/install/blueforce-install.sh --dealer-id 12345678
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--dealer-id` tek zorunlu bilgidir: 8 haneli bayi numarası.
|
||||||
|
- Betik numaradan ana makine adını (`bf-12345678`) ve cihaz kimliğini
|
||||||
|
(`BF-12345678`) kendisi üretir.
|
||||||
|
- Kurulum sırasında başka hiçbir soru sorulmaz. Onay istemeyen (fabrika/otomatik)
|
||||||
|
senaryoda sonuna `--yes` ekleyin.
|
||||||
|
- Kurulum bittiğinde cihaz yerinde kurulmuş olur ve `PROVISIONED_OFFLINE`
|
||||||
|
durumuna geçer. Cihazın **READY** sayılması için merkeze kayıt (enrollment)
|
||||||
|
gerekir; bu ayrı bir adımdır, kuruluma dahil değildir.
|
||||||
|
|
||||||
|
Paket aramaz, paket indirmez, apt kaynağı eklemez, anahtar getirmez. Bunların
|
||||||
|
hepsi zaten hazırdır.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Paketler nereden gelir?
|
||||||
|
|
||||||
|
Paketler **git deposunun içinde** taşınır:
|
||||||
|
|
||||||
|
```text
|
||||||
|
provisioning/offline-repo/built/ hazır paket seti (pool/, Packages, SHA256SUMS, packages.lock.tsv)
|
||||||
|
```
|
||||||
|
|
||||||
|
Bunları **repo sorumlusu** hazırlar ve commit eder; kurulumu yapan kişi sadece
|
||||||
|
depoyu çeker. Paket setinin nasıl üretildiği, hangi paketlerin neden
|
||||||
|
gerektiği ve sorun giderme adımları:
|
||||||
|
|
||||||
|
```text
|
||||||
|
provisioning/offline-repo/README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Kurucu paket setini kendi kendine bulur. Arama sırası:
|
||||||
|
|
||||||
|
| Sıra | Yer | Ne zaman kullanılır |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | `BF_OFFLINE_REPO` ortam değişkeni | Repo sorumlusu farklı bir dizin verdiyse (nadir) |
|
||||||
|
| 2 | `provisioning/offline-repo/built` | Normal durum: kurucu betiğin bulunduğu repo |
|
||||||
|
| 3 | `/opt/blueforce/offline-repo` | Paket seti cihaza ISO/medya ile kopyalanmışsa |
|
||||||
|
|
||||||
|
Bulunan depo kurulumdan önce baştan sona doğrulanır: dosya listesi,
|
||||||
|
checksum (`SHA256SUMS`) ve pinlenen her paketin depoda gerçekten durması.
|
||||||
|
Doğrulama geçmezse kurulum **hiç başlamaz**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. İnternet gerekmez — neden?
|
||||||
|
|
||||||
|
- Sahada internet yok veya güvenilmez; kurulumun ihtiyaç duyduğu her paket
|
||||||
|
yanında taşınır ve cihazdaki tek kaynak yerel depodur.
|
||||||
|
- Kurulum çalışırken Apt kaynakları yalnızca bu yerel depoyu gösterir. Dış
|
||||||
|
adreslere, DNS çözümlemesine veya indirmeye ihtiyaç duyulmaz.
|
||||||
|
- Bu yüzden **internet erişimi kontrolü kurulumu durdurmaz**: `01-precheck`
|
||||||
|
modülü interneti sadece bilgi olarak yazar. `05-network` modülü de bağlantı
|
||||||
|
yokken geçer (yerel ağ, internet ve merkez bağlantısı ayrı ayrı raporlanır;
|
||||||
|
hiçbiri kurulum için şart değildir).
|
||||||
|
- Merkez bağlantısı (WireGuard, izleme, kayıt) kurulumdan sonra, **enrollment
|
||||||
|
aşamasında** doğrulanır.
|
||||||
|
|
||||||
|
Yalnızca geliştirme/test makinesi için `--online` vardır: paketleri internetten
|
||||||
|
çeker. **Üretimde kullanmayın** — sahada kurulum yerel depodan yapılır.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Bir şey ters giderse
|
||||||
|
|
||||||
|
### "Yerel paket deposu yok" hatası
|
||||||
|
|
||||||
|
```text
|
||||||
|
HATA: Yerel paket deposu yok. Repo sorumlusuna başvurun: provisioning/offline-repo/README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Anlamı: cihazda kullanılacak paket seti yok. Kurulum başlamadı, sistemde
|
||||||
|
hiçbir değişiklik yapılmadı. Yapılacaklar:
|
||||||
|
|
||||||
|
1. Depoyu tam olarak çekin (`git pull`) veya repo sorumlusunun verdiği kopyayı
|
||||||
|
`/opt/blueforce/offline-repo` altına koyun.
|
||||||
|
2. Komutu yeniden çalıştırın. Aynı numarayla devam edebilirsiniz.
|
||||||
|
|
||||||
|
Ekranda aranan yerlerin listesi yazar; o listeyi repo sorumlusuna iletmek
|
||||||
|
yeterlidir.
|
||||||
|
|
||||||
|
### `OFFLINE BLOCKED` mesajları
|
||||||
|
|
||||||
|
Depo bulundu ama eksik ya da bozuk demektir (checksum tutmuyor, pinlenen paket
|
||||||
|
depoda yok, kilit/indeks dosyası boş...). Kurulum yine başlamaz ve sistem
|
||||||
|
değişmez. Mesajın altındaki "Ne yapmalı" satırı depoyu nasıl düzelteceğinizi
|
||||||
|
söyler; ayrıntılı tablo `provisioning/offline-repo/README.md` içindedir.
|
||||||
|
Sahada çözülmez — depoyu düzeltip yeniden getirmek gerekir.
|
||||||
|
|
||||||
|
### Kurulum kesildi, devam etmek istiyorum
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ./scripts/install/blueforce-install.sh --dealer-id 12345678 --resume
|
||||||
|
```
|
||||||
|
|
||||||
|
`--resume` daha önce tamamlanmış adımları atlar. Bütün adımlar tekrar
|
||||||
|
çalıştırılabilir (idempotent); bir adımı iki kez çalıştırmak zarar vermez.
|
||||||
|
|
||||||
|
### Kurulum yapıldı mı, kontrol etmek istiyorum
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ./scripts/install/blueforce-install.sh --dealer-id 12345678 --check
|
||||||
|
```
|
||||||
|
|
||||||
|
`--check` hiçbir şeyi değiştirmez (log, durum dosyası, dizin oluşturmaz);
|
||||||
|
yalnızca rapor verir. Denetim de aynı paket sözleşmesini doğruladığı için
|
||||||
|
depo yine gerekir.
|
||||||
|
|
||||||
|
### Kayıtlar nerede?
|
||||||
|
|
||||||
|
| Ne | Yer |
|
||||||
|
|---|---|
|
||||||
|
| Kurulum günlüğü | `/var/log/blueforce-install.log` |
|
||||||
|
| Adım adım durum | `/var/lib/blueforce/install-state` |
|
||||||
|
| Cihaz durumu | `/var/lib/blueforce/state.json` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Seçenekler (normalde gerekmez)
|
||||||
|
|
||||||
|
| Seçenek | Ne yapar |
|
||||||
|
|---|---|
|
||||||
|
| `--dealer-id NUMARA` | Zorunlu. 8 haneli bayi numarası. |
|
||||||
|
| `--yes`, `-y` | Onay sormadan başla. |
|
||||||
|
| `--check` | Salt okunur denetim. |
|
||||||
|
| `--from NN` | `NN` numaralı adımdan başla (örn. `--from 06`). |
|
||||||
|
| `--only AD` | Yalnız tek adımı çalıştır (örn. `--only 05-network`). |
|
||||||
|
| `--resume` | Daha önce tamamlanan adımları atla. |
|
||||||
|
| `--help`, `-h` | Yardım metni. |
|
||||||
|
| `--offline` | Yerel depoyu kullanmayı zorlar. Artık gerekmez; varsayılan davranış zaten budur (eski komutlar bozulmasın diye duruyor). |
|
||||||
|
| `--online` | Yalnız geliştirme/test: paketleri internetten çeker. Üretimde kullanılmaz. |
|
||||||
|
|
||||||
|
Kurulum sonucu: `0` başarılı · `1` kurulum durdu (depo ya da adım hatası) ·
|
||||||
|
`2` komut/parametre hatası.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Kurulum adımları (modül haritası)
|
||||||
|
|
||||||
|
Her adım tekrar çalıştırılabilir ve `--check` destekler.
|
||||||
|
|
||||||
|
`01-precheck` · `02-system` · `03-user` · `04-hostname` · `05-network` ·
|
||||||
|
`06-wireguard` · `07-ssh` · `08-rdp` · `09-rustdesk` · `10-docker` · `11-meg` ·
|
||||||
|
`12-monitoring` · `13-firewall` · `14-update-policy` · `15-logrotate` ·
|
||||||
|
`16-gui` · `17-healthcheck` · `18-final-check`
|
||||||
|
|
||||||
|
Uzak erişim için her cihaza özel değerler gerekir: `WG_ADDRESS`, `WG_ENDPOINT`,
|
||||||
|
`WG_PEER_PUBKEY`, `RUSTDESK_SERVER` ve yerel `RUSTDESK_DEB`. Yer tutucu
|
||||||
|
değerler kabul edilmez; WireGuard erişimi `BF_WG_HANDSHAKE_MAX_AGE` saniyeden
|
||||||
|
(öntanımlı `180`) daha yeni bir eş el sıkışması ister (`REQUIRE_WIREGUARD=false`
|
||||||
|
ile kapatılabilir).
|
||||||
|
|
||||||
|
Docker'ın dışa açtığı portlar öntanımlı olarak kapalıdır. Yalnız incelenmiş
|
||||||
|
`tcp PORT` / `udp PORT` satırları
|
||||||
|
`/etc/blueforce/docker-published-port-allowlist.conf` dosyasına eklenir;
|
||||||
|
`blueforce-docker-firewall.service` bu politikayı Docker her başladığında
|
||||||
|
yeniden uygular.
|
||||||
|
|
||||||
|
Not: AnyDesk bilinçli olarak yoktur. Uzak erişim SSH-over-WireGuard, xRDP ve
|
||||||
|
RustDesk ile sağlanır; AnyDesk elle yapılan cihaz başına bir istisnadır.
|
||||||
|
|
|
||||||
|
|
@ -265,8 +265,11 @@ fi
|
||||||
export DEALER_ID BF_HOSTNAME="bf-${DEALER_ID}" BF_DEVICE="BF-${DEALER_ID}" STATE_DIR BF_OFFLINE BF_OFFLINE_REPO="${REPO_DIR:-}"
|
export DEALER_ID BF_HOSTNAME="bf-${DEALER_ID}" BF_DEVICE="BF-${DEALER_ID}" STATE_DIR BF_OFFLINE BF_OFFLINE_REPO="${REPO_DIR:-}"
|
||||||
|
|
||||||
if [[ "$CHECK_MODE" -eq 0 && "$ASSUME_YES" -eq 0 ]]; then
|
if [[ "$CHECK_MODE" -eq 0 && "$ASSUME_YES" -eq 0 ]]; then
|
||||||
read -r -p "Kurulum $BF_DEVICE olarak başlatılsın mı? [e/H] " answer
|
if ! read -r -p "Kurulum $BF_DEVICE olarak başlatılsın mı? [e/H] " answer; then
|
||||||
[[ "$answer" =~ ^[Ee]$ ]] || { echo 'Kurulum iptal edildi.'; exit 2; }
|
printf '\nKurulum iptal edildi: onay alınamadı (terminal yok). Otomatik kurulum için --yes ekleyin.\n' >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
[[ "$answer" =~ ^[Ee]$ ]] || { printf 'Kurulum iptal edildi.\n'; exit 2; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RUN=(); for m in "${MODULES[@]}"; do
|
RUN=(); for m in "${MODULES[@]}"; do
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,17 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Pre-flight checks: root, Ubuntu 26.04, RAM/disk, internet.
|
# Pre-flight checks: root, Ubuntu release, RAM and disk.
|
||||||
|
#
|
||||||
|
# Network is informational here and never a gate: an offline install takes its
|
||||||
|
# packages from the local bundle, so it needs neither the Internet nor the
|
||||||
|
# central endpoint. Three things are reported separately for the operator:
|
||||||
|
# 1. local network link — no intent, not used by the install,
|
||||||
|
# 2. Internet — NOT required for an offline install (no warning),
|
||||||
|
# 3. central connection — not needed during install; that is the enrollment
|
||||||
|
# stage's job.
|
||||||
|
# This module therefore never fails because a network probe failed.
|
||||||
|
#
|
||||||
# Idempotent: safe to re-run. Supports --check for read-only verification.
|
# Idempotent: safe to re-run. Supports --check for read-only verification.
|
||||||
# Exit codes: 0 = OK, 3 = SKIP (optional step, nothing to do).
|
# Exit codes: 0 = OK, 3 = SKIP (optional step, nothing to do), 1 = real failure.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
MODULE="01-precheck"
|
MODULE="01-precheck"
|
||||||
|
|
@ -23,6 +33,25 @@ MIN_RAM_MB=2048
|
||||||
MIN_DISK_MB=20480
|
MIN_DISK_MB=20480
|
||||||
|
|
||||||
fail() { log "FAIL: $1"; echo "FAIL: $1" >&2; exit 1; }
|
fail() { log "FAIL: $1"; echo "FAIL: $1" >&2; exit 1; }
|
||||||
|
info() { log "BİLGİ: $1"; }
|
||||||
|
|
||||||
|
# Read-only network report. Nothing here can fail the install.
|
||||||
|
report_network() {
|
||||||
|
if ip -o link show up 2>/dev/null | grep -qv ' lo:'; then
|
||||||
|
info "yerel ağ: bağlantı var (kurulum için gerekmiyor, kullanılmıyor)"
|
||||||
|
else
|
||||||
|
info "yerel ağ: bağlantı görünmüyor (kurulum için gerekmiyor, kullanılmıyor)"
|
||||||
|
fi
|
||||||
|
if [[ "${BF_OFFLINE:-0}" == 1 ]]; then
|
||||||
|
# Offline install: no probe at all, and no warning either.
|
||||||
|
info "internet: kurulum yerel paket deposundan yapılır; internet GEREKMEZ"
|
||||||
|
elif getent hosts archive.ubuntu.com >/dev/null 2>&1; then
|
||||||
|
info "internet: erişilebilir (geliştirme/test kipi)"
|
||||||
|
else
|
||||||
|
info "internet: erişilemiyor (bu kurulum için gerekmez)"
|
||||||
|
fi
|
||||||
|
info "merkez bağlantısı: kurulum sırasında gerekmez; enrollment aşamasında doğrulanır"
|
||||||
|
}
|
||||||
|
|
||||||
run_checks() {
|
run_checks() {
|
||||||
[[ "$(id -u)" -eq 0 ]] || fail "must run as root"
|
[[ "$(id -u)" -eq 0 ]] || fail "must run as root"
|
||||||
|
|
@ -38,10 +67,8 @@ run_checks() {
|
||||||
[[ "$ram_mb" -ge "$MIN_RAM_MB" ]] || fail "RAM too low: ${ram_mb}MB (need >= ${MIN_RAM_MB}MB)"
|
[[ "$ram_mb" -ge "$MIN_RAM_MB" ]] || fail "RAM too low: ${ram_mb}MB (need >= ${MIN_RAM_MB}MB)"
|
||||||
disk_mb=$(df -m / --output=avail | tail -1 | tr -d ' ')
|
disk_mb=$(df -m / --output=avail | tail -1 | tr -d ' ')
|
||||||
[[ "$disk_mb" -ge "$MIN_DISK_MB" ]] || fail "disk too low: ${disk_mb}MB free on / (need >= ${MIN_DISK_MB}MB)"
|
[[ "$disk_mb" -ge "$MIN_DISK_MB" ]] || fail "disk too low: ${disk_mb}MB free on / (need >= ${MIN_DISK_MB}MB)"
|
||||||
if [[ "${BF_OFFLINE:-0}" != 1 ]] && ! getent hosts archive.ubuntu.com >/dev/null 2>&1 && ! ping -c1 -W5 1.1.1.1 >/dev/null 2>&1; then
|
report_network
|
||||||
fail "no internet connectivity (DNS and ping both failed)"
|
log "OK: ön denetim geçti (Ubuntu ${VERSION_ID}, RAM ${ram_mb}MB, disk ${disk_mb}MB boş; yerel kurulum=$([[ "${BF_OFFLINE:-0}" == 1 ]] && echo evet || echo hayır))"
|
||||||
fi
|
|
||||||
log "OK: precheck passed (Ubuntu ${VERSION_ID}, RAM ${ram_mb}MB, disk ${disk_mb}MB free; offline=${BF_OFFLINE:-0})"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run_checks
|
run_checks
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,47 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Network gates distinguish local link, Internet, and central enrollment reachability.
|
# Network report for the field device. It separates three things that used to be
|
||||||
|
# one gate:
|
||||||
|
# 1. local network link — informational; the install does not use it,
|
||||||
|
# 2. Internet — NOT required: packages come from the local bundle,
|
||||||
|
# so external name resolution is not mandatory and a
|
||||||
|
# failing lookup must never stop the run,
|
||||||
|
# 3. central connection — not needed during install; enrollment checks it.
|
||||||
|
#
|
||||||
|
# The module therefore always exits 0: no network condition can fail an install.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
LOG_FILE="${LOG_FILE:-/var/log/blueforce-install.log}"; CHECK_MODE=0
|
LOG_FILE="${LOG_FILE:-/var/log/blueforce-install.log}"; CHECK_MODE=0
|
||||||
[[ "${1:-}" == --check ]] && CHECK_MODE=1
|
[[ "${1:-}" == --check ]] && CHECK_MODE=1
|
||||||
OFFLINE="${BF_OFFLINE:-0}"; ENDPOINT="${BF_ENROLLMENT_ENDPOINT:-}"
|
OFFLINE="${BF_OFFLINE:-0}"; ENDPOINT="${BF_ENROLLMENT_ENDPOINT:-}"
|
||||||
log() { echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) [05-network] $1" | tee -a "$LOG_FILE"; }
|
log() { echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) [05-network] $1" | tee -a "$LOG_FILE"; }
|
||||||
local_link() { ip -o link show up 2>/dev/null | grep -qv ' lo:'; }
|
local_link() { ip -o link show up 2>/dev/null | grep -qv ' lo:'; }
|
||||||
internet() { getent hosts archive.ubuntu.com >/dev/null 2>&1 && (ping -c1 -W3 1.1.1.1 >/dev/null 2>&1 || curl --connect-timeout 3 -fsSI https://archive.ubuntu.com >/dev/null 2>&1); }
|
internet() { ping -c1 -W3 1.1.1.1 >/dev/null 2>&1 || getent hosts archive.ubuntu.com >/dev/null 2>&1; }
|
||||||
central() { [[ "$ENDPOINT" =~ ^https://[^[:space:]/]+ ]] && curl --connect-timeout 3 -fsSI "$ENDPOINT" >/dev/null 2>&1; }
|
central() { [[ "$ENDPOINT" =~ ^https://[^[:space:]/]+ ]] && curl --connect-timeout 3 -fsSI "$ENDPOINT" >/dev/null 2>&1; }
|
||||||
local_link || { log 'FAIL: no local network link'; exit 1; }
|
|
||||||
log 'OK: local link present'
|
if local_link; then
|
||||||
if [[ "$OFFLINE" == 1 ]]; then log 'OK: offline mode defers Internet and central endpoint checks'; exit 0; fi
|
log 'BİLGİ: yerel ağ bağlantısı var (kurulum için gerekmiyor)'
|
||||||
internet || { log 'FAIL: Internet reachability unavailable'; exit 1; }
|
else
|
||||||
log 'OK: Internet reachable'
|
log 'BİLGİ: yerel ağ bağlantısı görünmüyor (kurulum için gerekmiyor)'
|
||||||
if [[ -n "$ENDPOINT" ]]; then central && log 'OK: central enrollment endpoint reachable' || log 'WARN: central enrollment endpoint unavailable (enrollment remains pending)'; else log 'INFO: central enrollment endpoint not configured'; fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$OFFLINE" == 1 ]]; then
|
||||||
|
log 'BİLGİ: internet: kurulum yerel paket deposundan yapılır; internet GEREKMEZ'
|
||||||
|
log 'BİLGİ: Apt kaynakları yerel depoyu gösterir; dış DNS çözümlenemese de kurulum sürer'
|
||||||
|
else
|
||||||
|
if internet; then
|
||||||
|
log 'BİLGİ: internet erişilebilir (geliştirme/test kipi; üretimde gerekmez)'
|
||||||
|
else
|
||||||
|
log 'BİLGİ: internet erişilemiyor (bu kurulum için gerekmez)'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$ENDPOINT" ]]; then
|
||||||
|
if central; then
|
||||||
|
log 'BİLGİ: merkez kayıt uç noktası şu an erişilebilir (kurulumda yine de gerekmez)'
|
||||||
|
else
|
||||||
|
log 'BİLGİ: merkez kayıt uç noktasına şu an erişilemiyor; kurulum DURMAZ, enrollment aşamasında yeniden denenir'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log 'BİLGİ: merkez kayıt uç noktası tanımlı değil; bağlantı enrollment aşamasında kurulur'
|
||||||
|
fi
|
||||||
|
log 'OK: ağ raporu tamam; kurulum internetsiz tamamlanabilir'
|
||||||
|
exit 0
|
||||||
|
|
|
||||||
|
|
@ -386,7 +386,40 @@ expect_present 'bf-bootstrap cloned the repository' "$APPLY_ROOT/checkout/.git"
|
||||||
expect_present 'bf-bootstrap linked a diagnostics tool' "$APPLY_ROOT/bin/bf-status"
|
expect_present 'bf-bootstrap linked a diagnostics tool' "$APPLY_ROOT/bin/bf-status"
|
||||||
expect_contains 'bf-bootstrap prints the completion contract' "$WORK/apply1.out" 'Kurulum tamam. Başlamak için: sudo bf'
|
expect_contains 'bf-bootstrap prints the completion contract' "$WORK/apply1.out" 'Kurulum tamam. Başlamak için: sudo bf'
|
||||||
expect_contains 'bf-bootstrap reports the repository in its summary' "$WORK/apply1.out" "$APPLY_ROOT/checkout"
|
expect_contains 'bf-bootstrap reports the repository in its summary' "$WORK/apply1.out" "$APPLY_ROOT/checkout"
|
||||||
expect_contains 'bf-bootstrap warns when the Python console is not in the clone' "$WORK/apply1.out" 'admin/bf is not present'
|
# The "console missing from the clone" branch is unreachable in a normal clone
|
||||||
|
# because admin/bf and admin/bf-menu are tracked. Exercise it deliberately, or
|
||||||
|
# the warning silently rots the day one of them is renamed.
|
||||||
|
#
|
||||||
|
# Note: deleting the file from a git working tree is NOT enough. Neither is
|
||||||
|
# stripping .git entirely -- bootstrap clones with `--branch main` and a plain
|
||||||
|
# directory has no such ref. The source has to be a real git repo in which the
|
||||||
|
# console is absent from the committed tree, so build one.
|
||||||
|
STRIPPED_REPO="$WORK/stripped-repo"
|
||||||
|
rm -rf "$STRIPPED_REPO"
|
||||||
|
cp -a "$REPO_ROOT" "$STRIPPED_REPO"
|
||||||
|
rm -rf "$STRIPPED_REPO/.git"
|
||||||
|
rm -f "$STRIPPED_REPO/admin/bf"
|
||||||
|
git -C "$STRIPPED_REPO" init -q -b main
|
||||||
|
git -C "$STRIPPED_REPO" -c user.name=check -c user.email=check@example.invalid \
|
||||||
|
add -A
|
||||||
|
git -C "$STRIPPED_REPO" -c user.name=check -c user.email=check@example.invalid \
|
||||||
|
commit -q -m 'stripped checkout without the Python console'
|
||||||
|
if git -C "$STRIPPED_REPO" cat-file -e 'HEAD:admin/bf' 2>/dev/null; then
|
||||||
|
fail 'the stripped source still tracks admin/bf; the scenario is invalid'
|
||||||
|
fi
|
||||||
|
set +e
|
||||||
|
PATH="$APPLY_PATH" \
|
||||||
|
BF_SHIM_APT_LOG="$WORK/apt-stripped.log" \
|
||||||
|
BF_BIN_DIR="$WORK/stripped-bin" \
|
||||||
|
BF_INSTALL_DIR="$WORK/stripped-checkout" \
|
||||||
|
BF_REPO_URL="$STRIPPED_REPO" \
|
||||||
|
bash "$BOOTSTRAP" --yes < /dev/null > "$WORK/apply-stripped.out" 2>&1
|
||||||
|
stripped_rc=$?
|
||||||
|
set -e
|
||||||
|
expect_rc 'bf-bootstrap succeeds even when the Python console is absent' 0 "$stripped_rc"
|
||||||
|
expect_contains 'bf-bootstrap warns when the Python console is not in the clone' "$WORK/apply-stripped.out" 'admin/bf is not present'
|
||||||
|
expect_contains 'bf-bootstrap still links the bash fallback' "$WORK/apply-stripped.out" 'bf-menu ready'
|
||||||
|
rm -rf "$STRIPPED_REPO" "$WORK/stripped-bin" "$WORK/stripped-checkout"
|
||||||
linked1="$(find "$APPLY_ROOT/bin" -maxdepth 1 -type l 2>/dev/null | wc -l | tr -d ' ')"
|
linked1="$(find "$APPLY_ROOT/bin" -maxdepth 1 -type l 2>/dev/null | wc -l | tr -d ' ')"
|
||||||
check
|
check
|
||||||
if [[ "$linked1" -ge 10 ]]; then
|
if [[ "$linked1" -ge 10 ]]; then
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue