YAML · 7179 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 shithubd-runner binary (built by `make build` locally)
126 copy:
127 src: "{{ playbook_dir }}/../../bin/shithubd-runner"
128 dest: /usr/local/bin/shithubd-runner
129 mode: "0755"
130 owner: root
131 group: root
132 notify: restart shithubd-runner
133
134 - name: Archive a versioned runner binary copy
135 shell: cp /usr/local/bin/shithubd-runner /var/lib/shithubd-runner/binaries/shithubd-runner-$(date +%Y%m%d-%H%M%S)
136 args:
137 creates: /var/lib/shithubd-runner/binaries/shithubd-runner-{{ ansible_date_time.iso8601_basic_short }}
138
139 - name: Runner config file
140 template:
141 src: config.toml.j2
142 dest: /etc/shithubd-runner/config.toml
143 owner: root
144 group: shithub-runner
145 mode: "0640"
146 notify: restart shithubd-runner
147
148 - name: Runner env file
149 template:
150 src: runner.env.j2
151 dest: /etc/shithubd-runner/runner.env
152 owner: shithub-runner
153 group: shithub-runner
154 mode: "0600"
155 no_log: true
156 notify: restart shithubd-runner
157
158 - name: Runner seccomp profile
159 copy:
160 src: "{{ playbook_dir }}/../runner-config/seccomp.json"
161 dest: "{{ shithub_runner_seccomp_profile }}"
162 owner: root
163 group: shithub-runner
164 mode: "0640"
165 notify: restart shithubd-runner
166
167 - name: Runner DNS allowlist template
168 template:
169 src: "{{ playbook_dir }}/../runner-config/dnsmasq.conf.j2"
170 dest: "{{ shithub_runner_dnsmasq_config }}"
171 owner: root
172 group: root
173 mode: "0644"
174 notify: restart dnsmasq
175
176 - name: Runner firewall script
177 template:
178 src: "{{ playbook_dir }}/../runner-config/firewall.sh.j2"
179 dest: "{{ shithub_runner_firewall_script }}"
180 owner: root
181 group: root
182 mode: "0755"
183 notify: restart shithub-runner-firewall
184
185 - name: Runner firewall systemd unit
186 copy:
187 src: "{{ playbook_dir }}/../systemd/shithub-runner-firewall.service"
188 dest: /etc/systemd/system/shithub-runner-firewall.service
189 mode: "0644"
190 notify: [daemon-reload, restart shithub-runner-firewall]
191
192 - name: Enable + start runner firewall
193 systemd:
194 name: shithub-runner-firewall
195 state: started
196 enabled: yes
197 daemon_reload: yes
198
199 - name: Enable + start runner dnsmasq
200 systemd: { name: dnsmasq, state: started, enabled: yes }
201
202 - name: Runner systemd unit
203 copy:
204 src: "{{ playbook_dir }}/../systemd/shithubd-runner.service"
205 dest: /etc/systemd/system/shithubd-runner.service
206 mode: "0644"
207 notify: [daemon-reload, restart shithubd-runner]
208
209 - name: Pull default runner image
210 command: "{{ shithub_runner_engine }} pull {{ shithub_runner_default_image }}"
211 changed_when: false
212 when: not ansible_check_mode
213
214 - name: Enable + start shithubd-runner
215 systemd: { name: shithubd-runner, state: started, enabled: yes }
216