Skip to content

Instantly share code, notes, and snippets.

@hktonylee
Last active October 14, 2021 08:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hktonylee/54ce16999a12d0e9ad390f58b04a729f to your computer and use it in GitHub Desktop.
Save hktonylee/54ce16999a12d0e9ad390f58b04a729f to your computer and use it in GitHub Desktop.
2-Phases Backup with Unison
# Unison preferences file (Fast backup)
root = /home/xxxx/your-folder
root = ssh://target.host/your-folder
auto = true
batch = true
prefer = newer
ignore = Name venv
ignore = Name node_modules
ignore = Name .DS_Store
# Fast backup is fast, usually takes seconds. But may miss some file
fastcheck = true
# Unison preferences file (Full backup)
include backup
# Full backup is slow, usually takes minutes. But must be correct
fastcheck=false
#!/usr/bin/env bash
fast_backup_name="${1:-backup}"
slow_backup_name=("${2:-backup_full}")
unison_args=("${@:3}")
fast_backup_interval=600 # 10 mins for fast backup
slow_backup_interval=86400 # 1 day for slow backup
next_backup_type='Fast'
get_time() {
date '+%s'
}
get_backup_name() {
local backup_type="${1:-$next_backup_type}"
if [[ "$backup_type" == 'Slow' ]]; then
echo "$slow_backup_name"
else
echo "$fast_backup_name"
fi
}
get_last_time_path() {
local backup_type="${1:-$next_backup_type}"
echo "$backup_path/.LastBackupTime.$backup_type.$host_name"
}
get_last_time() {
local last_time="$(
cat "$(get_last_time_path "$1")" 2>/dev/null \
| sed -n 2p
)"
[[ -z "$last_time" ]] && echo "0" || echo "$last_time"
}
backup_path=$(
cat ~/".unison/$(get_backup_name Fast).prf" \
| grep 'root = ' \
| head -1 \
| awk -F' = ' '{print $2}'
)
min_wait_time=0
host_name=$(hostname)
while true; do
now_time=$(get_time)
fast_used_time=$(( "$now_time" - "$(get_last_time Fast)" ))
fast_diff_time=$(( "$fast_backup_interval" - "$fast_used_time" ))
slow_used_time=$(( "$now_time" - "$(get_last_time Slow)" ))
slow_diff_time=$(( "$slow_backup_interval" - "$slow_used_time" ))
# Take smaller between fast_diff_time and slow_diff_time
diff_time=$(( "$fast_diff_time" < "$slow_diff_time" ? "$fast_diff_time" : "$slow_diff_time" ))
next_backup_type=$([[ "$fast_diff_time" -lt "$slow_diff_time" ]] && echo "Fast" || echo "Slow")
# At least 180 seconds until next backup
sleep_time=$(( "$diff_time" > "$min_wait_time" ? "$diff_time" : "$min_wait_time" ))
echo "Now sleep for $sleep_time seconds to run $next_backup_type backup type..."
sleep "$sleep_time"
yes '.' | tr -d '\n' | head -c $(tput cols)
start_time=$(get_time)
start_time_human=$(date '+%Y-%m-%d %H:%M:%S %Z %z')
echo "Date: $start_time_human"
echo "Type: $next_backup_type"
echo
old_time=$(cat "$(get_last_time_path)")
echo -e "$start_time_human\n$start_time" > "$(get_last_time_path)"
# The "meat"
unison "$(get_backup_name)" "${unison_args[@]}"
if [[ $? -ne 0 ]]; then
# Restore the time if backup failed
echo "$old_time" > "$(get_last_time_path)"
fi
now_time=$(get_time)
used_time=$(( "$now_time" - "$start_time" ))
echo
echo "Used $used_time seconds."
min_wait_time=180
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment