-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackup_script.sh
More file actions
104 lines (88 loc) · 4.42 KB
/
Copy pathbackup_script.sh
File metadata and controls
104 lines (88 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/bin/bash
# List of hosts to back up, including the local device (e.g., rpi5-1.example.com).
# Example: Add your Raspberry Pi hostnames or IPs.
REMOTES=("pi1-hostname" "pi2-hostname" "pi3-ip-address"
# Folders to back up from each host (space-separated).
# Example: Add more paths like "/home/$USER/config/" if needed.
FOLDERS_TO_BACKUP="/home/$USER/docker/ /var/lib/docker/volumes/"
# Central backup destination root.
# Example: Change to "/mnt/external/backup" for an external drive.
BACKUP_ROOT="/home/$USER/backup"
# SSH private key for remote hosts.
# Example: Use "/home/$USER/.ssh/id_ed25519" if using Ed25519 key.
SSH_KEY="/home/$USER/.ssh/id_rsa"
# Webhook URL for alerts, using Signal CLI REST API by default.
# Example: "http://localhost:8080/v2/send" for local Signal API or "https://discord.com/api/webhooks/..." for Discord.
WEBHOOK_URL="https://your-webhook-url.com/alert"
# Webhook recipient details for Signal alerts.
# Example: Add more numbers like "[\"+27123456789\", \"+12345678901\"]".
WEBHOOK_NUMBER="+27123456789"
WEBHOOK_RECIPIENTS="[\"+27123456789\"]"
# Get the local hostname (e.g., "rpi5-1.example.com") to detect local device.
LOCAL_HOST=$(hostname -f)
# Function to back up a single host (local or remote).
backup_host() {
local host="$1"
local subfolder="$BACKUP_ROOT/$host"
# Create backup subfolder for this host (e.g., /home/$USER/backup/rpi5-1.example.com).
mkdir -p "$subfolder"
# Process each folder to back up.
for folder in $FOLDERS_TO_BACKUP; do
# Extract the last component of the folder path (e.g., "docker" or "volumes").
folder_name=$(basename "$folder")
# Check if the source folder exists on the host.
if [ "$host" = "$LOCAL_HOST" ]; then
# Local host: Use direct filesystem access.
# Use sudo for /var/lib/docker/volumes/ as it requires root access.
if [[ "$folder" == "/var/lib/docker/volumes/" ]]; then
sudo -n test -d "$folder" 2>/dev/null
else
test -d "$folder" 2>/dev/null
fi
else
# Remote host: Use SSH with sudo to check directory.
ssh -i "$SSH_KEY" your_user@"$host" "sudo -n test -d $folder" 2>/dev/null
fi
if [ $? -ne 0 ]; then
# If folder doesn't exist, send webhook alert and skip.
curl -X POST -H "Content-Type: application/json" \
-d "{\"message\": \"Backup skipped for $host: directory $folder does not exist at $(date)\", \"number\": \"$WEBHOOK_NUMBER\", \"recipients\": $WEBHOOK_RECIPIENTS}" \
"$WEBHOOK_URL"
echo "Skipping $host:$folder (directory does not exist)" >&2
continue
fi
# Perform rsync backup.
if [ "$host" = "$LOCAL_HOST" ]; then
# Local host: Direct rsync, with sudo for /var/lib/docker/volumes/.
if [[ "$folder" == "/var/lib/docker/volumes/" ]]; then
sudo -n rsync -avz -P "$folder" "$subfolder/$folder_name/" 2>&1
else
rsync -avz -P "$folder" "$subfolder/$folder_name/" 2>&1
fi
else
# Remote host: Rsync over SSH with sudo.
# -a: Preserve permissions/timestamps, -v: Verbose, -z: Compress, -P: Progress and partial transfers.
rsync -avz -P -e "ssh -i $SSH_KEY" --rsync-path="sudo -n rsync" your_user@"$host":"$folder" "$subfolder/$folder_name/" 2>&1
fi
if [ $? -ne 0 ]; then
# If rsync fails, send webhook alert and log error.
curl -X POST -H "Content-Type: application/json" \
-d "{\"message\": \"Backup failed for $host: rsync error on $folder at $(date)\", \"number\": \"$WEBHOOK_NUMBER\", \"recipients\": $WEBHOOK_RECIPIENTS}" \
"$WEBHOOK_URL"
echo "Error backing up $host:$folder" >&2
return 1
fi
# Create .last_backup file to track last successful backup time.
touch "$subfolder/$folder_name/.last_backup"
done
# Log success and send webhook alert.
echo "Backup completed for $host"
curl -X POST -H "Content-Type: application/json" \
-d "{\"message\": \"Backup completed for $host at $(date)\", \"number\": \"$WEBHOOK_NUMBER\", \"recipients\": $WEBHOOK_RECIPIENTS}" \
"$WEBHOOK_URL"
return 0
}
# Main loop: Back up all hosts in REMOTES array.
for host in "${REMOTES[@]}"; do
backup_host "$host"
done