fix: docker cleanup hangs silently on false-positive busy-wait match (#5051)

dockerSafeExec's busy-wait matched any process with "docker <letter>"
anywhere in its argv (e.g. Grafana's --packaging=docker cfg:...),
causing the wait loop to spin forever. Anchor the match to the actual
docker binary (argv[0]) instead, and add a MAX_WAIT ceiling so a
genuinely stuck docker process can't hang cleanup indefinitely either.

Also log failures in cleanupAll's catch instead of swallowing them,
since the scheduled cleanup path only goes through this function.

Fixes #5044
This commit is contained in:
Mauricio Siu
2026-08-11 20:40:24 -06:00
committed by GitHub
parent 3fbd67fe4d
commit 34c5b688ac
+18 -5
View File
@@ -153,19 +153,27 @@ export const getContainerByName = (name: string): Promise<ContainerInfo> => {
*/
export const dockerSafeExec = (exec: string) => `
CHECK_INTERVAL=10
MAX_WAIT=300
WAITED=0
echo "Preparing for execution..."
while true; do
PROCESSES=$(ps aux | grep -E "^.*docker [A-Za-z]" | grep -v grep)
PROCESSES=$(ps -eo args | awk '$1 ~ /(^|\\/)docker$/')
if [ -z "$PROCESSES" ]; then
echo "Docker is idle. Starting execution..."
break
else
echo "Docker is busy. Will check again in $CHECK_INTERVAL seconds..."
sleep $CHECK_INTERVAL
fi
if [ "$WAITED" -ge "$MAX_WAIT" ]; then
echo "Docker still busy after \${MAX_WAIT}s, proceeding anyway." >&2
break
fi
echo "Docker is busy. Will check again in $CHECK_INTERVAL seconds..."
sleep $CHECK_INTERVAL
WAITED=$((WAITED + CHECK_INTERVAL))
done
${exec}
@@ -323,7 +331,12 @@ export const cleanupAll = async (serverId?: string) => {
} else {
await execAsync(dockerSafeExec(command));
}
} catch {}
} catch (error) {
console.error(
`Docker cleanup: "${key}" failed${serverId ? ` on server ${serverId}` : ""}`,
error,
);
}
}
};