orchestrator: anchor pxe+tftp runtime dirs under artifacts parent
CI / Lint + build + test (push) Successful in 1m38s
Release / release (push) Successful in 2m43s

Previously tftp_root defaulted to logs.dir/../tftp and the pxe
runtime dir to logs.dir/../pxe. On a production install that
resolves to /var/log/tftp and /var/log/pxe, both outside the
systemd unit's ReadWritePaths=/var/lib/vetting /var/log/vetting
sandbox. The service crash-looped with "mkdir /var/log/pxe:
read-only file system" as soon as PXE was enabled.

Switch the anchor to filepath.Dir(cfg.Artifacts.Dir) — typically
/var/lib/vetting — which the sandbox already allows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-18 11:14:11 -04:00
parent caebd00d8d
commit 9d17859992
+8 -2
View File
@@ -136,9 +136,15 @@ func main() {
Interval: time.Duration(cfg.Janitor.IntervalMinutes) * time.Minute,
}, &janitor.StoreAdapter{Runs: runStore, Artifacts: artifactStore, Logs: logHub})
// Anchor tftp_root and the pxe runtime dir under artifacts.dir's
// parent (typically /var/lib/vetting), not logs.dir's parent. The
// production systemd unit's ReadWritePaths=/var/lib/vetting /var/log/vetting
// sandbox forbids writing outside those trees, so deriving from
// /var/log/vetting would land us at /var/log/{tftp,pxe} — unwritable.
stateRoot := filepath.Dir(cfg.Artifacts.Dir)
tftpRoot := cfg.PXE.TFTPRoot
if tftpRoot == "" {
tftpRoot = filepath.Join(cfg.Logs.Dir, "..", "tftp")
tftpRoot = filepath.Join(stateRoot, "tftp")
}
var supervisor *pxe.Supervisor
if cfg.PXE.Enabled {
@@ -147,7 +153,7 @@ func main() {
Interface: cfg.PXE.Interface,
DHCPRange: cfg.PXE.DHCPRange,
OrchestratorURL: cfg.PXE.OrchestratorURL,
RuntimeDir: filepath.Join(cfg.Logs.Dir, "..", "pxe"),
RuntimeDir: filepath.Join(stateRoot, "pxe"),
TFTPRoot: tftpRoot,
LiveDir: cfg.PXE.LiveDir,
})