Files
gitea-updater/gitea_update.sh
T

510 lines
12 KiB
Bash

#!/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="[email protected]"
EMAIL_TO="[email protected]"
# 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 <<EOF
{
"embeds": [{
"title": "$status_emoji Gitea Backup & Update - $STATUS",
"color": $status_color,
"fields": [
{
"name": "Server",
"value": "$HOSTNAME",
"inline": true
},
{
"name": "Duration",
"value": "$duration_formatted",
"inline": true
},
{
"name": "Timestamp",
"value": "$(date +'%Y-%m-%d %H:%M:%S')",
"inline": false
},
{
"name": "Status Message",
"value": "${STATUS_MESSAGE:-Operation completed}",
"inline": false
},
{
"name": "Backup Location",
"value": "$BACKUP_DIR",
"inline": false
}
],
"footer": {
"text": "Gitea Automation"
}
}]
}
EOF
)
curl --silent --show-error \
--request POST "$DISCORD_WEBHOOK_URL" \
--header "Content-Type: application/json" \
--data "$payload" \
>/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 <<EOF
{
"attachments": [{
"color": "$status_color",
"title": "$status_emoji Gitea Backup & Update - $STATUS",
"fields": [
{
"title": "Server",
"value": "$HOSTNAME",
"short": true
},
{
"title": "Duration",
"value": "$duration_formatted",
"short": true
},
{
"title": "Timestamp",
"value": "$(date +'%Y-%m-%d %H:%M:%S')",
"short": false
},
{
"title": "Status Message",
"value": "${STATUS_MESSAGE:-Operation completed}",
"short": false
},
{
"title": "Backup Location",
"value": "$BACKUP_DIR",
"short": false
}
]
}]
}
EOF
)
curl --silent --show-error \
--request POST "$SLACK_WEBHOOK_URL" \
--header "Content-Type: application/json" \
--data "$payload" \
>/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