Blueforce-Linux/provisioning/offline-repo
2026-09-17 13:22:26 +03:00
..
built fix(offline-repo): commit the bundle pool so a clone carries the packages 2026-09-16 22:12:57 +03:00
manifests feat(offline-repo): build the APT index so installs work without network 2026-09-16 21:42:27 +03:00
packages feat(offline-repo): build the APT index so installs work without network 2026-09-16 21:42:27 +03:00
add-packages.sh fix(offline-repo): read dpkg-deb output in both of its shapes 2026-09-16 21:57:44 +03:00
build-index.sh fix(offline-repo): read dpkg-deb output in both of its shapes 2026-09-16 21:57:44 +03:00
build-offline-repo.sh fix(offline-repo): read dpkg-deb output in both of its shapes 2026-09-16 21:57:44 +03:00
README.md Unify Blueforce identity and Python operator surfaces 2026-09-17 13:22:26 +03:00
repo-manifest.yaml feat(offline-repo): ship the reviewed package set so installs never download 2026-09-16 19:03:45 +03:00

Offline APT deposu (paketler git ile taşınır)

Saha cihazı internetsiz kuruluyor. Bu dizin, kurulumda kullanılacak Ubuntu paketlerini ve bunların APT indeksini bu git deposunun içinde taşır.

İki kural:

  1. Paketleri repo sorumlusu toplar ve bu dizine commit eder (Ubuntu makinesi gerekir).
  2. Kuran kişi hiçbir şey indirmez. Cihazdaki kurucu yalnızca git'ten gelen yerel depoyu okur; internet, apt kaynağı, anahtar indirme, apt download gibi hiçbir yol kullanılmaz.

Roller

