#!/bin/bash # Gitea Backup and Update Script with Notifications set -e # Configuration GITEA_HOME="/var/lib/gitea" GITEA_USER="git" GITEA_BIN="/usr/local/bin/gitea" BACKUP_DIR="/var/backups/gitea" LOG_FILE="/var/log/gitea-backup-update.log" TIMESTAMP=$(date +"%Y%m%d_%H%M%S") BACKUP_NAME="gitea_backup_${TIMESTAMP}" HOSTNAME=$(hostname) # Notification Settings # Email notifications ENABLE_EMAIL="false" EMAIL_FROM="noreply@example.com" EMAIL_TO="admin@example.com" # Discord webhook ENABLE_DISCORD="false" DISCORD_WEBHOOK_URL="https://discordapp.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN" # Slack webhook ENABLE_SLACK="false" SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Status tracking STATUS="RUNNING" STATUS_MESSAGE="" START_TIME=$(date +%s) # ------------------------------------------------------------ # Logging # ------------------------------------------------------------ log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # ------------------------------------------------------------ # Notifications # ------------------------------------------------------------ send_email() { local subject="$1" local body="$2" if [ "$ENABLE_EMAIL" != "true" ]; then return fi log "Sending email notification..." if command -v msmtp >/dev/null 2>&1; then { echo "To: $EMAIL_TO" echo "From: $EMAIL_FROM" echo "Subject: $subject" echo "" echo "$body" } | msmtp "$EMAIL_TO" log "${GREEN}Email sent successfully${NC}" return fi if command -v ssmtp >/dev/null 2>&1; then { echo "To: $EMAIL_TO" echo "From: $EMAIL_FROM" echo "Subject: $subject" echo "" echo "$body" } | ssmtp "$EMAIL_TO" log "${GREEN}Email sent successfully${NC}" return fi if command -v mail >/dev/null 2>&1; then echo "$body" | mail -s "$subject" "$EMAIL_TO" log "${GREEN}Email sent successfully${NC}" return fi log "${YELLOW}Warning: No mail client found${NC}" } send_discord() { if [ "$ENABLE_DISCORD" != "true" ] || [ -z "$DISCORD_WEBHOOK_URL" ]; then return fi local status_color local status_emoji case "$STATUS" in RUNNING) status_color="3447525" status_emoji="⏳" ;; SUCCESS) status_color="3066993" status_emoji="✅" ;; FAILED) status_color="15158332" status_emoji="❌" ;; esac local duration local duration_formatted duration=$(($(date +%s) - START_TIME)) duration_formatted="$((duration / 60))m $((duration % 60))s" local payload payload=$(cat </dev/null 2>&1 \ || log "${YELLOW}Warning: Discord notification failed${NC}" } send_slack() { if [ "$ENABLE_SLACK" != "true" ] || [ -z "$SLACK_WEBHOOK_URL" ]; then return fi local status_color local status_emoji case "$STATUS" in RUNNING) status_color="warning" status_emoji="⏳" ;; SUCCESS) status_color="good" status_emoji="✅" ;; FAILED) status_color="danger" status_emoji="❌" ;; esac local duration local duration_formatted duration=$(($(date +%s) - START_TIME)) duration_formatted="$((duration / 60))m $((duration % 60))s" local payload payload=$(cat </dev/null 2>&1 \ || log "${YELLOW}Warning: Slack notification failed${NC}" } send_notifications() { log "Sending notifications..." local subject local body subject="Gitea Backup & Update - $STATUS" body="Gitea Backup and Update Script Results Server: $HOSTNAME Status: $STATUS Duration: $(($(date +%s) - START_TIME)) seconds Timestamp: $(date +'%Y-%m-%d %H:%M:%S') Log File: $LOG_FILE Details: $STATUS_MESSAGE Backup Location: $BACKUP_DIR" send_email "$subject" "$body" send_discord send_slack } error_exit() { log "${RED}ERROR: $1${NC}" STATUS="FAILED" STATUS_MESSAGE="$1" send_notifications exit 1 } # ------------------------------------------------------------ # Initial checks # ------------------------------------------------------------ if [[ $EUID -ne 0 ]]; then STATUS="FAILED" STATUS_MESSAGE="This script must be run as root" echo "$STATUS_MESSAGE" exit 1 fi if [ ! -x "$GITEA_BIN" ]; then error_exit "Gitea binary not found or is not executable: $GITEA_BIN" fi if ! command -v curl >/dev/null 2>&1; then error_exit "curl is required but was not found" fi mkdir -p "$(dirname "$LOG_FILE")" log "${GREEN}=== Gitea Backup and Update Started ===${NC}" STATUS="RUNNING" send_discord # ------------------------------------------------------------ # Check installed and latest versions # ------------------------------------------------------------ log "Checking installed Gitea version..." INSTALLED_VERSION=$( "$GITEA_BIN" --version 2>/dev/null | grep -oE 'version [0-9]+\.[0-9]+\.[0-9]+' | awk '{print $2}' | head -n 1 ) if [ -z "$INSTALLED_VERSION" ]; then error_exit "Could not determine installed Gitea version" fi log "Checking latest Gitea release..." LATEST_VERSION=$( curl --fail --silent --show-error \ https://api.github.com/repos/go-gitea/gitea/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | head -n 1 ) if [ -z "$LATEST_VERSION" ]; then error_exit "Failed to fetch latest Gitea version" fi LATEST_VERSION_NUMBER="${LATEST_VERSION#v}" log "Installed version: $INSTALLED_VERSION" log "Latest version: $LATEST_VERSION_NUMBER" # Exit before stopping Gitea or creating a backup if already current if [ "$INSTALLED_VERSION" = "$LATEST_VERSION_NUMBER" ]; then STATUS="SUCCESS" STATUS_MESSAGE="Gitea is already up to date at version $INSTALLED_VERSION" log "${GREEN}$STATUS_MESSAGE${NC}" send_notifications exit 0 fi log "${YELLOW}Update available: $INSTALLED_VERSION -> $LATEST_VERSION_NUMBER${NC}" STATUS_MESSAGE="Update available: $INSTALLED_VERSION -> $LATEST_VERSION_NUMBER" send_discord # ------------------------------------------------------------ # Determine architecture # ------------------------------------------------------------ ARCH=$(uname -m) case "$ARCH" in x86_64) DOWNLOAD_ARCH="amd64" ;; aarch64) DOWNLOAD_ARCH="arm64" ;; armv7l) DOWNLOAD_ARCH="armv7" ;; *) error_exit "Unsupported architecture: $ARCH" ;; esac DOWNLOAD_URL="https://github.com/go-gitea/gitea/releases/download/${LATEST_VERSION}/gitea-${LATEST_VERSION_NUMBER}-linux-${DOWNLOAD_ARCH}" # ------------------------------------------------------------ # Stop Gitea # ------------------------------------------------------------ log "Stopping Gitea service..." systemctl stop gitea || error_exit "Failed to stop Gitea service" sleep 2 # ------------------------------------------------------------ # Create backup # ------------------------------------------------------------ log "Creating backup of Gitea data..." mkdir -p "$BACKUP_DIR/$BACKUP_NAME" cp -r "$GITEA_HOME" "$BACKUP_DIR/$BACKUP_NAME/gitea_home" || error_exit "Failed to backup Gitea home directory" cp "$GITEA_BIN" "$BACKUP_DIR/$BACKUP_NAME/gitea_bin_backup" || error_exit "Failed to backup Gitea binary" log "${GREEN}Backup created at: $BACKUP_DIR/$BACKUP_NAME${NC}" STATUS_MESSAGE="Backup created successfully" send_discord # ------------------------------------------------------------ # Compress backup # ------------------------------------------------------------ log "Compressing backup..." cd "$BACKUP_DIR" tar -czf "${BACKUP_NAME}.tar.gz" "$BACKUP_NAME" || error_exit "Failed to compress backup" rm -rf "$BACKUP_DIR/$BACKUP_NAME" log "${GREEN}Backup compressed: $BACKUP_DIR/${BACKUP_NAME}.tar.gz${NC}" # ------------------------------------------------------------ # Download and install Gitea # ------------------------------------------------------------ log "Downloading Gitea $LATEST_VERSION_NUMBER..." log "Download URL: $DOWNLOAD_URL" TMP_BINARY=$(mktemp /tmp/gitea_new.XXXXXX) curl --fail --location --silent --show-error \ --output "$TMP_BINARY" \ "$DOWNLOAD_URL" || { rm -f "$TMP_BINARY" error_exit "Failed to download Gitea" } if [ ! -s "$TMP_BINARY" ]; then rm -f "$TMP_BINARY" error_exit "Downloaded Gitea binary is empty" fi log "Installing new Gitea binary..." chmod 755 "$TMP_BINARY" chown "$GITEA_USER:$GITEA_USER" "$TMP_BINARY" mv "$TMP_BINARY" "$GITEA_BIN" || error_exit "Failed to install new Gitea binary" log "${GREEN}Gitea binary updated to $LATEST_VERSION_NUMBER${NC}" STATUS_MESSAGE="Gitea updated from $INSTALLED_VERSION to $LATEST_VERSION_NUMBER" send_discord # ------------------------------------------------------------ # Start and verify Gitea # ------------------------------------------------------------ log "Starting Gitea service..." systemctl start gitea || error_exit "Failed to start Gitea service" sleep 3 if systemctl is-active --quiet gitea; then log "${GREEN}Gitea service is running${NC}" else error_exit "Gitea service failed to start. Check the service logs." fi # ------------------------------------------------------------ # Clean up old backups # ------------------------------------------------------------ log "Cleaning up old backups; keeping the last five..." cd "$BACKUP_DIR" ls -t *.tar.gz 2>/dev/null | tail -n +6 | xargs -r rm -- log "${GREEN}Backup cleanup completed${NC}" # ------------------------------------------------------------ # Finish # ------------------------------------------------------------ log "${GREEN}=== Gitea Backup and Update Completed Successfully ===${NC}" STATUS="SUCCESS" STATUS_MESSAGE="Backup completed and Gitea updated from $INSTALLED_VERSION to $LATEST_VERSION_NUMBER successfully" send_notifications