header image

Code Snippets

Backup libvirt Domains Using virtnbdbackup

| Last updated:
#!/usr/bin/env bash

# This script is used to backup libvirt domains using virtnbdbackup
# It is intended to be run as a cron job, e.g. 0 3 * * 1 /home/user/scripts/libvirt-backup >> /var/log/libvirt-backup.log 2>&1

virtnbdbackup_path=/home/user/virtnbdbackup/virtnbdbackup
backup_base_dir=/mnt/backups
remove_backups_older_than_months=3
domains_to_backup=(
  "domain-a"
  "domain-b"
)

failure_email_address=failure@example.com
gmail_email_address=user@example.com
gmail_password=gmailapppassword # Google app password, see https://support.google.com/accounts/answer/185833?hl=en

for domain in "${domains_to_backup[@]}"; do
  echo "[$(date +"%T")] Backing up $domain"

  backup_dir="$backup_base_dir/$domain/$(date +"%Y-%m")"
  echo "[$(date +"%T")] Creating backup directory $backup_dir"
  mkdir -p "$backup_dir"

  echo "[$(date +"%T")] Creating backup of $domain"
  if "$virtnbdbackup_path" -l auto -d "$domain" -o "$backup_dir" ; then
    echo "[$(date +"%T")] Backup of $domain completed successfully"
  else
    echo "[$(date +"%T")] Backup of $domain failed"
    failure_message_path=$(mktemp)
    echo -e "Subject: Backup of $domain failed\n\n[$(date +"%T")] Backup of $domain failed" > "$failure_message_path"
    curl --ssl-reqd \
      --url 'smtps://smtp.gmail.com:465' \
      --user "$gmail_email_address:$gmail_password" \
      --mail-from "$gmail_email_address" \
      --mail-rcpt "$failure_email_address" \
      --upload-file "$failure_message_path"
  fi

  echo "[$(date +"%T")] Removing backups older than $remove_backups_older_than_months months"
  old_backup_dir="${backup_base_dir:?}/${domain:?}/$(date --date="$remove_backups_older_than_months months ago" +%Y-%m)"
  echo "[$(date +"%T")] Removing $old_backup_dir is it exists"
  if [[ -d "$old_backup_dir" ]]; then
    rm -rf "$old_backup_dir"
  fi
done

echo "[$(date +"%T")] Backups completed"

Bash script to backup Libvirt domains using the wonderful virtnbdbackup backup tool.

Outline of Script

  • Creates full & incremental backups based on cron, archiving monthly
  • Removes old monthly backups after a set period
  • Send an email via Gmail on backup failure

The script can be used for local backups as part of a backup strategy. Complementing with a remote backup setup, such as using the tool restic, is recommended.

Steps

  • Install virtnbdbackup
  • Add script and make executable (chmod +x <path-to-script>)
  • Go through the script and update variables, e.g. domains_to_backup and failure_email_address
  • Set up crontab to run script periodically, crontab.guru can help with this, e.g.
  • Check logs to ensure the script runs correctly (tail -f /var/log/libvirt-backup.log)
0 3 * * 1 /home/user/scripts/libvirt-backup >> /var/log/libvirt-backup.log 2>&1

Notes

  • The gmail_password is stored in the script. If the script can be accessed by other users, you might want to edit the script to make it more secure