Rol Kimdir Ne yapar
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 --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 / dizin Ne işe yarar Kim çalıştırır
packages/ Doğrulanmış .deb dosyaları (kaynak havuz) repo sorumlusu (add-packages.sh ile doldurur)
add-packages.sh .deb doğrular, packages/ altına ekler, Türkçe rapor verir repo sorumlusu (Ubuntu)
build-index.sh packages/tan offline indeksi üretir (built/), repo-manifest.yaml yazar repo sorumlusu (Ubuntu)
built/ Git'e giren hazır depo: pool/, Packages, Packages.gz, packages.lock.tsv, SHA256SUMS üretilir
repo-manifest.yaml Deponun künyesi: sürüm, mimari, paket listesi, boyut, tarih build-index.sh üretir
build-offline-repo.sh Sözleşme doğrulayıcı (--dry-run-plan) ve alternatif derleyici repo sorumlusu / CI
manifests/*.txt Pin listesi: paket=sürüm. Cihazda ne olması gerektiği repo sorumlusu doldurur
manifests/requirements.tsv Hangi paket neden gerekli (denetim tablosu) insan okur
manifests/packages.lock.schema.tsv packages.lock.tsv biçiminin tanımı insan okur
packages/.gitkeep Boş dizinin git'te durması için yer tutucu —

1. Repo sorumlusu: sıfırdan adım adım

1.0 Gereksinimler

  • Ubuntu 26.04 LTS makinesi, mimari amd64, internet erişimi var (paketleri toplamak için). Docker CE ve RustDesk paketleri Ubuntu arşivinde değildir; aşağıda ayrı anlatılıyor.

  • Şu iki araç kurulu olmalı:

    sudo apt-get install -y dpkg apt-utils
    dpkg-deb --version        # okunur: .deb künyesini okur
    apt-ftparchive --version  # okunur: APT indeksini üretir
    

    CachyOS/Arch gibi bir makinede apt-ftparchive ve dpkg-deb yoktur; orada paket toplanamaz ve indeks üretilemez. Toplama işi Ubuntu makinesinde yapılır, sonuç bu depoya commit edilir.

1.1 Paketleri indir

Çalışma dizini açın:

mkdir -p ~/bf-debs && cd ~/bf-debs

Hangi sürümün "aday" olduğunu görün (pini bu sürümle dolduracaksınız):

apt-cache policy openssh-server | head -n 3

Paketleri ve bağımlılıklarını indirin (--download-only hiçbir şey kurmaz):

sudo apt-get install --download-only --reinstall -y \
  curl wget ca-certificates gnupg lsb-release apt-transport-https \
  openssh-server wireguard-tools smartmontools ufw iptables \
  prometheus-node-exporter xrdp xorgxrdp gnome-session ubuntu-desktop-minimal

cp /var/cache/apt/archives/*.deb ~/bf-debs/
rm -f ~/bf-debs/*partial*

ubuntu-desktop-minimal çok sayıda bağımlılık getirir; bu normaldir ve offline kurulum için gereklidir.

Docker CE (Ubuntu arşivinde yok, Docker deposundan gelir):

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update
sudo apt-get install --download-only --reinstall -y \
  docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
cp /var/cache/apt/archives/*.deb ~/bf-debs/

containerd.io Docker'ın kendi çalışma zamanıdır; Ubuntu'nun containerd paketi ile karıştırmayın.

RustDesk (Ubuntu arşivinde yok, üretici .deb dosyası):

  • Projenin sürüm sayfasından amd64 paketini indirin: https://github.com/rustdesk/rustdesk/releases → rustdesk-<sürüm>-x86_64.deb
  • Dosyayı ~/bf-debs/ içine kopyalayın. Kullanılacak sürüm, incelenmiş (self-hosted sunucuya bağlanan) istemci sürümü olmalıdır.

1.2 Paketleri depoya ekle

cd provisioning/offline-repo

# Ön izleme: hiçbir dosya kopyalanmaz, ne olacağını söyler
./add-packages.sh --from ~/bf-debs --check

# Gerçek ekleme (pinlenen + bağımlılıklar)
./add-packages.sh --from ~/bf-debs

Yalnız manifestte pinlenen paketleri eklemek isterseniz:

./add-packages.sh --from ~/bf-debs --manifest manifests/base-packages.txt
# bağımlılıkları da eklemek için sonuna --include-all ekleyin

Araç her dosyayı denetler ve Türkçe yazar:

  • EKLENDİ: → eklendi,
  • ATLANDI: aynı dosya zaten repoda → tekrar eklemeye çalıştınız (zararsız),
  • HATA: mimari uyumsuz → paket amd64/all değil; o dosyayı kullanmayın,
  • HATA: çakışma: <paket> repoda <sürüm> ile duruyor → aynı paketin ikinci bir sürümü. Manifestler tek sürüm pinler, bu yüzden otomatik üzerine yazılmaz; ekranda yazan rm komutu ile eski dosyayı kaldırıp yeniden ekleyin,
  • ATLANDI: manifestte istenen sürüm farklı → manifestteki pin başka bir sürümü istiyor; pini güncelleyin ya da doğru sürümün .deb dosyasını indirin.

Sonda MANIFEST GÜNCELLEMESİ GEREKİYOR listesi çıkar: bu araç manifest dosyalarını değiştirmez, yalnızca yazmanız gereken satırı söyler.

1.3 Manifest pinlerini doldur

manifests/base-packages.txt, remote-access.txt, docker.txt içindeki her satır şu biçimdedir:

openssh-server=UNPINNED

UNPINNED bir yer tutucudur, sürüm değildir. add-packages.sh çıktısındaki listeyi kullanarak gerçek sürümü yazın:

openssh-server=9.6p1-3ubuntu13

Kurallar: küçük harfli paket adı, = çevresinde boşluk yok, satır sonuna not yazılmaz, bir paket yalnızca bir manifestte pinlenir. Yeni paket ekler/çıkarırsanız manifests/requirements.tsv tablosunu aynı işlemde güncelleyin.

Kontrol:

./build-offline-repo.sh --dry-run-plan     # PLAN READY görmelisiniz

PLAN READY görünene kadar derleme yapmayın. Bir sürümden emin değilseniz elinizdeki dosyadan okuyun:

dpkg-deb -f ~/bf-debs/openssh-server_*.deb Package Version Architecture

1.4 İndeksi üret

./build-index.sh --check     # yalnızca doğrular, hiçbir şey yazmaz
./build-index.sh             # built/ altına indeksi yazar

Çıktı:

built/pool/*.deb            paketlerin kopyası
built/Packages              APT indeksi (apt-ftparchive)
built/Packages.gz           sıkıştırılmış indeks (zaman damgasız)
built/packages.lock.tsv     SBOM: package/version/architecture/sha256/source
built/SHA256SUMS            indeks dosyalarının özetleri
repo-manifest.yaml          deponun künyesi (güncellenir)

Araç fail-closed çalışır:

  • manifestteki bir pin repoda yoksa hiçbir şey yazmaz ve eksikleri liste hâlinde söyler (manifestlerde istenen şu paketler eksik:),
  • bir pin hâlâ UNPINNED ise yine yazmaz; önce manifesti doldurun,
  • aynı havuzla tekrar çalıştırıldığında indeks birebir aynı çıkar; içerik değişmediyse DEĞİŞİKLİK YOK yazar ve dizini yeniden yazmaz.

1.5 Git'e ekle ve commit et

# Paketler ve manifestler:
git add provisioning/offline-repo/packages provisioning/offline-repo/manifests

# İndeks: .gitignore, Packages / Packages.gz / packages.lock.tsv adlarını her
# dizinde yok sayar (eski LAB akışından kalma kural), bu yüzden -f gerekir:
git add -f provisioning/offline-repo/built

git add provisioning/offline-repo/repo-manifest.yaml
git commit -m "offline repo: <paket sayısı> paket, offline APT indeksi"

build-index.sh çalıştığınızda bu komutları ekrana da yazar (kopyala-yapıştır). .gitignore dosyasının sahibi isterse bu üç ad için daha sonra istisna kuralı ekleyebilir; o zaman -f gereksizleşir.

1.6 Bitirmeden önce kontrol

bash tests/check-offline-repo-static.sh
./build-offline-repo.sh --dry-run-plan
cd built && sha256sum -c SHA256SUMS      # OK görmelisiniz

2. Kuran kişi neden hiç indirme yapmaz

  • 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.

  • Kurucu paket setini kendi kendine bulur; --offline bayrağı artık gerekmez (geriye uyumluluk için duruyor ve yalnızca yerel depoyu zorlar). Arama sırası — ilk eksiksiz aday kazanır:

    Sıra Yer Ne zaman kullanılır
    1 BF_OFFLINE_REPO ortam değişkeni Repo sorumlusu bilinçli olarak başka bir dizin verdiyse
    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, 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 koymak ve kurucuyu çalıştırmaktır. Hiçbir şey indirmez, depoyu elle 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 (bayrak gerekmez):

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 --tui).

Depo bulunduğunda kurucu şu duyuruyu yazar:

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 ya da eksik depo olursa ne olur?

Cihazdaki kurucu, paket modüllerinden önce yerel depoyu arar ve doğrular. Burada birbirinden farklı iki durum vardır; ikisi de kurulumu başlatmadan durdurur ve sistemde hiçbir değişiklik bırakmaz, ama mesajları ve anlamları 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:

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):

  - 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".

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
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
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
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
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
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: ./build-index.sh eksikleri listeler ve yazmadan durur. Sahada OFFLINE BLOCKED görürseniz depo, bilgi eksik ya da bozuk bir hâlde yayınlanmış demektir; çözüm 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:

sudo ./scripts/install/blueforce-install.sh --dealer-id <8 haneli numara>

4. Hangi paketler gerekli ve neden?

Liste manifests/requirements.tsv dosyasının okunabilir hâlidir; kaynak doğrudur. Her satır bir paket=sürüm pinidir ve kurucu bu pinlerin tamamını depoda arar; biri eksikse OFFLINE BLOCKED ile durur.

Temel araçlar — manifests/base-packages.txt

Paket Neden gerekli Nerede kullanılır
curl HTTPS aktarımı yapan temel araç 02-system.sh
wget Saha runbook'larının beklediği dosya çekme aracı 02-system.sh
ca-certificates TLS doğrulaması için kök sertifika deposu 02-system.sh
gnupg İncelenmiş dosyaların imza işlemleri 02-system.sh
lsb-release Dağıtım sürümünü tanıma 02-system.sh
apt-transport-https apt 2.0+ üzerinde geçiş (dummy) paket; referans derlemeyle uyum için tutuluyor 02-system.sh
openssh-server Yönetilen SSH erişim kanalı 07-ssh.sh
wireguard-tools wg komutu (VPN tüneli) 06-wireguard.sh
smartmontools Disk sağlığı kanıtı (SMART) scripts/diagnostics/bf-diagnostics
ufw Güvenlik duvarı temeli 13-firewall.sh
iptables Güvenlik duvarı kural arka ucu 13-firewall.sh
prometheus-node-exporter Cihaz metrikleri (textfile collector paketin içinde) 12-monitoring.sh

Uzak erişim ve masaüstü — manifests/remote-access.txt

Paket Neden gerekli Nerede kullanılır
xrdp RDP erişim kanalı 08-rdp.sh
xorgxrdp xRDP için X11 arka ucu (bağımlılık kapatması LAB'da doğrulanır) 08-rdp.sh
gnome-session xRDP oturumunda başlatılan masaüstü oturumu 08-rdp.sh
ubuntu-desktop-minimal En küçük masaüstü yığını 16-gui.sh
rustdesk Uzak masaüstü istemcisi. Ubuntu arşivinde yoktur: üreticinin incelenmiş .deb dosyası 09-rustdesk.sh

Docker CE — manifests/docker.txt

Paket Neden gerekli Nerede kullanılır
docker-ce Konteyner motoru 10-docker.sh
docker-ce-cli docker komutu 10-docker.sh
containerd.io Docker CE ile gelen çalışma zamanı (Ubuntu'nun containerd paketi değil) 10-docker.sh
docker-buildx-plugin buildx eklentisi 10-docker.sh
docker-compose-plugin Compose v2 eklentisi 10-docker.sh

Notlar:

  • Pinler sürüm doldurulmadan UNPINNED görünür ve bu hâlde derleme yapılmaz.
  • Bu 22 paketin dışındaki paketler (bağımlılıklar) da depoda bulunur; ancak yalnız pinlenen 22 paket sözleşmedir.
  • Çekirdek modülleri gibi .deb olarak taşınmayan dosyalar bu deponun kapsamı dışındadır.

5. repo-manifest.yaml ve built/ nedir?

  • repo-manifest.yaml = deponun künyesi (kimlik kartı): hedef Ubuntu sürümü, mimari, kaç paket, toplam boyut, üretim tarihi ve her paketin adı/sürümü/ sha256'sı. ISO release manifesti ve denetim kaydı ile birlikte saklanır.
  • built/ = cihaza gidecek depo. Hedef cihazda /opt/blueforce/offline-repo olur; içinde pool/, Packages, Packages.gz, packages.lock.tsv, SHA256SUMS bulunur. Kurucu bu dosyaları sha256sum -c SHA256SUMS ile ve manifestteki her pini pool/ içindeki bir dosyayla eşleştirerek doğrular.

6. Sık karşılaşılan durumlar

Belirti Neden / çözüm
apt-ftparchive bulunamadı Ubuntu makinesinde kurun: sudo apt-get install -y apt-utils
dpkg-deb bulunamadı sudo apt-get install -y dpkg (Arch/CachyOS'ta yoktur; orada derleme yapılamaz)
git add indeks dosyalarını almıyor .gitignore bu adları yok sayıyor; git add -f provisioning/offline-repo/built kullanın
HATA: çakışma Aynı paketin ikinci sürümü eklenmeye çalışıldı. Manifestler tek sürüm pinler; ekrandaki rm ile eskiyi kaldırın
mimari uyumsuz Yalnız amd64 ve all kabul edilir; arm64/i386 paketi eklemeyin
manifestlerde istenen şu paketler eksik Paketi indirip add-packages.sh ile ekleyin; pin hâlâ UNPINNED ise sürümü yazın
ISO betiği depoyu bulamıyor provisioning/iso/build-blueforce-iso.sh şu an provisioning/offline-repo/build adını arıyor; built/ kullanacaksanız ./build-index.sh --output build ile de üretin ya da ISO betiğinin otomatik bulma yolunu güncelleyin
Depo boyutu beklenenden büyük packages/ ve built/pool/ aynı .deb dosyalarını iki kez tutar (git içeriği bir kez saklar, çalışma kopyasında iki dosya durur). Kasıtlıdır: biri kaynak, diğeri teslim depo

7. Commit öncesi kontrol listesi

  • ./add-packages.sh --from <dizin> --check temiz geçti.
  • manifests/*.txt içinde UNPINNED kalmadı.
  • ./build-offline-repo.sh --dry-run-plan → PLAN READY.
  • ./build-index.sh eksiksiz geçti, eksik paket listesi boş.
  • cd built && sha256sum -c SHA256SUMS → OK.
  • repo-manifest.yaml güncel (paket sayısı ve tarih yazılmış).
  • bash tests/check-offline-repo-static.sh geçti.
  • Commit: paketler, manifestler, built/ (-f ile) ve repo-manifest.yaml.