Skip to content

Instantly share code, notes, and snippets.

@EmilMaric
Created July 22, 2024 05:15
Show Gist options
  • Save EmilMaric/3ac9d4281a100e8e7a88ed433e352f57 to your computer and use it in GitHub Desktop.
Save EmilMaric/3ac9d4281a100e8e7a88ed433e352f57 to your computer and use it in GitHub Desktop.
RPI Backup Generation & Rotation Script
#!/bin/bash
# When this script is run, it generates a new incremental RPI backup .img file
# using RonR's image-backup script, deletes the oldest .img file and renames the
# remaining .img file to to not contain the `latest` word in the file name. The
# idea is that by running this script consistently, there will always be two .img
# files:
# 1) The .img file generated on the last run.
# 2) The .img file generated on the run before the last run.
# When the script is run again, the .img file in step 2 is deleted (rotated out) and
# the one in step 1 is renamed, while a .img file is generated.
#
# This script also takes care of stopping and restarting all docker containers as it's
# not recommended to have docker running while image-backup is running. In fact, I've ran
# into issues when docker is running wherein I could not generate a backup image file due to
# various errors.
set -e
# NOTE: This is the one thing you'll need to change in the script to match your system
# setup.
# Directory containing the .img files.
backup_dir="/mnt/backupdisk"
# Function to restart Docker containers
restart_docker() {
echo "Restarting all Docker containers..."
docker restart $(docker ps -a -q)
}
# Assert there are two .img files in the directory
img_files=("$backup_dir"/*.img)
if [ "${#img_files[@]}" -ne 2 ]; then
echo "Error: There are not exactly two .img files in $backup_dir"
exit 1
fi
# Assert only one of the .img files has the word 'latest' in its name
latest_files=("$backup_dir"/*latest*.img)
if [ "${#latest_files[@]}" -ne 1 ]; then
echo "Error: There should be exactly one .img file with 'latest' in its name in $backup_dir"
exit 1
fi
# Delete the .img file that doesn't have the word 'latest' in it
echo "Deleting old backup image"
for file in "${img_files[@]}"; do
if [[ ! $file == *latest* ]]; then
rm "$file"
fi
done
# Make a copy of the .img file with the word 'latest' in it, but remove 'latest' from its name
echo "Duplicating latest backup image"
latest_file="${latest_files[0]}"
new_file="${latest_file//latest-/}"
cp "$latest_file" "$new_file"
# Rename the original .img file to be `rpi-backup-latest-$(today's date).img`
today=$(date +%Y-%m-%d)
new_name="$backup_dir/rpi-backup-latest-$today.img"
# Skip move if the source and target filenames are the same
if [ "$latest_file" != "$new_name" ]; then
mv "$latest_file" "$new_name"
else
echo "Source and target filenames are the same, skipping move operation."
fi
echo "Stop all running Docker containers"
docker stop $(docker ps -a -q)
# Trap to ensure Docker containers are restarted if they were stopped
trap 'restart_docker' EXIT
# Run the image-backup command with the new file name
sudo image-backup "$new_name"
# If the script reaches this point, remove the trap for EXIT
trap - EXIT
# Restart all Docker containers
restart_docker
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment