-
-
Save stvhay/0954febc5baf98068a5da51968f9a728 to your computer and use it in GitHub Desktop.
Automate your macOS backup to Backblaze B2 using Restic and launchd.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
log () { echo "$(date +"%Y-%m-%d %T") " "$@"; } | |
home_dir='' # FILL THIS OUT | |
name='remote' | |
restic_path='/opt/homebrew/bin' # ADJUST AS NEEDED | |
pid_file="${home_dir}/.restic/${name}.pid" | |
timestamp_file="${home_dir}/.restic/${name}.timestamp" | |
hc_ping="https://hc-ping.com/uuid_here" # REPLACE WITH YOUR UUID | |
backup_period="+3H" | |
local_wifi='' # FILL THIS OUT | |
# Configuration Variables | |
B2_ACCOUNT_ID=$(/usr/bin/security find-generic-password -s backup-restic-b2-accound-id -w) || { log "B2 Account ID retrieval failed"; exit 10; } | |
B2_ACCOUNT_KEY=$(/usr/bin/security find-generic-password -s backup-restic-b2-account-key -w) || { log "B2 Account Key retrieval failed"; exit 10; } | |
export B2_ACCOUNT_ID | |
export B2_ACCOUNT_KEY | |
export RESTIC_REPOSITORY='' # FILL THIS OUT | |
export RESTIC_PASSWORD_COMMAND='/usr/bin/security find-generic-password -s backup-restic-password-repository -w' | |
# Checks if a backup is already running. | |
backup_running () { | |
if [ -f "$pid_file" ]; then | |
if ps -p "$(cat $pid_file)" > /dev/null; then | |
log "File $pid_file exists and $(cat $pid_file) running. Backup is already in progress." | |
return 1 | |
else | |
log "File $pid_file exists but process " "$(cat $pid_file)" " not found. Removing PID file." | |
rm -f "$pid_file" | |
log "Removing restic lock..." | |
"${restic_path}/restic" --verbose unlock | |
fi | |
fi | |
} | |
# Checks if its too soon to take a backup. | |
time_too_soon () { | |
if [ -f "$timestamp_file" ]; then | |
time_run=$(cat "$timestamp_file") | |
current_time=$(date +"%s") | |
if [[ $current_time -lt $time_run ]]; then | |
return 1 | |
fi | |
fi | |
} | |
# Check if you are not on local wifi. | |
not_local_wifi () { | |
if [[ "$(/usr/sbin/networksetup -getairportnetwork en0 | grep -E "$local_wifi")" == "" ]]; then | |
log "Unsupported network." | |
return 1 | |
fi | |
} | |
# Check if power is not connected. | |
power_not_connected () { | |
if [[ $(pmset -g ps | head -1) =~ "Battery" ]]; then | |
log "Computer is not connected to the power source." | |
return 1 | |
fi | |
} | |
# Run the backup | |
run_backup () { | |
"${restic_path}/restic" cache --cleanup | |
"${restic_path}/restic" backup \ | |
--verbose \ | |
--files-from "${home_dir}/.restic/${name}.include" \ | |
--exclude-file "${home_dir}/.restic/${name}.exclude" | |
backup_success=$? | |
if [ $backup_success -ne 0 ]; then | |
log "Error running restic backup." | |
return 1 | |
fi | |
log "Backup success." | |
} | |
# Prune the backup database | |
prune_backup () { | |
${restic_path}/restic forget \ | |
--keep-daily 7 \ | |
--keep-weekly 5 \ | |
--keep-monthly 12 \ | |
--keep-yearly 10 \ | |
--prune | |
prune_success=$? | |
# Exit if pruning is a failure. | |
if [ $prune_success -ne 0 ]; then | |
log "Pruning failed." | |
return 1 | |
fi | |
log "Pruning finished." | |
} | |
# Perform Checks | |
backup_running || exit 0 | |
time_too_soon || exit 0 | |
not_local_wifi || exit 0 | |
power_not_connected || exit 0 | |
echo "$$" > "$pid_file" | |
# Run backup | |
log "Backup start" | |
run_backup || { rm -f "$pid_file"; log "Backup failed."; exit 5; } | |
# Update backup timestamp | |
date -v $backup_period +"%s" > "$timestamp_file" | |
log "Backup finished." | |
# Prune backup database | |
prune_backup || { rm -f "$pid_file"; log "Pruning failed."; exit 6; } | |
curl -fsS -m 10 --retry 5 "$hc_ping" > /dev/null | |
rm -f "$pid_file" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Edit the paths to point to the correct locations --> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" | |
"http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>Label</key> | |
<string>com.myself.backup_remote</string> | |
<key>Program</key> | |
<string>/Users/myself/.local/bin/backup_remote.sh</string> | |
<key>ProcessType</key> | |
<string>Background</string> | |
<key>StartInterval</key> | |
<integer>300</integer> | |
<key>WorkingDirectory</key> | |
<string>/Users/myself</string> | |
<key>EnvironmentVariables</key> | |
<dict> | |
<key>HOME</key> | |
<string>/Users/myself</string> | |
</dict> | |
<key>StandardOutPath</key> | |
<string>/Users/myself/Library/Logs/com.myself.backup_remote.out.log</string> | |
<key>StandardErrorPath</key> | |
<string>/Users/myself/Library/Logs/com.myself.backup_remote.error.log</string> | |
</dict> | |
</plist> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment