First-boot initialization hardening + systemd/packaging fixes - #157
Open
joshschmelzle wants to merge 2 commits into
Open
First-boot initialization hardening + systemd/packaging fixes#157joshschmelzle wants to merge 2 commits into
joshschmelzle wants to merge 2 commits into
Conversation
Python correctness: - app.py: define InitializationManager.initial_retry_delay (2.0) so the security-init retry loop no longer raises AttributeError before retrying; it now retries 3x with exponential backoff. - app.py: fail loud instead of fail open. Critical init (system readiness, security, database) now raises CriticalInitializationError, which propagates out of the startup handler to fail the ASGI lifespan so systemd can detect a broken start. Token-manager failure remains non-fatal (limited functionality). - database.py: fix undefined self.log -> module-level log in initialize_with_retry (would have AttributeError'd on the DB retry path). systemd / debian: - wlanpi-core.service: remove duplicate Type=notify; add Restart=on-failure + RestartSec=2 and StartLimitIntervalSec/StartLimitBurst in [Unit] with a finite burst; add RequiresMountsFor for current state/log paths; add ExecStartPre writable probe. - install/usr/bin/wlanpi-core-preflight: new ExecStartPre helper (shell, since a unit cannot import Python constants) that verifies the current state dir is writable; wired into debian/wlanpi-core.install. - wlanpi-core.socket: fix stale '# wlanpi-webui.socket' header comment. - wlanpi-core.service: bind absolute unix:/run/wlanpi_core.sock (matches the socket unit ListenStream and nginx proxy_pass) instead of the relative unix:wlanpi_core.sock that resolved to a different socket. - prerm: fix wrong mount-unit name (var-log-wlanpi_core-debug.mount); add #DEBHELPER# so dh injects the service/socket stop on removal. Scope: A0 only. Keeps current /home/wlanpi state paths (flip is a later PR).
- wlanpi-core.service: add TimeoutStartSec=30 in [Service] to bound the start wait before the restart policy engages on a first-boot failure. - wlanpi-core-preflight: mkdir -p -m 0700 so the state dir is created 0700 instead of the default 0755. PrivateTmp left as false intentionally (cross-process /tmp reads: lldpneigh/cdpneigh); tmp hardening deferred to a separate PR.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix a first-boot initialization failure and clean up the systemd unit + Debian maintainer scripts.
This effort does NOT include the state move to
/home/wlanpi-core, auth rework, or root-only perms.Changes
Core
app.py: defineInitializationManager.initial_retry_delay(was undefined ->AttributeErrorcrashed the security-init retry before it retried).app.py: fail loud on critical init — readiness/security/database failures now raiseCriticalInitializationErrorand fail the ASGI lifespan instead of logging and continuing (previously db/token failures setinitialized=Trueand returned success). Token-manager failure stays non-fatal (limited functionality; health loop recovers).database.py: fix undefinedself.log-> module-levellogininitialize_with_retry.systemd / Debian
wlanpi-core.service: remove duplicateType=notify; addRestart=on-failure+RestartSec=2+StartLimitIntervalSec=60/StartLimitBurst=5(finite burst so a permanent failure can't tight-loop) +TimeoutStartSec=30;RequiresMountsForfor the current state paths;ExecStartPrewritability probe.install/usr/bin/wlanpi-core-preflighthelper (probes the state dir is writable; creates it 0700) wired intodebian/wlanpi-core.install.wlanpi-core.socket: fix stale header comment./run/wlanpi_core.sock) so it matches nginxproxy_passand the socket unit.debian/prerm: fix wrong mount-unit name (var-log-wlanpi_core-debug.mount) and add#DEBHELPER#so the service/socket are stopped on removal.Testing
pytest -q: 400 passed, 20 skipped, 0 failures.initialize_components, so the fail-loud/retry paths aren't exercised by app-level tests: TODO: follow-up to add real unit tests.Validation this PR should exercise
lintian+systemd-analyze verify.Follow-ups
/tmphandoffs to/runand enablePrivateTmp=true.mock_app_initializationautouse fixture).multi-user.target+ socket activation).