#!/bin/bash # Forgejo Runner healthcheck — managed by Ansible (roles/forgejo_runner) # # Answers "is forgejo-runner healthy" and records it two ways: this log, and the # exit code. The exit code is the durable artefact — systemd keeps it, so # systemctl is-failed {{ healthcheck_service_name }}.service # answers the question with no monitoring system involved. # # Reporting is optional and generic: if a push URL is configured it also pings # it. Nothing here knows or cares which monitoring product is on the other end. LOG_FILE="{{ healthcheck_log_file }}" # Read from the environment rather than templated in, so the unit file is the # only place the token lives and the script is not secret. PUSH_URL="${HEALTHCHECK_PUSH_URL:-}" PUSH_TOKEN="${HEALTHCHECK_PUSH_TOKEN:-}" log_message() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" } # Gatus external endpoint: a POST with a bearer token and success=true|false. # # This used to report ONLY success - it exited before pushing when the runner # was down - so a failure was invisible until the heartbeat window expired. # Reporting the failure is the whole point of having a check. report() { local ok="$1" msg="$2" [ -n "$PUSH_URL" ] || return 0 curl -s --max-time 15 --retry 2 -o /dev/null -X POST \ -H "Authorization: Bearer ${PUSH_TOKEN}" \ "${PUSH_URL}?success=${ok}&error=${msg// /%20}" || true } main() { if ! systemctl is-active --quiet forgejo-runner; then log_message "ERROR: forgejo-runner is not active" report false "forgejo-runner is not active" exit 1 fi log_message "forgejo-runner is active" report true "active" exit 0 } main