CIS490/etc/cis490-orchestrator.service
Elliott Kolden 842918556b Add automated campaign runner, shipper, and systemd units
Implements the unattended episode loop described in docs/deploy.md but not
yet built. run_campaign.py boots a fresh VM per episode, drives the full
phase schedule via the existing EpisodeRunner/VMLoadController stack, writes
campaign.json atomically after each episode, and signals completion with
campaign_done.marker. shipper.py watches data/episodes/ for done.marker
files, tar+zstd-compresses each, and PUTs them to the receiver with
exponential backoff on failure. Both support SIGTERM gracefully, finishing
the current episode/scan before exiting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 14:53:40 -06:00

33 lines
742 B
Desktop File

[Unit]
Description=CIS490 episode campaign runner
Documentation=https://maxgit.wg/spectral/CIS490
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=cis490
Group=cis490
SupplementaryGroups=kvm
WorkingDirectory=/opt/cis490
ExecStart=/opt/cis490/.venv/bin/python tools/run_campaign.py \
--data-root /var/lib/cis490/data \
--target 100
Restart=on-failure
RestartSec=10
# Hardening
NoNewPrivileges=true
PrivateTmp=false
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/cis490 /tmp/cis490-vm /dev/kvm
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
LockPersonality=true
RestrictRealtime=true
SystemCallArchitectures=native
[Install]
WantedBy=multi-user.target