YAML · 7645 bytes Raw Blame History
1 ---
2 # SPDX-License-Identifier: AGPL-3.0-or-later
3 #
4 # shithubd-runner role: installs the runner binary, config, default
5 # container image, and systemd unit. Docker itself is a host prerequisite.
6
7 - name: Runner token is configured
8 assert:
9 that:
10 - shithub_runner_token | length > 0
11 - shithub_runner_engine == "docker"
12 fail_msg: >-
13 shithub_runner_token is required and the Ansible role supports
14 shithub_runner_engine=docker. Generate a token with
15 `shithubd admin runner register`, store it in the inventory or
16 vault, and keep Docker installed on the runner host.
17 no_log: true
18
19 - name: Runner workspace is inside the systemd write path
20 assert:
21 that:
22 - (shithub_runner_workspace_root | string) is match("^/var/lib/shithubd-runner(/|$)")
23 fail_msg: >-
24 shithub_runner_workspace_root must stay under /var/lib/shithubd-runner
25 unless the shithubd-runner systemd unit's ReadWritePaths= hardening is
26 updated with the matching path.
27
28 - name: Runner Docker bridge name fits Linux interface limit
29 assert:
30 that:
31 - (shithub_runner_network_bridge | string | length) <= 15
32 fail_msg: >-
33 shithub_runner_network_bridge must be 15 characters or fewer because
34 Linux interface names are capped by IFNAMSIZ.
35
36 - name: Docker group exists
37 getent:
38 database: group
39 key: docker
40 when: shithub_runner_engine == "docker"
41
42 - name: Runner network firewall packages
43 apt:
44 name:
45 - dnsmasq
46 - ipset
47 - iptables
48 state: present
49 update_cache: yes
50 when: shithub_runner_engine == "docker"
51
52 - name: Runner group
53 group:
54 name: shithub-runner
55 system: yes
56
57 - name: Runner user
58 user:
59 name: shithub-runner
60 group: shithub-runner
61 groups: docker
62 append: yes
63 system: yes
64 create_home: no
65 home: /var/lib/shithubd-runner
66 shell: /usr/sbin/nologin
67
68 - name: Runner directories
69 file:
70 path: "{{ item.path }}"
71 state: directory
72 owner: "{{ item.owner }}"
73 group: "{{ item.group }}"
74 mode: "{{ item.mode }}"
75 loop:
76 - { path: /etc/shithubd-runner, owner: root, group: shithub-runner, mode: "0750" }
77 - { path: /var/lib/shithubd-runner, owner: shithub-runner, group: shithub-runner, mode: "0750" }
78 - { path: "{{ shithub_runner_workspace_root }}", owner: shithub-runner, group: shithub-runner, mode: "0750" }
79 - { path: /var/lib/shithubd-runner/binaries, owner: shithub-runner, group: shithub-runner, mode: "0750" }
80
81 - name: Inspect Actions Docker network
82 command: "{{ shithub_runner_engine }} network inspect {{ shithub_runner_network }}"
83 register: shithub_runner_network_inspect
84 failed_when: shithub_runner_network_inspect.rc not in [0, 1]
85 changed_when: false
86 when: shithub_runner_engine == "docker" and not ansible_check_mode
87
88 - name: Create Actions Docker network
89 command: >-
90 {{ shithub_runner_engine }} network create
91 --driver bridge
92 --subnet {{ shithub_runner_network_subnet }}
93 --gateway {{ shithub_runner_network_gateway }}
94 --opt com.docker.network.bridge.name={{ shithub_runner_network_bridge }}
95 {{ shithub_runner_network }}
96 when:
97 - shithub_runner_engine == "docker"
98 - not ansible_check_mode
99 - shithub_runner_network_inspect.rc == 1
100
101 - name: Inspect Actions Docker network after converge
102 command: "{{ shithub_runner_engine }} network inspect {{ shithub_runner_network }}"
103 register: shithub_runner_network_final
104 changed_when: false
105 when: shithub_runner_engine == "docker" and not ansible_check_mode
106
107 - name: Record Actions Docker network facts
108 set_fact:
109 shithub_runner_network_info: "{{ (shithub_runner_network_final.stdout | from_json)[0] }}"
110 when: shithub_runner_engine == "docker" and not ansible_check_mode
111
112 - name: Actions Docker network matches runner firewall config
113 assert:
114 that:
115 - shithub_runner_network_info.Driver == "bridge"
116 - shithub_runner_network_info.Options["com.docker.network.bridge.name"] == shithub_runner_network_bridge
117 - shithub_runner_network_info.IPAM.Config[0].Subnet == shithub_runner_network_subnet
118 - shithub_runner_network_info.IPAM.Config[0].Gateway == shithub_runner_network_gateway
119 fail_msg: >-
120 Existing Docker network {{ shithub_runner_network }} does not match the
121 configured Actions subnet/gateway/bridge. Remove or rename the network
122 before re-running the role so firewall rules target the correct bridge.
123 when: shithub_runner_engine == "docker" and not ansible_check_mode
124
125 - name: Upload candidate shithubd-runner binary (built by `make build` locally)
126 copy:
127 src: "{{ playbook_dir }}/../../bin/shithubd-runner"
128 dest: /var/lib/shithubd-runner/binaries/shithubd-runner-candidate
129 mode: "0755"
130 owner: root
131 group: root
132
133 - name: Candidate runner binary executes on target
134 command: /var/lib/shithubd-runner/binaries/shithubd-runner-candidate version
135 register: shithubd_runner_version
136 changed_when: false
137
138 - name: Promote candidate shithubd-runner binary
139 copy:
140 src: /var/lib/shithubd-runner/binaries/shithubd-runner-candidate
141 dest: /usr/local/bin/shithubd-runner
142 remote_src: true
143 mode: "0755"
144 owner: root
145 group: root
146 notify: restart shithubd-runner
147
148 - name: Archive a versioned runner binary copy
149 shell: cp /usr/local/bin/shithubd-runner /var/lib/shithubd-runner/binaries/shithubd-runner-$(date +%Y%m%d-%H%M%S)
150 args:
151 creates: /var/lib/shithubd-runner/binaries/shithubd-runner-{{ ansible_date_time.iso8601_basic_short }}
152
153 - name: Runner config file
154 template:
155 src: config.toml.j2
156 dest: /etc/shithubd-runner/config.toml
157 owner: root
158 group: shithub-runner
159 mode: "0640"
160 notify: restart shithubd-runner
161
162 - name: Runner env file
163 template:
164 src: runner.env.j2
165 dest: /etc/shithubd-runner/runner.env
166 owner: shithub-runner
167 group: shithub-runner
168 mode: "0600"
169 no_log: true
170 notify: restart shithubd-runner
171
172 - name: Runner seccomp profile
173 copy:
174 src: "{{ playbook_dir }}/../runner-config/seccomp.json"
175 dest: "{{ shithub_runner_seccomp_profile }}"
176 owner: root
177 group: shithub-runner
178 mode: "0640"
179 notify: restart shithubd-runner
180
181 - name: Runner DNS allowlist template
182 template:
183 src: "{{ playbook_dir }}/../runner-config/dnsmasq.conf.j2"
184 dest: "{{ shithub_runner_dnsmasq_config }}"
185 owner: root
186 group: root
187 mode: "0644"
188 notify: restart dnsmasq
189
190 - name: Runner firewall script
191 template:
192 src: "{{ playbook_dir }}/../runner-config/firewall.sh.j2"
193 dest: "{{ shithub_runner_firewall_script }}"
194 owner: root
195 group: root
196 mode: "0755"
197 notify: restart shithub-runner-firewall
198
199 - name: Runner firewall systemd unit
200 copy:
201 src: "{{ playbook_dir }}/../systemd/shithub-runner-firewall.service"
202 dest: /etc/systemd/system/shithub-runner-firewall.service
203 mode: "0644"
204 notify: [daemon-reload, restart shithub-runner-firewall]
205
206 - name: Enable + start runner firewall
207 systemd:
208 name: shithub-runner-firewall
209 state: started
210 enabled: yes
211 daemon_reload: yes
212
213 - name: Enable + start runner dnsmasq
214 systemd: { name: dnsmasq, state: started, enabled: yes }
215
216 - name: Runner systemd unit
217 copy:
218 src: "{{ playbook_dir }}/../systemd/shithubd-runner.service"
219 dest: /etc/systemd/system/shithubd-runner.service
220 mode: "0644"
221 notify: [daemon-reload, restart shithubd-runner]
222
223 - name: Pull default runner image
224 command: "{{ shithub_runner_engine }} pull {{ shithub_runner_default_image }}"
225 changed_when: false
226 when: not ansible_check_mode
227
228 - name: Enable + start shithubd-runner
229 systemd: { name: shithubd-runner, state: started, enabled: yes }
230