mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-09 13:35:12 +09:00
ServiceControl.is_active raises FileNotFoundError when systemctl is absent -- deliberately, so a host without systemd reads as "could not check" rather than "not running". DovecotService.get_status called it unguarded, so GET /api/v1/email/status returned a 500 on every such host. Email.jsx catches that and renders "Mail server not installed" with an Install button, on a box already running Postfix and Dovecot. Guarding only the is_active line -- the literal review comment -- leaves the second escape route open one statement later: both wrappers carry timeout=PROBE_TIMEOUT, so a systemd that stops answering raises TimeoutExpired straight through is_enabled, which swallows only the missing binary. Hence (subprocess.SubprocessError, FileNotFoundError), covering both probes -- the same pair dkim, spamassassin, ftp and postfix already catch. running/enabled report None on an unreadable probe. Fabricating False here is exactly the dishonesty this round removed from the firewall and SSL services. email_service keeps its top-level `running` boolean with bool(), since `True and None` is None and that field is documented as a boolean; the honest tri-state stays in the per-component dicts. Mutation-checked by line number: the narrow `except FileNotFoundError` fails 2 of the 4 new tests, a guard catching neither fails 3, and the healthy path passes throughout. Reported by Copilot on the plan-75 PR (is_active only). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>