Files
awoooi/ops/runner/audit-runner-pool.sh
2026-05-24 09:47:02 +08:00

222 lines
5.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Read-only Gitea act-runner pool inventory.
# Run on 110, or from a workstation:
# ssh 192.168.0.110 'bash -s' < ops/runner/audit-runner-pool.sh
RUNNER_SERVICE_NAME="${RUNNER_SERVICE_NAME:-gitea-act-runner-host.service}"
RUNNER_CONFIG_PATH="${RUNNER_CONFIG_PATH:-/home/wooo/act-runner/config.yaml}"
DOCKER_RUNNER_NAME="${DOCKER_RUNNER_NAME:-gitea-runner}"
JOURNAL_SINCE="${JOURNAL_SINCE:-2 hours ago}"
TASK_LOG_LINES="${TASK_LOG_LINES:-80}"
section() {
printf '\n== %s ==\n' "$1"
}
command_exists() {
command -v "$1" >/dev/null 2>&1
}
detect_systemd_scope() {
if systemctl --user show "$RUNNER_SERVICE_NAME" >/dev/null 2>&1; then
printf 'user'
return 0
fi
if systemctl show "$RUNNER_SERVICE_NAME" >/dev/null 2>&1; then
printf 'system'
return 0
fi
printf 'unknown'
}
print_service_status() {
local scope="$1"
section "runner service"
printf 'service=%s\n' "$RUNNER_SERVICE_NAME"
printf 'scope=%s\n' "$scope"
case "$scope" in
user)
systemctl --user show "$RUNNER_SERVICE_NAME" \
-p ActiveState -p SubState -p MainPID -p NRestarts \
-p ExecMainStartTimestamp --no-pager 2>/dev/null || true
;;
system)
systemctl show "$RUNNER_SERVICE_NAME" \
-p ActiveState -p SubState -p MainPID -p NRestarts \
-p ExecMainStartTimestamp --no-pager 2>/dev/null || true
;;
*)
printf 'status=unavailable\n'
;;
esac
}
extract_labels() {
local config_path="$1"
awk '
/^[[:space:]]*labels:[[:space:]]*$/ {
in_labels=1
next
}
in_labels && /^[[:space:]]*-[[:space:]]*/ {
line=$0
sub(/^[[:space:]]*-[[:space:]]*"/, "", line)
sub(/^[[:space:]]*-[[:space:]]*/, "", line)
sub(/"[[:space:]]*$/, "", line)
print line
next
}
in_labels && /^[^[:space:]]/ {
in_labels=0
}
' "$config_path"
}
print_config_inventory() {
section "runner config"
printf 'config_path=%s\n' "$RUNNER_CONFIG_PATH"
if [ ! -r "$RUNNER_CONFIG_PATH" ]; then
printf 'config_readable=false\n'
return 0
fi
awk '
/^runner:[[:space:]]*$/ {
in_runner=1
print
next
}
in_runner && /^[^[:space:]]/ && $0 !~ /^runner:[[:space:]]*$/ {
in_runner=0
}
in_runner && /^[[:space:]]*(capacity|timeout|shutdown_timeout):/ {
print
}
in_runner && /^[[:space:]]*labels:[[:space:]]*$/ {
print
}
in_runner && /^[[:space:]]*-[[:space:]]*/ {
print
}
' "$RUNNER_CONFIG_PATH"
section "runner label ownership"
local labels=()
while IFS= read -r label; do
[ -n "$label" ] && labels+=("$label")
done < <(extract_labels "$RUNNER_CONFIG_PATH")
if [ "${#labels[@]}" -eq 0 ]; then
printf 'labels_found=0\n'
return 0
fi
local foreign=()
local label_name owner
for label in "${labels[@]}"; do
label_name="${label%%:*}"
case "$label_name" in
ubuntu-latest|ubuntu-22.04|ubuntu-24.04|self-hosted|awoooi-*|awoooi)
owner="awoooi_or_shared_ci"
;;
*)
owner="foreign_or_cross_repo"
foreign+=("$label")
;;
esac
printf 'label=%s owner=%s\n' "$label" "$owner"
done
if [ "${#foreign[@]}" -gt 0 ]; then
printf 'foreign_labels=%s\n' "$(IFS=,; printf '%s' "${foreign[*]}")"
else
printf 'foreign_labels=none\n'
fi
}
print_docker_inventory() {
section "docker runner"
if ! command_exists docker; then
printf 'docker=unavailable\n'
return 0
fi
docker inspect "$DOCKER_RUNNER_NAME" \
--format 'name={{.Name}} Restart={{.HostConfig.RestartPolicy.Name}} Status={{.State.Status}} Running={{.State.Running}}' \
2>/dev/null || printf 'name=%s status=not_found\n' "$DOCKER_RUNNER_NAME"
section "active action containers"
local containers
containers="$(docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}' 2>/dev/null | awk '$1 ~ /^GITEA-ACTIONS-TASK-/ { print }' || true)"
if [ -n "$containers" ]; then
printf '%s\n' "$containers"
else
printf 'active_action_containers=none\n'
fi
}
collect_journal() {
local scope="$1"
case "$scope" in
user)
journalctl --user -u "$RUNNER_SERVICE_NAME" --since "$JOURNAL_SINCE" --no-pager 2>/dev/null || true
;;
system)
journalctl -u "$RUNNER_SERVICE_NAME" --since "$JOURNAL_SINCE" --no-pager 2>/dev/null || true
;;
*)
true
;;
esac
}
print_recent_tasks() {
local scope="$1"
local journal_output
journal_output="$(collect_journal "$scope")"
section "recent runner task lines"
printf 'journal_since=%s\n' "$JOURNAL_SINCE"
if [ -z "$journal_output" ]; then
printf 'task_log=unavailable_or_empty\n'
return 0
fi
printf '%s\n' "$journal_output" | grep -E 'wooo/[A-Za-z0-9_.-]+' | tail -n "$TASK_LOG_LINES" || true
section "recent repo counts"
local counts
counts="$(printf '%s\n' "$journal_output" | grep -Eo 'wooo/[A-Za-z0-9_.-]+' | sort | uniq -c | sort -nr || true)"
if [ -n "$counts" ]; then
printf '%s\n' "$counts"
else
printf 'repo_counts=none\n'
fi
}
main() {
local scope
scope="$(detect_systemd_scope)"
section "audit metadata"
printf 'host=%s\n' "$(hostname 2>/dev/null || printf unknown)"
printf 'user=%s\n' "$(id -un 2>/dev/null || printf unknown)"
printf 'timestamp=%s\n' "$(date -Is 2>/dev/null || date)"
printf 'read_only=true\n'
print_service_status "$scope"
print_config_inventory
print_docker_inventory
print_recent_tasks "$scope"
}
main "$@"