/var/lib/ci/backups was root:root because ci-backup-template.service runs as root and mkdir(exist_ok=True) created it before ci-runner ever touched it, so every 7z backup failed with errno=13. Chown to ci-runner:ci-runner + 750, and stop the drift from coming back: the setup script now creates+chmods the dir, and the systemd unit gets an ExecStartPre that (re)installs it with the right owner on every start.
40 lines
1.7 KiB
Desktop File
40 lines
1.7 KiB
Desktop File
[Unit]
|
|
Description=Local CI/CD — weekly backup of VMware templates
|
|
Documentation=file:///opt/ci/local-ci-cd-system/deploy/systemd/README.md
|
|
After=network-online.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
User=root
|
|
EnvironmentFile=/etc/ci/environment
|
|
WorkingDirectory=/opt/ci/local-ci-cd-system
|
|
# This service runs as root (to restart act-runner.service via ExecStopPost),
|
|
# but the backups dir is shared with ci-web.service, which runs as ci-runner
|
|
# and offers a manual "backup template" action. Guarantee the dir exists owned
|
|
# by ci-runner *before* the root-owned backup writes into it, otherwise a first
|
|
# root run would create /var/lib/ci/backups as root:root and lock ci-runner
|
|
# (the web UI) out with errno=13. Idempotent; -o/-g re-assert ownership.
|
|
ExecStartPre=/usr/bin/install -d -o ci-runner -g ci-runner -m 750 /var/lib/ci/backups
|
|
# --keep-count 1: three generations of Windows templates cost ~195 GB and the
|
|
# archives were byte-identical between runs (the templates rarely change), so
|
|
# the extra generations bought nothing. --exclude WinBuildTest: retired test
|
|
# template, ~26 GB per generation.
|
|
ExecStart=/opt/ci/venv/bin/python -m ci_orchestrator template backup --all-templates --keep-count 1 --exclude WinBuildTest
|
|
# Safety net: bring act-runner.service back up on any exit path (success,
|
|
# failure, signal). The Python `finally` block can be skipped if the
|
|
# service is killed mid-run, and a runner left stopped by a killed
|
|
# backup would cause the next backup to skip the restart too.
|
|
ExecStopPost=-/bin/systemctl start act-runner.service
|
|
TimeoutStartSec=4h
|
|
IOSchedulingClass=best-effort
|
|
IOSchedulingPriority=7
|
|
Nice=19
|
|
ProtectSystem=strict
|
|
ProtectHome=true
|
|
PrivateTmp=true
|
|
NoNewPrivileges=true
|
|
ReadWritePaths=/var/lib/ci
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|