feat(runners): set job container memory below runner
All checks were successful
CICD Start / Sanity and Base Decision (push) Successful in 28s
CICD Start / Sanity and Base Decision (pull_request) Successful in 1m6s

This commit is contained in:
copilotcoder
2026-07-05 12:38:15 -04:00
parent 0a29464d42
commit 9ae4d6eafb

View File

@@ -19,7 +19,9 @@ HOSTS = {
}
DEFAULT_MEM_FRACTION = 0.75
DEFAULT_JOB_MEM_FRACTION = 0.9
MIN_RUNNER_MEM_MIB = 1024
MIN_JOB_MEM_MIB = 128
def parse_mem_fraction(argv):
@@ -35,6 +37,20 @@ def parse_mem_fraction(argv):
raise SystemExit("--mem-fraction must be > 0 and <= 1")
return fraction
def parse_job_mem_fraction(argv):
fraction = DEFAULT_JOB_MEM_FRACTION
for arg in argv[1:]:
if arg.startswith("--job-mem-fraction="):
_, value = arg.split("=", 1)
try:
fraction = float(value)
except ValueError as exc:
raise SystemExit(f"Invalid --job-mem-fraction value: {value}") from exc
if fraction <= 0 or fraction > 1:
raise SystemExit("--job-mem-fraction must be > 0 and <= 1")
return fraction
def ssh(host, cmd):
proc = subprocess.run(
[
@@ -184,6 +200,25 @@ def upsert_service_deploy_memory(compose_text, service_names, value):
return "\n".join(lines) + "\n"
def upsert_compose_env_var(compose_text, var_name, var_value, anchor_line):
lines = compose_text.splitlines()
new_line = f" - {var_name}={var_value}"
replaced = False
for idx, line in enumerate(lines):
stripped = line.strip()
if stripped.startswith(f"- {var_name}="):
lines[idx] = new_line
replaced = True
if not replaced:
for idx, line in enumerate(lines):
if line.strip() == anchor_line.strip():
lines.insert(idx + 1, new_line)
return "\n".join(lines) + "\n"
def parse_mem_value_to_mib(raw_value):
value = raw_value.strip().lower()
if not value:
@@ -258,7 +293,7 @@ def find_service_memory_value(compose_text, service_names):
return None
def build_compose(compose_text, runner_mem_limit):
def build_compose(compose_text, runner_mem_limit, job_mem_limit):
updated = compose_text
volume_line = " - ./daemon.json:/etc/docker/daemon.json:ro"
@@ -268,7 +303,15 @@ def build_compose(compose_text, runner_mem_limit):
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:
if force_pull_line in updated:
updated = upsert_compose_env_var(updated, "CONFIG_FILE", "/config.yaml", force_pull_line)
updated = upsert_compose_env_var(
updated,
"GITEA_RUNNER_JOB_CONTAINER_OPTIONS",
f"--memory={job_mem_limit} --memory-swap={job_mem_limit}",
force_pull_line,
)
elif add_cfg_env not in updated:
updated = updated.replace(force_pull_line, force_pull_line + "\n" + add_cfg_env)
runner_services = {"act_runner_1", "act_runner_2", "runner1", "runner2"}
@@ -321,8 +364,10 @@ def current_runner_baseline_mib(host, compose_text):
mem_fraction = parse_mem_fraction(sys.argv)
job_mem_fraction = parse_job_mem_fraction(sys.argv)
print(f"Runner mem fraction: {mem_fraction:.2f}")
print(f"Job mem fraction: {job_mem_fraction:.2f}")
print("Fetching canonical runner config template")
rc, template = ssh(TEMPLATE_HOST, f"cat {TEMPLATE_PATH}")
if rc != 0 or not template.strip():
@@ -360,7 +405,15 @@ with tempfile.TemporaryDirectory() as tmpdir:
print(f"runner_mem_baseline={baseline_source}")
print(f"runner_mem_limit={runner_mem_limit} ({runner_mem_mib} MiB)")
new_compose = build_compose(compose, runner_mem_limit)
job_mem_mib = int(runner_mem_mib * job_mem_fraction)
if job_mem_mib < MIN_JOB_MEM_MIB:
job_mem_mib = MIN_JOB_MEM_MIB
if job_mem_mib >= runner_mem_mib and runner_mem_mib > 1:
job_mem_mib = runner_mem_mib - 1
job_mem_limit = f"{job_mem_mib}m"
print(f"job_mem_limit={job_mem_limit} ({job_mem_mib} MiB)")
new_compose = build_compose(compose, runner_mem_limit, job_mem_limit)
rc, _ = ssh(host, f"mkdir -p {root}/backups")
rc, _ = ssh(host, f"cp -f {root}/compose.yml {root}/backups/compose.yml.{now}")
@@ -388,6 +441,8 @@ with tempfile.TemporaryDirectory() as tmpdir:
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"grep -n 'GITEA_RUNNER_JOB_CONTAINER_OPTIONS=' {root}/compose.yml")
print(out.strip())
rc, out = ssh(host, f"grep -n 'memory:' {root}/compose.yml")
print(out.strip())