I recently had an annoying experience where my PiFi accidentally reset to factory defaults, clearing out all my customizations (only to then realize that I didn’t have an updated backup).
So I decided to share a step-by-step guide for setting up an automatic daily backup for your PiFi. I decided to store my backups on my mounted cloud drive, but you can modify the guide below to backup anywhere, for example on a small USB thumb drive you keep plugged it for this purpose. Additionally, the script below will automatically ensure that only the 30 most recent backups are retained by deleting older files, to prevent clutter.
Backup Script Overview:
The script performs the following tasks:
- Ensures the backup destination exists.
- Reads the OpenWrt version from
/etc/openwrt_version
(to include that in the filename, to prevent restoring from incompatible versions if there’s a version upgrade) - Creates a backup file named with the hostname, current date, and OpenWrt version.
- Runs the backup.
- Checks the number of backup files and deletes the oldest ones if more than 30 are present.
The Backup Script Code:
#!/bin/sh
# Set the backup destination folder
BACKUP_DIR="/mnt/htpc/Backups/PiFi"
mkdir -p "$BACKUP_DIR"
# Retrieve the most recent previous backup file, if any
PREV_BACKUP=$(ls -1tr "${BACKUP_DIR}"/backup-* 2>/dev/null | tail -n 1)
if [ -n "$PREV_BACKUP" ]; then
echo "Previous backup file: $PREV_BACKUP"
else
echo "No previous backup file found."
fi
# Retrieve the OpenWrt version from /etc/openwrt_version if it exists
if [ -f /etc/openwrt_version ]; then
OPENWRT_VERSION=$(cat /etc/openwrt_version)
else
OPENWRT_VERSION="unknown"
fi
# Construct the backup file name: includes hostname, current date, time (hours and minutes), and OpenWrt version
BACKUP_FILE="${BACKUP_DIR}/backup-${HOSTNAME}-$(date +%F-%H%M)-${OPENWRT_VERSION}.tar.gz"
# Create the backup using sysupgrade in backup mode
sysupgrade -b "$BACKUP_FILE"
# If a previous backup exists and its name is different from the new backup file, compare MD5 hashes
if [ -n "$PREV_BACKUP" ] && [ "$PREV_BACKUP" != "$BACKUP_FILE" ]; then
NEW_HASH=$(md5sum "$BACKUP_FILE" | awk '{print $1}')
PREV_HASH=$(md5sum "$PREV_BACKUP" | awk '{print $1}')
if [ "$NEW_HASH" = "$PREV_HASH" ]; then
echo "New backup ($BACKUP_FILE) is identical to previous backup ($PREV_BACKUP). Removing duplicate."
rm -f "$BACKUP_FILE"
fi
fi
# Keep only the most recent 30 backup files (files starting with "backup-")
NUM_FILES=$(ls -1 "${BACKUP_DIR}"/backup-* 2>/dev/null | wc -l)
if [ "$NUM_FILES" -gt 30 ]; then
NUM_TO_DELETE=$(expr "$NUM_FILES" - 30)
ls -1tr "${BACKUP_DIR}"/backup-* 2>/dev/null | head -n "$NUM_TO_DELETE" | while read file; do
rm -f "$file"
done
fi
Explanation of the Script:
- Backup Directory Creation: The script sets the backup folder to
/mnt/htpc/Backups/PiFi
and ensures it exists by creating it if needed. You can replace that folder with whatever you want. - Retrieving OpenWrt Version: It reads the version from
/etc/openwrt_version
and defaults to “unknown” if the file isn’t found. - Constructing the Filename: The backup file is named using the device’s hostname, the current date (in YYYY-MM-DD format), and the OpenWrt version.
- Creating the Backup: The
sysupgrade -b
command is used to generate the backup. - Managing Backup Files: The script counts how many backup files exist. If there are more than 30, it deletes the oldest ones to maintain only the latest 30 backups. If a daily backup happens and it is identical to the previous day backup then the current backup will not be saved (to prevent redundant duplicate backups).
Setting Up the Script:
- Create the Script File:
Save the above script as/root/backup_openwrt.sh
using your favorite text editor (e.g., vi or nano). - Make the Script Executable:
Run the following command to give it executable permissions:
chmod +x /root/backup_openwrt.sh
- Test the Script:
Execute the script manually:
/root/backup_openwrt.sh
Verify that a backup file with a name like backup-[hostname]-YYYY-MM-DD-[version].tar.gz
appears in your backup folder.
Scheduling the Backup with Cron:
To run the backup daily, add a cron entry:
- In LuCI, go to System → Scheduled Tasks (or edit
/etc/crontabs/root
) withvi /etc/crontabs/root
) - Add the following line to schedule the script to run daily at 22:00 (10 PM):
0 22 * * * /root/backup_openwrt.sh
- Save the file and restart the cron service:
/etc/init.d/cron restart
I hope this is useful for others as well, happy backing up!
Update 1: Updated the script so consecutive duplicate backups will not be stored. So if nothing changed on a given day, no need to keep duplicate backups. It’ll only keep the backup if it is different than the previous one.