Created
January 25, 2019 20:10
-
-
Save jedisct1/62f836ca4f140b79be19707e2dff781e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
cd /local/backups || exit 1 | |
export PATH=/usr/local/sbin:/usr/local/bin:$PATH | |
BACKUPDEST="$1" | |
DOMAIN="$2" | |
MAXBACKUPS="$3" | |
PASSWD="/* change this, obviously */" | |
if [ -z "$BACKUPDEST" -o -z "$DOMAIN" ]; then | |
echo "Usage: ./vm-backup <backup-folder> <domain> [max-backups]" | |
exit 1 | |
fi | |
if [ -z "$MAXBACKUPS" ]; then | |
MAXBACKUPS=5 | |
fi | |
BACKUPDOMAIN="$BACKUPDEST/$DOMAIN" | |
# | |
# Cleanup older backups. | |
# | |
echo "Cleaning older backups for $DOMAIN" | |
LIST=$(ls -r1 "$BACKUPDOMAIN" | grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}\.[0-9]+$') | |
i=1 | |
for b in $LIST; do | |
if [ $i -gt "$MAXBACKUPS" ]; then | |
echo "Removing old backup $BACKUPDOMAIN/$b" | |
rm -rf "$BACKUPDOMAIN/$b" | |
fi | |
i=$[$i+1] | |
done | |
# Generate the backup path | |
# | |
BACKUPDATE=`date "+%Y-%m-%d.%H%M%S"` | |
BACKUP="$BACKUPDOMAIN/$BACKUPDATE" | |
mkdir -p "$BACKUP" | |
echo "Beginning backup for $DOMAIN" | |
# | |
# Get the list of targets (disks) and the image paths. | |
# | |
TARGETS=$(virsh domblklist "$DOMAIN" --details | grep -e '^ *file' | grep -v 'cdrom' | grep -v 'floppy' | awk '{print $3}') | |
IMAGES=$(virsh domblklist "$DOMAIN" --details | grep -e '^ *file' | grep -v 'cdrom' | grep -v 'floppy' | awk '{print $4}') | |
# | |
# Create the snapshot. | |
# | |
DISKSPEC="" | |
for t in $TARGETS; do | |
DISKSPEC="$DISKSPEC --diskspec $t,snapshot=external" | |
done | |
virsh snapshot-create-as --domain "$DOMAIN" --name backup --no-metadata \ | |
--atomic --disk-only $DISKSPEC >/dev/null | |
if [ $? -ne 0 ]; then | |
echo "Failed to create snapshot for $DOMAIN" | |
exit 1 | |
fi | |
# | |
# Copy disk images | |
# | |
for t in $IMAGES; do | |
NAME=$(basename "$t") | |
nice ionice zstd -12 -v -c "$t" | nice encpipe -e -p "$PASSWD" -o "$BACKUP"/"$NAME".zst.encpipe | |
done | |
# | |
# Merge changes back. | |
# | |
BACKUPIMAGES=`virsh domblklist "$DOMAIN" --details | grep -e '^ *file' | awk '{print $4}'` | |
for t in $TARGETS; do | |
virsh blockcommit "$DOMAIN" "$t" --active --pivot >/dev/null | |
if [ $? -ne 0 ]; then | |
echo "Could not merge changes for disk $t of $DOMAIN. VM may be in invalid state." | |
exit 1 | |
fi | |
done | |
# | |
# Resume VM | |
# | |
virsh resume "$DOMAIN" 2> /dev/null | |
# | |
# Cleanup left over backup images. | |
# | |
for t in $BACKUPIMAGES; do | |
rm -f "$t" | |
done | |
# | |
# Dump the configuration information. | |
# | |
virsh dumpxml "$DOMAIN" >"$BACKUP/$DOMAIN.xml" | |
echo "Finished backup" | |
echo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment