#!/bin/bash # notify-gitea.sh - Create Gitea issues for systemd service failures # # Usage: notify-gitea.sh # status: "success" or "failure" # Only creates an issue on failure; success is logged but ignored. # # Configuration: # Set these environment variables or create /etc/notify-gitea.conf: # GITEA_URL - Base URL of your Gitea instance (e.g., https://gitea.example.com) # GITEA_TOKEN - API token with repo write access # GITEA_OWNER - Repository owner (user or org) # GITEA_REPO - Repository name set -euo pipefail SERVICE_NAME="${1:-unknown}" STATUS="${2:-unknown}" HOSTNAME=$(hostname) TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S %Z') # Load config from file if not set if [[ -f /etc/notify-gitea.conf ]]; then source /etc/notify-gitea.conf fi # Validate required variables for var in GITEA_URL GITEA_TOKEN GITEA_OWNER GITEA_REPO; do if [[ -z "${!var:-}" ]]; then echo "Error: $var not set" >&2 exit 1 fi done # Only create issues on failure if [[ "$STATUS" == "success" ]]; then echo "Service ${SERVICE_NAME} succeeded - no issue created" exit 0 fi # Get recent logs for context (last 20 lines) # Try system journal first, fall back to user journal RECENT_LOGS=$(journalctl -u "$SERVICE_NAME" -n 20 --no-pager 2>/dev/null) if [[ -z "$RECENT_LOGS" || "$RECENT_LOGS" == *"-- No entries --"* ]]; then RECENT_LOGS=$(journalctl --user-unit "$SERVICE_NAME" -n 20 --no-pager 2>/dev/null || echo "No logs available") fi # Build issue title and body TITLE="[${HOSTNAME}] Service failure: ${SERVICE_NAME}" BODY="## Service Failure Report **Service:** \`${SERVICE_NAME}\` **Host:** \`${HOSTNAME}\` **Time:** ${TIMESTAMP} **Status:** ${STATUS} ## Recent Logs \`\`\` ${RECENT_LOGS} \`\`\` " # Create JSON payload using jq for proper escaping PAYLOAD=$(jq -n \ --arg title "$TITLE" \ --arg body "$BODY" \ '{title: $title, body: $body}') # Create the issue via Gitea API API_URL="${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/issues" RESPONSE=$(curl -s -w "\n%{http_code}" \ -X POST \ -H "Content-Type: application/json" \ -H "Authorization: token ${GITEA_TOKEN}" \ -d "$PAYLOAD" \ "$API_URL") HTTP_CODE=$(echo "$RESPONSE" | tail -1) BODY_RESPONSE=$(echo "$RESPONSE" | sed '$d') if [[ "$HTTP_CODE" -ge 200 && "$HTTP_CODE" -lt 300 ]]; then ISSUE_NUMBER=$(echo "$BODY_RESPONSE" | jq -r '.number // "unknown"') ISSUE_URL=$(echo "$BODY_RESPONSE" | jq -r '.html_url // "unknown"') echo "Issue #${ISSUE_NUMBER} created for ${SERVICE_NAME} failure" echo "URL: ${ISSUE_URL}" else echo "Error creating issue: HTTP ${HTTP_CODE}" >&2 echo "$BODY_RESPONSE" >&2 exit 1 fi