Files
tireless/asset/systemd/tireless-api.service
rob thijssen 267cb3314d
Some checks failed
deploy / deploy (push) Failing after 5m49s
fix(deploy): quote --rsync-path, and let systemd own the state directory
Run 4 failed at `ship artifacts` with `sudo: unrecognized option '--server'`.

`R="--rsync-path=sudo rsync --mkpath"` expanded unquoted as `rsync $R` splits
into three arguments — `--rsync-path=sudo`, plus a stray `rsync` that rsync
reads as a source path — so the remote end ran `sudo --server`. Use an array.
The dashboard step quoted it inline and was unaffected, which is why only half
the deploy was broken.

Every rsync destination and every sudo command in `apply system state` has now
been exercised directly against bob as gitea_ci, rather than by another six
minute round trip: seven rsync targets, sysusers, restorecon, firewalld and
daemon-reload all pass.

That surfaced the second fault. restorecon was given /var/lib/tireless, which
does not exist on a fresh host: infra-setup.sh tried to create it before
systemd-sysusers had created the account to own it, so the attempt always raced
and always lost. Declare StateDirectory=tireless on all three units instead —
systemd creates the directory, owns it as the service user and labels it — and
drop the path from restorecon, the grant, and infra-setup.

Refs #9

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013TxK1CWPkFXqdcXMJ4hVe6
2026-08-07 16:32:31 +03:00

42 lines
1.2 KiB
Desktop File

[Unit]
Description=tireless API
Documentation=https://git.lair.cafe/lair/tireless
After=network-online.target
Wants=network-online.target
[Service]
Type=exec
User=tireless
Group=tireless
Environment=HOME=/var/lib/tireless
ExecStart=/usr/local/bin/tireless-api --config /etc/tireless/config.toml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
# Hardening (architecture/generic.md §8)
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictSUIDSGID=true
LockPersonality=true
MemoryDenyWriteExecute=true
SystemCallArchitectures=native
# StateDirectory rather than a bare ReadWritePaths: systemd creates
# /var/lib/tireless on first start, owns it as the service user, and labels it
# for SELinux. A plain ReadWritePaths requires the directory to already exist,
# which on a fresh host it does not — the service account is created by
# systemd-sysusers during the same deploy that first starts these units.
StateDirectory=tireless
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
[Install]
WantedBy=multi-user.target