Blueforce-Linux/scripts/install
emirhanmamak-blueforce 1387186b03 feat(bfos): Python operator console, Turkish UI, committable offline packages
Switches the operator path from bash-only to a Python console, keeps the bash
menu as a fallback, and makes the offline package set travel with the repository
so the person installing a device never downloads anything.

bfos/ (stdlib only, no textual/rich: those would need a download, which defeats
the offline goal):
- simple mode offers three choices (Kur / Durum / Çıkış); the detailed mode with
  all 21 fleet operations and the local installer is reachable from the menu or
  with --full, so a first-time operator is not buried in options
- gate parity with the bash console: scope read from the playbook file and
  refused on mismatch, production needs a typed token plus a separate approval,
  release-gated runs need their wave name typed, destructive runs need a second
  approval, "all" walks wave by wave and stops at the first failure
- Turkish throughout; audit log at /var/log/blueforce-console.log (600, falls
  back to the user state dir) with a single redaction choke point
- bfos/ui_gui.py adds an optional tkinter window over the same operations layer;
  headless and missing-tkinter cases explain themselves in Turkish

admin/bf-bootstrap.sh: links the Python console as `bf` (primary) and keeps
`bf-menu` (fallback), reports both, and recommends `sudo bf`.

Offline packages are committable now (this was the blocking contradiction):
- .gitignore ignored `Packages`, `Packages.gz` and `packages.lock.tsv` everywhere,
  so a built bundle could never be committed and the installer would always have
  been told to download. provisioning/offline-repo/built/ is now allowed through
  while scratch output stays untracked
- provisioning/offline-repo/{add-packages.sh,build-index.sh,repo-manifest.yaml}
  plus a Turkish step-by-step README for the repository owner
- the over-broad `*token*` ignore rule is narrowed to `*[-_.]token*` so ordinary
  filenames are not silently excluded while token files still are

Tests: run-all.sh now runs the Python suites too (previously it collected only
*.sh, so 212 Python assertions were silently skipped) and executes from the repo
root. 11/11 pass, exit 0.

Two test expectations were corrected rather than the code: a read-only
wave-scoped report legitimately asks for no gate token (the bash console never
did either), so that assertion now checks the command carries operation_wave and
operation_confirmed, and a new test asserts release-gated runs still require
their token. The bootstrap completion contract moved from `sudo bf-menu` to
`sudo bf`.
2026-09-16 16:15:27 +03:00
..
installer feat(field-os): provisioning layer, real ISO build, offline contracts 2026-09-16 11:14:42 +03:00
optional/anydesk feat(field-os): provisioning layer, real ISO build, offline contracts 2026-09-16 11:14:42 +03:00
.gitkeep docs: Blueforce 700-device fleet architecture (TR) - GNOME baseline 2026-09-15 17:03:02 +03:00
blueforce-install.sh feat(bfos): Python operator console, Turkish UI, committable offline packages 2026-09-16 16:15:27 +03:00
README.md feat(field-os): provisioning layer, real ISO build, offline contracts 2026-09-16 11:14:42 +03:00

Blueforce installer (scripts/install/)

Single entry point: sudo ./blueforce-install.sh --dealer-id <8 digits>.

  • 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 · 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 covered by SSH-over-WireGuard, xRDP and RustDesk. AnyDesk stays a manual, per-device exception outside this installer.