feat: allow forced AgentRun runner cleanup
This commit is contained in:
+17
-5
@@ -1677,6 +1677,7 @@ interface CleanupRunnersOptions extends ConfirmOptions {
|
||||
node: string | null;
|
||||
lane: string | null;
|
||||
timeoutSeconds: number;
|
||||
forceActive: boolean;
|
||||
}
|
||||
|
||||
interface CleanupRunsOptions extends ConfirmOptions {
|
||||
@@ -1935,13 +1936,14 @@ function parseGitMirrorOptions(args: string[]): GitMirrorOptions {
|
||||
}
|
||||
|
||||
function parseCleanupRunnersOptions(args: string[]): CleanupRunnersOptions {
|
||||
validateOptions(args, new Set(["--confirm", "--dry-run"]), new Set(["--timeout-seconds", "--node", "--lane"]));
|
||||
validateOptions(args, new Set(["--confirm", "--dry-run", "--force-active"]), new Set(["--timeout-seconds", "--node", "--lane"]));
|
||||
const base = parseConfirmOptions(args);
|
||||
return {
|
||||
...base,
|
||||
node: optionValue(args, "--node") ?? null,
|
||||
lane: optionValue(args, "--lane") ?? null,
|
||||
timeoutSeconds: positiveIntegerOption(args, "--timeout-seconds", 180, 600),
|
||||
forceActive: args.includes("--force-active"),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2925,7 +2927,7 @@ async function cleanupRunners(config: UniDeskConfig, options: CleanupRunnersOpti
|
||||
dryRun: true,
|
||||
mutation: false,
|
||||
next: {
|
||||
confirm: `bun scripts/cli.ts agentrun control-plane cleanup-runners --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
|
||||
confirm: `bun scripts/cli.ts agentrun control-plane cleanup-runners --node ${spec.nodeId} --lane ${spec.lane}${options.forceActive ? " --force-active" : ""} --confirm`,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -2934,7 +2936,7 @@ async function cleanupRunners(config: UniDeskConfig, options: CleanupRunnersOpti
|
||||
dryRun: false,
|
||||
mutation: true,
|
||||
followUp: {
|
||||
dryRun: `bun scripts/cli.ts agentrun control-plane cleanup-runners --node ${spec.nodeId} --lane ${spec.lane} --dry-run`,
|
||||
dryRun: `bun scripts/cli.ts agentrun control-plane cleanup-runners --node ${spec.nodeId} --lane ${spec.lane}${options.forceActive ? " --force-active" : ""} --dry-run`,
|
||||
status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
|
||||
},
|
||||
};
|
||||
@@ -3030,6 +3032,7 @@ function cleanupRunnersScript(options: CleanupRunnersOptions, spec: AgentRunLane
|
||||
`age_based_cleanup_enabled=${retention.ageBasedCleanup.enabled ? "true" : "false"}`,
|
||||
`age_based_max_age_hours=${retention.ageBasedCleanup.maxAgeHours === null ? "" : String(retention.ageBasedCleanup.maxAgeHours)}`,
|
||||
`timeout_seconds=${String(options.timeoutSeconds)}`,
|
||||
`force_active=${options.forceActive ? "true" : "false"}`,
|
||||
`match_labels_json_b64=${shQuote(matchLabelsB64)}`,
|
||||
`job_name_prefixes_json_b64=${shQuote(jobNamePrefixesB64)}`,
|
||||
"match_labels_json=$(printf '%s' \"$match_labels_json_b64\" | base64 -d)",
|
||||
@@ -3048,7 +3051,7 @@ function cleanupRunnersScript(options: CleanupRunnersOptions, spec: AgentRunLane
|
||||
"if [ \"$facts_exit\" -ne 0 ]; then",
|
||||
" printf '%s\\n' '{\"ok\":false,\"items\":[],\"failureKind\":\"manager-facts-unavailable\",\"valuesPrinted\":false}' > \"$tmp_dir/runner-facts.json\"",
|
||||
"fi",
|
||||
"MATCH_LABELS_JSON=\"$match_labels_json\" JOB_NAME_PREFIXES_JSON=\"$job_name_prefixes_json\" MAX_RUNNERS=\"$max_runners\" CLEANUP_ORDER=\"$cleanup_order\" ACTIVE_HEARTBEAT_MAX_AGE_MS=\"$active_heartbeat_max_age_ms\" AGE_BASED_CLEANUP_ENABLED=\"$age_based_cleanup_enabled\" AGE_BASED_MAX_AGE_HOURS=\"$age_based_max_age_hours\" FACTS_EXIT=\"$facts_exit\" TMP_DIR=\"$tmp_dir\" NAMESPACE=\"$namespace\" node <<'NODE' > \"$tmp_dir/plan.json\"",
|
||||
"MATCH_LABELS_JSON=\"$match_labels_json\" JOB_NAME_PREFIXES_JSON=\"$job_name_prefixes_json\" MAX_RUNNERS=\"$max_runners\" CLEANUP_ORDER=\"$cleanup_order\" ACTIVE_HEARTBEAT_MAX_AGE_MS=\"$active_heartbeat_max_age_ms\" AGE_BASED_CLEANUP_ENABLED=\"$age_based_cleanup_enabled\" AGE_BASED_MAX_AGE_HOURS=\"$age_based_max_age_hours\" FORCE_ACTIVE=\"$force_active\" FACTS_EXIT=\"$facts_exit\" TMP_DIR=\"$tmp_dir\" NAMESPACE=\"$namespace\" node <<'NODE' > \"$tmp_dir/plan.json\"",
|
||||
cleanupRunnersPlanNodeScript(),
|
||||
"NODE",
|
||||
"if [ " + shQuote(options.confirm && !options.dryRun ? "true" : "false") + " != true ]; then",
|
||||
@@ -4273,6 +4276,7 @@ const cleanupOrder = process.env.CLEANUP_ORDER || "";
|
||||
const activeHeartbeatMaxAgeMs = Number(process.env.ACTIVE_HEARTBEAT_MAX_AGE_MS || 0);
|
||||
const ageBasedCleanupEnabled = process.env.AGE_BASED_CLEANUP_ENABLED === "true";
|
||||
const ageBasedMaxAgeHours = process.env.AGE_BASED_MAX_AGE_HOURS ? Number(process.env.AGE_BASED_MAX_AGE_HOURS) : null;
|
||||
const forceActive = process.env.FORCE_ACTIVE === "true";
|
||||
const matchLabels = JSON.parse(process.env.MATCH_LABELS_JSON || "{}");
|
||||
const jobNamePrefixes = JSON.parse(process.env.JOB_NAME_PREFIXES_JSON || "[]");
|
||||
const now = Date.now();
|
||||
@@ -4457,8 +4461,15 @@ if (ageBasedCleanupEnabled && ageBasedMaxAgeHours !== null) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (forceActive) {
|
||||
for (const item of runnerJobs) {
|
||||
selectedByName.set(item.name, item);
|
||||
selectionReasons.set(item.name, item.protectedActive ? "force-active-runner-cleanup" : "force-runner-cleanup");
|
||||
}
|
||||
}
|
||||
|
||||
const selected = inactiveCandidates
|
||||
const selectionPool = forceActive ? runnerJobs : inactiveCandidates;
|
||||
const selected = selectionPool
|
||||
.filter((item) => selectedByName.has(item.name))
|
||||
.map((item) => ({ ...item, selectionReason: selectionReasons.get(item.name) || "selected" }));
|
||||
const matchedPodNames = new Set(runnerJobs.map((item) => item.name));
|
||||
@@ -4476,6 +4487,7 @@ console.log(JSON.stringify({
|
||||
maxRunners,
|
||||
cleanupOrder,
|
||||
activeHeartbeatMaxAgeMs,
|
||||
forceActive,
|
||||
selectors: { matchLabels, jobNamePrefixes },
|
||||
ageBasedCleanup: { enabled: ageBasedCleanupEnabled, maxAgeHours: ageBasedMaxAgeHours },
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user