105 lines
2.7 KiB
Bash
105 lines
2.7 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# 2026-05-05 ogt + Codex
|
|
# Find or stop stale Gitea/act job containers on the 110 host.
|
|
#
|
|
# Default is dry-run:
|
|
# bash scripts/ops/stop-stale-gitea-actions-jobs.sh
|
|
#
|
|
# Apply after reviewing candidates:
|
|
# bash scripts/ops/stop-stale-gitea-actions-jobs.sh --apply
|
|
#
|
|
# Safety rules:
|
|
# - Only touches Docker containers named GITEA-ACTIONS-*.
|
|
# - Defaults to containers older than 20 minutes.
|
|
# - Known long-running workflows get a higher stop threshold than the alert threshold.
|
|
# - Skips containers with recent log output unless --force is provided.
|
|
|
|
MIN_AGE_SECONDS=1200
|
|
APPLY=0
|
|
FORCE=0
|
|
|
|
threshold_for_name() {
|
|
local name="$1"
|
|
|
|
case "$name" in
|
|
*WORKFLOW-CD-Pipeline_JOB-deploy*)
|
|
# .gitea/workflows/cd.yaml deploy job timeout is 60m. Give act/Gitea
|
|
# cleanup a buffer before treating the container as abandoned.
|
|
echo 4500
|
|
;;
|
|
*WORKFLOW-CD-Pipeline_JOB-tests*|*WORKFLOW-CD-Pipeline_JOB-post-deploy-checks*)
|
|
echo 2400
|
|
;;
|
|
*WORKFLOW-Code-Review_JOB-ai-code-review*)
|
|
echo 720
|
|
;;
|
|
*WORKFLOW-Deploy-Alert-Rules_JOB-deploy-alerts*)
|
|
echo 900
|
|
;;
|
|
*)
|
|
echo "$MIN_AGE_SECONDS"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--apply)
|
|
APPLY=1
|
|
shift
|
|
;;
|
|
--force)
|
|
FORCE=1
|
|
shift
|
|
;;
|
|
--min-age-seconds)
|
|
MIN_AGE_SECONDS="${2:?--min-age-seconds requires a value}"
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "Unknown argument: $1" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
now="$(date +%s)"
|
|
found=0
|
|
|
|
while read -r name; do
|
|
[[ -n "$name" ]] || continue
|
|
started_raw="$(docker inspect "$name" --format '{{.State.StartedAt}}')"
|
|
started="$(date -u -d "$started_raw" +%s 2>/dev/null || echo 0)"
|
|
age=$((now - started))
|
|
stop_threshold="$(threshold_for_name "$name")"
|
|
[[ "$stop_threshold" -ge "$MIN_AGE_SECONDS" ]] || stop_threshold="$MIN_AGE_SECONDS"
|
|
[[ "$age" -ge "$stop_threshold" ]] || continue
|
|
|
|
found=1
|
|
log_tail="$(docker logs --since 5m --tail 5 "$name" 2>&1 || true)"
|
|
has_recent_logs=0
|
|
if [[ -n "$log_tail" ]]; then
|
|
has_recent_logs=1
|
|
fi
|
|
|
|
printf 'candidate name=%s age_seconds=%s stop_threshold_seconds=%s recent_logs=%s\n' \
|
|
"$name" "$age" "$stop_threshold" "$has_recent_logs"
|
|
if [[ "$has_recent_logs" == "1" ]]; then
|
|
printf '%s\n' "$log_tail" | sed 's/^/ log: /'
|
|
fi
|
|
|
|
if [[ "$APPLY" == "1" ]]; then
|
|
if [[ "$has_recent_logs" == "1" && "$FORCE" != "1" ]]; then
|
|
echo "skip $name: recent logs exist; use --force only after manual review"
|
|
continue
|
|
fi
|
|
docker stop "$name"
|
|
fi
|
|
done < <(docker ps --format '{{.Names}}' | grep '^GITEA-ACTIONS-' || true)
|
|
|
|
if [[ "$found" == "0" ]]; then
|
|
echo "No stale Gitea Actions containers older than policy threshold (minimum ${MIN_AGE_SECONDS}s)."
|
|
fi
|