deploy/gitbay-runner.override.conf
72 lines · 3748 bytes
1# Drop-in for gitbay-runner.service, installed by `make deploy-runner` to
2# /etc/systemd/system/gitbay-runner.service.d/override.conf.
3#
4# A build must never starve the host: the e2e suite alone starts sixty
5# daemon instances, and with nothing holding it back a deploy's scp on
6# the admin sshd stalled at 1%. Lower CPU and IO weight keep sshd,
7# gitbayd and the backup timers responsive while a build runs.
8#
9# These weights are for the service, not per build, so `-jobs N` divides
10# them among N builds rather than taking N times as much. Raising -jobs
11# does not need them raised; it makes each build slower, not the host
12# busier.
13#
14# A build runs whatever the repository's ci.yml says, as the runner's
15# own user. Keep that user unprivileged: its key is added with
16# `keys add --scope runner`, which confines it to the runner protocol
17# and read-only git, and the sandboxing below keeps a step from
18# touching the system outside its workspace.
19#
20# Delegate=yes and the storage path below are what rootless podman needs
21# (#144): it manages its own cgroups for a container, and its image and
22# container store lives under the runner's home, which ProtectSystem
23# would otherwise make read-only. Prepare the host with
24# deploy/runner-podman-setup.sh before deploying a runner that isolates.
25[Service]
26# ExecStart is overridden here rather than left in the unit so the flags
27# and the sandboxing that has to match them live in one file: -isolation
28# podman needs NoNewPrivileges=no below, and -image needs an image the
29# host has been given (deploy/runner-podman-setup.sh, Containerfile.ci).
30# podman's run root is pinned under the runner's home by storage.conf
31# (runner-podman-setup.sh), not taken from XDG_RUNTIME_DIR or /tmp: this
32# unit has PrivateTmp, so a /tmp run root is a per-instance tmpfs.
33#
34# The cgroupfs manager puts podman's pause process under the user slice,
35# outside this unit's cgroup, so a stop does not end it and the next
36# start joins its namespaces — including a /tmp that no longer exists.
37# End it with the service.
38ExecStopPost=-/usr/bin/pkill -u ci-runner -x catatonit
39ExecStart=
40ExecStart=/usr/local/bin/gitbay-runner -remote git@127.0.0.1 -workdir /var/lib/gitbay-runner/work -poll 5s -timeout 45m -repos krz/gitbay -isolation podman -image localhost/gitbay-ci:1
41Nice=10
42CPUWeight=30
43IOWeight=30
44# NoNewPrivileges is off, and that is a deliberate trade (#144).
45#
46# Rootless podman sets up its user namespace with newuidmap, a setuid
47# helper; NoNewPrivileges=yes blocks it and podman fails with
48# "newuidmap: write to uid_map failed: Operation not permitted", so the
49# runner refuses to start. The choice is between this flag and running
50# builds in containers at all.
51#
52# Containers are the stronger boundary by a wide margin. NoNewPrivileges
53# constrained a process that was already executing arbitrary repository
54# code as this user; a container confines that code to an image and a
55# bind-mounted workspace. What is lost is one hardening layer on the
56# runner process itself, which is ours rather than a build's — a build no
57# longer runs in this process's context at all.
58#
59# Under -isolation none there is no container, and this flag should be
60# yes. Set it back if you run that way.
61NoNewPrivileges=no
62ProtectSystem=full
63ProtectKernelTunables=yes
64ProtectControlGroups=yes
65RestrictSUIDSGID=yes
66Delegate=yes
67# The runner's home is /var/lib/gitbay-runner (see the Admin page), and
68# the leading - makes a missing path ignored rather than fatal: this
69# drop-in installs on hosts that have not been prepared for podman yet,
70# and a unit that refuses to start would stop every build on the
71# instance.
72ReadWritePaths=-/var/lib/gitbay-runner/.local/share/containers -/var/lib/gitbay-runner/.config/containers