Files
ServerKit/backend/serverkit_installer
Juan DenisandClaude Opus 4.8 db16100a42 feat(installer): Phase 5 — additive Python bootstrap foundation
Hardening plan §8. A stdlib-only, import-safe, unit-tested Python package that
ports the stabilized bash install logic into testable orchestration. Per the
plan's migration path this is ADDITIVE — install.sh stays canonical and this is
NOT wired into it yet; it is the validated foundation a future thin-bootstrap
install.sh can call.

backend/serverkit_installer/:
  - _proc.py    — sudo-aware subprocess helpers, mirroring app/utils/system.py
                  WITHOUT importing app (the bootstrap runs before the venv
                  exists, so it must not pull in Flask).
  - distro.py   — OS family mapping (a faithful port of install.sh's
                  os_family_from, rhel-before-fedora) + container/WSL/systemd
                  predicates (mirroring scripts/lib/env.sh).
  - deps.py     — loads scripts/deps/manifest.yaml (its primary consumer) and
                  resolves base/python/node/docker/pkg-manager per family.
  - firewall.py — detect + pure open/close command builders (port of
                  scripts/lib/firewall.sh).
  - service.py  — init detect + pure start/stop/enable/reload builders (port of
                  scripts/lib/init.sh).
  - main.py     — composes a READ-ONLY install "plan" + `python -m
                  serverkit_installer plan|detect` CLI. No host mutation.

Tests: backend/tests/test_serverkit_installer.py — 46 pure-logic cases
(family mapping vs os_family_from, real-manifest resolution for all six
families, firewall/service command builders, env predicates, composed plan).
46 passed; py_compile + pyflakes clean. The CLI proves the manifest is genuinely
consumed (Debian -> apt + python3.11 + base packages), not dead config.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 01:06:44 -04:00
..

serverkit_installer

Phase 5 foundation from the Installer/Updater/Uninstaller Hardening Plan (§8). A stdlib-only, import-safe, unit-tested Python port of the bash installer's detection and orchestration logic.

Additive, not a replacement. install.sh is still the canonical installer. This package exists so the stabilized multi-distro logic has a single, unit-testable home that the backend can eventually share. It is not wired into install.sh yet — per the plan's migration path, the bash scripts stay in charge until this is fully validated on real boxes.

Why it doesn't import app

The real bootstrap runs before the backend venv exists, so importing app.utils.system (which pulls in Flask/SQLAlchemy) would fail. This package is deliberately stdlib-only (plus PyYAML for the manifest) and mirrors app/utils/system.py's run_privileged/sudo contract in _proc.py.

Modules

Module Mirrors Responsibility
distro.py install.sh:os_family_from + scripts/lib/env.sh OS family + container/WSL/systemd detection
deps.py scripts/deps/manifest.yaml Load the manifest, resolve packages per family
firewall.py scripts/lib/firewall.sh Detect backend, build open/close command lists
service.py scripts/lib/init.sh Detect init system, build start/stop/enable commands
main.py — Compose a read-only install plan + CLI
_proc.py app/utils/system.py sudo-aware subprocess helpers

The command builders are pure functions returning argv lists, so they're tested without touching a real firewall/init system.

Usage

# Read-only: print what an install would do on the detected distro
python -m serverkit_installer plan

# Just the distro detection
python -m serverkit_installer detect --os-release /etc/os-release

# Force backends for a preview on any host
python -m serverkit_installer plan --firewall firewalld --init systemd

Tests

backend/tests/test_serverkit_installer.py (46 cases) — family mapping kept in lockstep with os_family_from, manifest resolution for every family, the firewall/service command builders, environment predicates, and the composed plan. Pure logic, no host mutation:

cd backend && pytest tests/test_serverkit_installer.py