From 0a29464d42d81ef02ae10a05c6daacf48f5c702f Mon Sep 17 00:00:00 2001 From: copilotcoder Date: Sun, 5 Jul 2026 12:30:46 -0400 Subject: [PATCH] fix(runners): update deploy memory without mem_limit conflict --- .../gitea-actions/deploy-runner-config.xsh | 137 +++++++++++++++--- 1 file changed, 116 insertions(+), 21 deletions(-) diff --git a/scripts/gitea-actions/deploy-runner-config.xsh b/scripts/gitea-actions/deploy-runner-config.xsh index 2d3ee69..adda065 100755 --- a/scripts/gitea-actions/deploy-runner-config.xsh +++ b/scripts/gitea-actions/deploy-runner-config.xsh @@ -73,6 +73,23 @@ def scp(local_path, host, remote_path): return proc.returncode, proc.stdout + proc.stderr +def service_block_bounds(lines, start_index): + service_indent = len(lines[start_index]) - len(lines[start_index].lstrip(" ")) + block_start = start_index + 1 + block_end = len(lines) + j = block_start + while j < len(lines): + cur = lines[j] + cur_stripped = cur.strip() + if cur_stripped: + cur_indent = len(cur) - len(cur.lstrip(" ")) + if cur_indent <= service_indent: + block_end = j + break + j += 1 + return service_indent, block_start, block_end + + def upsert_service_key(compose_text, service_names, key, value): lines = compose_text.splitlines() i = 0 @@ -83,22 +100,9 @@ def upsert_service_key(compose_text, service_names, key, value): i += 1 continue - service_indent = len(lines[i]) - len(lines[i].lstrip(" ")) + service_indent, block_start, block_end = service_block_bounds(lines, i) field_indent = " " * (service_indent + 2) - block_start = i + 1 - block_end = len(lines) - j = block_start - while j < len(lines): - cur = lines[j] - cur_stripped = cur.strip() - if cur_stripped: - cur_indent = len(cur) - len(cur.lstrip(" ")) - if cur_indent <= service_indent: - block_end = j - break - j += 1 - key_prefix = f"{key}:" found_idx = None for k in range(block_start, block_end): @@ -118,6 +122,68 @@ def upsert_service_key(compose_text, service_names, key, value): return "\n".join(lines) + "\n" +def remove_service_key(compose_text, service_names, key): + lines = compose_text.splitlines() + i = 0 + + while i < len(lines): + stripped = lines[i].strip() + if stripped.rstrip(":") not in service_names or not stripped.endswith(":"): + i += 1 + continue + + _, block_start, block_end = service_block_bounds(lines, i) + key_prefix = f"{key}:" + filtered = [] + for idx in range(block_start, block_end): + if not lines[idx].strip().startswith(key_prefix): + filtered.append(lines[idx]) + + lines = lines[:block_start] + filtered + lines[block_end:] + i = block_start + len(filtered) + + return "\n".join(lines) + "\n" + + +def upsert_service_deploy_memory(compose_text, service_names, value): + lines = compose_text.splitlines() + i = 0 + + while i < len(lines): + stripped = lines[i].strip() + if stripped.rstrip(":") not in service_names or not stripped.endswith(":"): + i += 1 + continue + + service_indent, block_start, block_end = service_block_bounds(lines, i) + deploy_indent = " " * (service_indent + 2) + resources_indent = " " * (service_indent + 4) + limits_indent = " " * (service_indent + 6) + memory_indent = " " * (service_indent + 8) + + memory_idx = None + for idx in range(block_start, block_end): + if lines[idx].strip().startswith("memory:"): + memory_idx = idx + break + + if memory_idx is not None: + lines[memory_idx] = f"{memory_indent}memory: {value}" + i = block_end + continue + + insert_lines = [ + f"{deploy_indent}deploy:", + f"{resources_indent}resources:", + f"{limits_indent}limits:", + f"{memory_indent}memory: {value}", + ] + lines = lines[:block_start] + insert_lines + lines[block_start:] + i = block_end + len(insert_lines) + + return "\n".join(lines) + "\n" + + def parse_mem_value_to_mib(raw_value): value = raw_value.strip().lower() if not value: @@ -172,6 +238,26 @@ def find_service_key_value(compose_text, service_names, key): return None +def find_service_memory_value(compose_text, service_names): + lines = compose_text.splitlines() + i = 0 + + while i < len(lines): + stripped = lines[i].strip() + if stripped.rstrip(":") not in service_names or not stripped.endswith(":"): + i += 1 + continue + + _, block_start, block_end = service_block_bounds(lines, i) + for idx in range(block_start, block_end): + cur = lines[idx].strip() + if cur.startswith("memory:"): + return cur.split(":", 1)[1].strip() + i = block_end + + return None + + def build_compose(compose_text, runner_mem_limit): updated = compose_text @@ -185,12 +271,9 @@ def build_compose(compose_text, runner_mem_limit): 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) - updated = upsert_service_key( - updated, - {"act_runner_1", "act_runner_2", "runner1", "runner2"}, - "mem_limit", - runner_mem_limit, - ) + runner_services = {"act_runner_1", "act_runner_2", "runner1", "runner2"} + updated = remove_service_key(updated, runner_services, "mem_limit") + updated = upsert_service_deploy_memory(updated, runner_services, runner_mem_limit) return updated @@ -211,6 +294,14 @@ def host_mem_limit(host, fraction): def current_runner_baseline_mib(host, compose_text): + deploy_memory_value = find_service_memory_value( + compose_text, + {"act_runner_1", "act_runner_2", "runner1", "runner2"}, + ) + deploy_mib = parse_mem_value_to_mib(deploy_memory_value) if deploy_memory_value else None + if deploy_mib and deploy_mib > 0: + return deploy_mib, f"compose(deploy.memory={deploy_memory_value})" + compose_value = find_service_key_value( compose_text, {"act_runner_1", "act_runner_2", "runner1", "runner2"}, @@ -297,10 +388,14 @@ 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 'mem_limit:' {root}/compose.yml") + rc, out = ssh(host, f"grep -n 'memory:' {root}/compose.yml") print(out.strip()) rc, out = ssh(host, f"docker compose -f {root}/compose.yml up -d act_runner_1") + if rc != 0: + print(out.strip()) + print("Failed to apply compose changes on host") + continue print(out.strip()) rc, out = ssh(host, "docker inspect gitea-act-runner-1 --format '{{range .Mounts}}{{.Destination}} {{end}}'")