diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index fe71674..bdebb37 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -105,15 +105,29 @@ jobs: # directory for a single-file copy, and Fedora ships neither # /etc/sysusers.d nor /etc/firewalld/services # (architecture/deployment-gitea-actions.md ยง6). - R=(--rsync-path="sudo rsync --mkpath") + # -p so --chmod actually applies. Without it, --chmod only affects + # files rsync transfers, so a redeploy whose config is byte-identical + # leaves whatever mode the file already had โ€” including a wrong one. + R=(-p --rsync-path="sudo rsync --mkpath") B=target/x86_64-unknown-linux-musl/release - rsync "${R[@]}" --chmod 0755 "$B/tireless-api" \ + rsync "${R[@]}" --chmod=F755 "$B/tireless-api" \ gitea_ci@"$API_HOST":/usr/local/bin/tireless-api - rsync "${R[@]}" --chmod 0755 "$B/tireless-worker" \ + rsync "${R[@]}" --chmod=F755 "$B/tireless-worker" \ gitea_ci@"$API_HOST":/usr/local/bin/tireless-worker - rsync "${R[@]}" --chmod 0755 "$B/tireless" \ + rsync "${R[@]}" --chmod=F755 "$B/tireless" \ gitea_ci@"$API_HOST":/usr/local/bin/tireless - rsync "${R[@]}" --chmod 0640 config.toml \ + # 0644 root:root, not 0640: the services run as `tireless`, which is + # not in the root group, so 0640 root:root is unreadable to them โ€” + # and `--chown root:tireless` cannot be used here because on a fresh + # host the group does not exist until systemd-sysusers runs, later in + # this same deploy. + # + # World-readable is acceptable because this file carries no secrets by + # design: tokens are named by environment variable rather than written + # down, and there is a test asserting no api-key field can appear in it. + # The file that does carry secrets is /etc/tireless/tireless.env, which + # stays 0640 root:tireless and is installed by hand, never by CI. + rsync "${R[@]}" --chmod=F644 config.toml \ gitea_ci@"$API_HOST":/etc/tireless/config.toml rsync "${R[@]}" asset/systemd/tireless.sysusers.conf \ gitea_ci@"$API_HOST":/etc/sysusers.d/tireless.conf diff --git a/asset/systemd/tireless-runner.service b/asset/systemd/tireless-runner.service index ea11071..daa045a 100644 --- a/asset/systemd/tireless-runner.service +++ b/asset/systemd/tireless-runner.service @@ -4,6 +4,15 @@ Documentation=https://git.lair.cafe/lair/tireless After=network-online.target Wants=network-online.target +# Give up rather than loop. The runner's preflight fails permanently when the +# service account has no agent login, and that needs a human โ€” so `Restart=on-failure` +# with a 30s backoff would retry forever without ever getting closer. The default +# rate limit (5 starts / 10s) never trips at that interval, so state it explicitly: +# three attempts in ten minutes, then sit in `failed` where `systemctl status` +# reports the reason. +StartLimitIntervalSec=600 +StartLimitBurst=3 + [Service] Type=exec User=tireless