Skip to content

Instantly share code, notes, and snippets.

@xaverruss
Last active February 18, 2025 14:40
Show Gist options
  • Save xaverruss/fc2bee6afe9669e03974800119a972a7 to your computer and use it in GitHub Desktop.
Save xaverruss/fc2bee6afe9669e03974800119a972a7 to your computer and use it in GitHub Desktop.
Incus Backup Server, profile based, pulling
#!/bin/bash
# This script is used to backup all instances of a remote server to the local server
# It will create a profile on the remote server and filter for instances with the profile name
# It will then copy the instances to the local server in the project backup with the profile default
# And a name schema of remote-project-instance, e.g. Server1-project1-instance1
# The script is intended to be run on the backup server, as cronjob or manually
# The script utilizes the incus cli settings of the executing user, so make sure to have the correct remotes configured
# At the end of the file are some convenience scripts (add all instances to the backup profile)
# There are a few options to configure: the targeted remotes, the backup profile name and optional snapshot creation :: see below
# a simple list of remote servers, that have to be configured as remote in the current incus client ( eg. incus remote list)
remotes=( "Server1" "Server2" "Server3" )
# using all remotes configured in the incus-cli of the user, inclusing the local server
# usefull if the backup server is running a couple of instances on another disk / project
#remotes=($(incus remote list -c n -f csv | cut -d' ' -f1 | grep -v 'images'))
# Using all remotes configured in the incus-cli of the user except the local
# remotes=($(incus remote list -c n -f csv | cut -d' ' -f1 | grep -Ev 'images|local'))
# allows for a flexible backup target selection
# after the initial run of this script on a backup server, simply add the profile name to the instances you want to backup
#backupprofilename=backup
backupprofilename="backup-to-$(hostname)"
# END of configuration
for remote in "${remotes[@]}"
do
echo "Processing remote $remote"
projects=($(incus project list $remote: -c n -f csv | cut -d' ' -f1))
for project in "${projects[@]}"
do
echo "Processing project $project on remote $remote"
# Create profile inside project
incus profile create $remote:$backupprofilename --project $project > /dev/null 2>&1
# Filter for backup Profile
echo "Filter for backup Profile on: $remote"
instances=($(incus profile show $remote:$backupprofilename --project $project | grep instances | awk '{print $2}' | cut -d'/' -f4 | cut -d'?' -f1))
for instance in "${instances[@]}"
do
echo "Backup of remote: $remote project: $project instance: $instance to local machine in project backup with profile default"
incus copy $remote:$instance local:$remote-$project-$instance --project $project --target-project backup -p default --instance-only --refresh --stateless
done
done
done
# Added some convinience scripts
# this adds all instances that are currently listed by "incus ls" to the profile backup-to-HOSTNAME
# for instance in $(incus ls -c n -f csv); do incus profile add $instance backup-to-HOSTNAME ; done
# 0 * * * * bash /root/incus-backup.sh
@xaverruss
Copy link
Author

Background:
I wanted Proxmox for the backup server features ... and wanted incus for everything else.
So I wrote a backup script that would cover my needs.
"Tagged" based incremental backups pulled by the backup server.

It does add the profile to all accessible servers and projects, that could be a disliked side effect,
just delete the profile create command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment