feat(runners): set job container memory below runner
This commit is contained in:
@@ -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())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user