Backups are important, regular ones doubly so. Unfortunately it's very easy to forget to make regular backups. Since Qubes stores the date and time when a VM was backed up, we will use this information to remind the user (probably you) when it has been more than N days since a backup.
We create a shell script that:
We use an "exclude file" to exclude some VMs which we don't backup, and therefore for which we should not check timestamps for.
Since we're probably running on a laptop, we run the script daily using anacron
instead of cron
, since anacron
will deal with situtions when the machine is frequently in "suspend" mode. (Which laptops are)
We set up an anacrontab for our user (as opposed to using a system-wide one) and run anacron
hourly using the user's crontab
. This gives some minor security benefits (by not running things as root) and reduces the chance of accidentally causing problems in the system through misconfiguration.
A plain text file containing the names of VMs which are not backed up. In this example, we save it in dom0, /home/${USER}/backup/exclude_vms.txt
:
fedora-30
whonix-gw-15
whonix-ws-15
(you'll need to change as needed depending on your backup policy)
Put this in dom0, probably in /home/${USER}/backup/remind.sh
:
#!/bin/bash
# Remind if this many days since backup
DAYS_THRESHOLD=3
# Setup variables
BACKUP_DIR="/home/${USER}/backup"
EXCLUDE_FILE=${BACKUP_DIR}/exclude_vms.txt
# Build backup VM list
ALL_VMS=(`/usr/bin/qvm-ls --raw-list`)
EXCLUDE_VMS=(`/usr/bin/cat $EXCLUDE_FILE`)
EXCLUDE_VMS+=("dom0")
BACKUP_VMS=()
for i in "${ALL_VMS[@]}"; do
skip=
for j in "${EXCLUDE_VMS[@]}"; do
[[ $i == $j ]] && { skip=1; break; }
done
[[ -n $skip ]] || BACKUP_VMS+=("$i")
done
# Get oldest known backup TS
TS=`/usr/bin/date +%s`
echo "TS now: $TS"
for vm in "${BACKUP_VMS[@]}"; do
vm_ts=`/usr/bin/qvm-prefs --get $vm backup_timestamp`
if [ "$vm_ts" -lt "$TS" ]; then
echo "New oldest TS: $vm_ts"
TS=$vm_ts
fi
done
# Get delta between current time and oldest backup
NOW=`/usr/bin/date +%s`
DELTA=`/usr/bin/expr $NOW - $TS`
DELTA_DAYS=`/usr/bin/expr $DELTA / 86400`
echo "delta in seconds: $DELTA / days: $DELTA_DAYS"
if [ "$DELTA_DAYS" -gt "$DAYS_THRESHOLD" ]; then
/usr/bin/notify-send --expire-time 86400000 "It has been $DELTA_DAYS days since last backup"
fi
echo `/usr/bin/date` >> $BACKUP_DIR/reminders.log
remind.sh (END)
Then mark it as executable with chmod +x /home/${USER}/backup/remind.sh
.
You can try running it right away to see how long it's been since your last backup.
Anacron should be installed by default in dom0, but you can check it by running (in dom0): dnf info cronie-anacron
and verifying the first line of the info is "Installed Packages".
First some basic configuration:
mkdir -p ~/.config
touch ~/.config/anacrontab
mkdir -p ~/.var/spool/anacron/
Now open up the file ${HOME}/.config/anacrontab
in your text editor of choice and add to it the following, replacing USERNAME_GOES_HERE with the dom0 user account name (to find it, echo ${USER}
:
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=USERNAME_GOES_HERE
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
@daily 0 backup-reminder /home/USERNAME_GOES_HERE/backup/remind.sh
Finally, add the following to your crontab file, accessed by running crontab -e
: (crontab -e
is the only way you should access your crontab)
@hourly /usr/sbin/anacron -t ${HOME}/.config/anacrontab -S ${HOME}/.var/spool/anacron