All checks were successful
CICD Start / Sanity and Base Decision (pull_request) Successful in 1m7s
Signed-off-by: copilotcoder <copilotcoder@darkhelm.org>
133 lines
4.2 KiB
Plaintext
Executable File
133 lines
4.2 KiB
Plaintext
Executable File
#!/usr/bin/env xonsh
|
|
|
|
"""Deploy shared runner config.yaml to all hosts and wire compose to use CONFIG_FILE."""
|
|
|
|
import os
|
|
import subprocess
|
|
import tempfile
|
|
from datetime import datetime
|
|
|
|
TEMPLATE_HOST = "kankali.darkhelm.lan"
|
|
TEMPLATE_PATH = "/home/darkhelm/Projects/DarkHelm.org/gitea/runner-config.template.yaml"
|
|
|
|
HOSTS = {
|
|
"kankali.darkhelm.lan": "/home/darkhelm/Projects/DarkHelm.org/gitea",
|
|
"zhokq.darkhelm.lan": "/home/darkhelm/Projects/DarkHelm.org/gitea-runner",
|
|
"urtzul.darkhelm.lan": "/home/darkhelm/Projects/DarkHelm.org/gitea-runner",
|
|
"pi-desktop.darkhelm.lan": "/home/darkhelm/Projects/DarkHelm.org/gitea-runner",
|
|
}
|
|
|
|
def ssh(host, cmd):
|
|
proc = subprocess.run(
|
|
[
|
|
"ssh",
|
|
"-o",
|
|
"ConnectTimeout=30",
|
|
"-o",
|
|
"ServerAliveInterval=30",
|
|
"-o",
|
|
"ServerAliveCountMax=6",
|
|
host,
|
|
cmd,
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
return proc.returncode, proc.stdout + proc.stderr
|
|
|
|
|
|
def scp(local_path, host, remote_path):
|
|
proc = subprocess.run(
|
|
[
|
|
"scp",
|
|
"-o",
|
|
"ConnectTimeout=30",
|
|
"-o",
|
|
"ServerAliveInterval=30",
|
|
"-o",
|
|
"ServerAliveCountMax=6",
|
|
local_path,
|
|
f"{host}:{remote_path}",
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
return proc.returncode, proc.stdout + proc.stderr
|
|
|
|
|
|
def build_compose(compose_text):
|
|
updated = compose_text
|
|
|
|
volume_line = " - ./daemon.json:/etc/docker/daemon.json:ro"
|
|
add_volume = " - ./config.yaml:/config.yaml:ro"
|
|
if add_volume not in updated and volume_line in updated:
|
|
updated = updated.replace(volume_line, volume_line + "\n" + add_volume)
|
|
|
|
force_pull_line = " - GITEA_RUNNER_JOB_CONTAINER_FORCE_PULL=${GITEA_RUNNER_JOB_CONTAINER_FORCE_PULL:-false}"
|
|
add_cfg_env = " - CONFIG_FILE=/config.yaml"
|
|
if add_cfg_env not in updated and force_pull_line in updated:
|
|
updated = updated.replace(force_pull_line, force_pull_line + "\n" + add_cfg_env)
|
|
|
|
return updated
|
|
|
|
|
|
print("Fetching canonical runner config template")
|
|
rc, template = ssh(TEMPLATE_HOST, f"cat {TEMPLATE_PATH}")
|
|
if rc != 0 or not template.strip():
|
|
print("Failed to fetch template from kankali")
|
|
raise SystemExit(2)
|
|
|
|
now = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
local_cfg = os.path.join(tmpdir, "config.yaml")
|
|
with open(local_cfg, "w", encoding="utf-8") as f:
|
|
f.write(template)
|
|
|
|
for host, root in HOSTS.items():
|
|
print(f"\n===== {host} =====")
|
|
|
|
rc, compose = ssh(host, f"cat {root}/compose.yml")
|
|
if rc != 0:
|
|
print("Could not read compose.yml")
|
|
continue
|
|
|
|
new_compose = build_compose(compose)
|
|
|
|
rc, _ = ssh(host, f"mkdir -p {root}/backups")
|
|
rc, _ = ssh(host, f"cp -f {root}/compose.yml {root}/backups/compose.yml.{now}")
|
|
rc, _ = ssh(host, f"test -f {root}/config.yaml")
|
|
if rc == 0:
|
|
ssh(host, f"cp -f {root}/config.yaml {root}/backups/config.yaml.{now}")
|
|
|
|
local_compose = os.path.join(tmpdir, f"compose.{host}.yml")
|
|
with open(local_compose, "w", encoding="utf-8") as f:
|
|
f.write(new_compose)
|
|
|
|
rc, out = scp(local_compose, host, f"{root}/compose.yml")
|
|
if rc != 0:
|
|
print("Failed to upload compose.yml")
|
|
print(out)
|
|
continue
|
|
|
|
rc, out = scp(local_cfg, host, f"{root}/config.yaml")
|
|
if rc != 0:
|
|
print("Failed to upload config.yaml")
|
|
print(out)
|
|
continue
|
|
|
|
rc, out = ssh(host, f"grep -n 'config.yaml:/config.yaml:ro' {root}/compose.yml")
|
|
print(out.strip())
|
|
rc, out = ssh(host, f"grep -n 'CONFIG_FILE=/config.yaml' {root}/compose.yml")
|
|
print(out.strip())
|
|
|
|
rc, out = ssh(host, f"docker compose -f {root}/compose.yml up -d act_runner_1")
|
|
print(out.strip())
|
|
|
|
rc, out = ssh(host, "docker inspect gitea-act-runner-1 --format '{{range .Mounts}}{{.Destination}} {{end}}'")
|
|
print("mounts:", out.strip())
|
|
|
|
print("Done")
|
|
|
|
print("\nDeployment complete")
|