#!/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 "$@"