-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkarellen-sysbox-ghar-wrapper
executable file
·109 lines (88 loc) · 4.14 KB
/
karellen-sysbox-ghar-wrapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/python3
import argparse
import re
import sys
from configparser import ConfigParser
from os import chmod, makedirs
from os.path import join, isabs, abspath, exists
from subprocess import call, check_call, CalledProcessError
from tempfile import TemporaryDirectory
from requests import Session
from requests.exceptions import HTTPError, RequestException
from requests.auth import HTTPBasicAuth
KERNEL_VERSION = re.compile(r"^Linux version (\d+)\.(\d+)\.(\d+)")
parser = argparse.ArgumentParser("Karellen Sysbox GitHub Action Runner Service Wrapper")
parser.add_argument("--config", default="/etc/sysconfig/karellen-sysbox-ghar")
parser.add_argument("--tmp-dir", default=None)
parser.add_argument("--image", default="ghcr.io/karellen/karellen-gha-runner:latest")
parser.add_argument("service")
def main():
args = parser.parse_args()
service_name = args.service
config = ConfigParser()
config.read(args.config)
with Session() as s:
def post(url, key=None, auth=None, headers=None, data=None):
while True:
h = {}
if headers:
h.update(headers)
h.update({"X-GitHub-Api-Version": "2022-11-28",
"Accept": "application/vnd.github+json"})
if key:
h["Authorization"] = f"Bearer {key}"
if auth:
auth = HTTPBasicAuth(*auth)
try:
with s.post(f"https://{config['github'].get('api-host', 'api.github.com')}/{url}",
headers=h,
auth=auth,
data=data,
timeout=(float(config["github"].get("connection-timeout", "5")),
float(config["github"].get("read-timeout", "15"))),
) as r:
r.raise_for_status()
return r.json()
except RequestException as e:
if e.response and e.response.status_code and 400 <= e.response.status_code <= 407:
raise
print(f"restarting due to GitHub API error {e}", file=sys.stderr)
return 0
reg_token = post(f"orgs/{config['github']['organization']}/actions/runners/registration-token",
config["github"]["pat-token"])["token"]
if False:
rem_token = post(f"orgs/{config['github']['organization']}/actions/runners/remove-token",
config["github"]["pat-token"])["token"]
with open("/proc/version", "rt") as f:
version = tuple(map(int, KERNEL_VERSION.match(f.read()).groups()[0:3]))
# This is due to ID-mapping features: https://github.com/nestybox/sysbox/issues/689#issuecomment-1532460385
mountable_tmp_dir = args.tmp_dir
if not mountable_tmp_dir and version < (6, 3):
mountable_tmp_dir = f"/var/lib/{service_name}"
if mountable_tmp_dir:
if not isabs(mountable_tmp_dir):
mountable_tmp_dir = abspath(mountable_tmp_dir)
if not exists(mountable_tmp_dir):
makedirs(mountable_tmp_dir, mode=0o700, exist_ok=True)
with TemporaryDirectory(dir=mountable_tmp_dir, ignore_cleanup_errors=False) as tmp_dir:
chmod(tmp_dir, 0o700)
reg_f_name = join(tmp_dir, "registration_token")
with open(reg_f_name, "wt") as reg_f:
reg_f.write(reg_token)
chmod(reg_f_name, 0o600)
if False:
rem_f_name = join(tmp_dir, "removal_token")
with open(rem_f_name, "wt") as rem_f:
rem_f.write(rem_token)
chmod(rem_f_name, 0o600)
image = config["service"].get("image", args.image)
try:
call(["docker", "pull", image])
check_call(["docker", "run", "--rm", "-t", "--runtime", "sysbox-runc",
"--name", service_name,
"-v", f"{tmp_dir}:/home/runner/__secure",
image])
except CalledProcessError as e:
return e.returncode
if __name__ == "__main__":
sys.exit(main())