Files
plex-playlist/scripts/gitea-actions/deploy-runner-config.xsh
copilotcoder de66e9134d
All checks were successful
CICD Start / Sanity and Base Decision (pull_request) Successful in 1m7s
Scripts for restructuring the gitea runners.
Signed-off-by: copilotcoder <copilotcoder@darkhelm.org>
2026-06-16 09:54:31 -04:00

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")