Initial commit

This commit is contained in:
nd 2021-03-12 03:35:14 +01:00
commit 420be44f56
No known key found for this signature in database
GPG key ID: 21B5CD4DEE3670E9
11 changed files with 432 additions and 0 deletions

6
templates/backup-all-vms.j2 Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
set -euo pipefail
for d in `virsh list --all --name`; do
backup-vm "$d"
done

15
templates/backup-cronjob.j2 Executable file
View file

@ -0,0 +1,15 @@
#!/bin/bash
set -euo pipefail
(
set -euo pipefail
flock -x -w 10 200 || exit 1
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
echo started backup cronjob
ionice -c 3 -p$$
nice -n 19 backup-full
echo finished backup cronjob
) 200>/var/lock/backup-cronjob.lock | logger -t "backup-cronjob"

13
templates/backup-full.j2 Executable file
View file

@ -0,0 +1,13 @@
#!/bin/bash
set -euo pipefail
{% if backup_executor %}
backup-standalone
{% endif %}
{% if backups.mode in ['hypervisor-restic'] %}
backup-all-vms
{% endif %}
{% if backup_executor %}
backup-retention
{% endif %}

19
templates/backup-retention.j2 Executable file
View file

@ -0,0 +1,19 @@
#!/bin/bash
set -euo pipefail
source /etc/backup-client/retention.env
{% if backup_backend == 'restic' %}
# restic backend
source /etc/backup-client/restic.env
restic forget \
--verbose \
--prune \
--group-by "host,paths,tags" \
--keep-hourly ${BACKUP_RETENTION_HOURS} \
--keep-daily ${BACKUP_RETENTION_DAYS} \
--keep-weekly ${BACKUP_RETENTION_WEEKS} \
--keep-monthly ${BACKUP_RETENTION_MONTHS} \
--keep-yearly ${BACKUP_RETENTION_YEARS}
{% endif %}

22
templates/backup-standalone.j2 Executable file
View file

@ -0,0 +1,22 @@
#!/bin/bash
set -euo pipefail
test -f "/etc/backup-client/enabled" || { echo "Standalone backup is disabled"; exit 0; }
{% if backup_backend == 'restic' %}
# restic backend
source /etc/backup-client/restic.env
restic backup \
--verbose \
--exclude-caches \
--one-file-system \
--exclude "${RESTIC_REPOSITORY}" \
--exclude-file "/etc/backup-client/exclude_files" \
--files-from "/etc/backup-client/include_files"
{% endif %}
{% if not backup_backend %}
echo "Noop, backup is handled external"
{% endif %}

95
templates/backup-vm.j2 Executable file
View file

@ -0,0 +1,95 @@
#!/bin/bash
set -euo pipefail
(
set -euo pipefail
flock -x -w 10 200 || exit 1
export LVM_SUPPRESS_FD_WARNINGS=1
DOMAIN=${1:?VM name musst be passed!}
DOMAIN_MOUNTBASE="/var/backup-client/vm-mountpoint"
function unfreeze_vm {
virsh resume "$DOMAIN" > /dev/null || true
}
function delete_snapshots {
cleanup_vmmount > /dev/null 2>&1
for i in $DISKS; do
extract_lvm
SNAPSHOT="/dev/$VG/backup-$DEVICE"
lvremove -f "$SNAPSHOT" > /dev/null 2>&1 || true
done
}
function cleanup_vmmount {
umount -l $DOMAIN_MOUNTBASE/* || true
rmdir ${DOMAIN_MOUNTBASE:?}/* || true
rm "$DOMAIN_MOUNTBASE/config.xml" || true
}
function extract_lvm {
DISK=`echo $i | awk -F, '{print $1}'`
DEVICE=`echo $i | awk -F, '{print $2}'`
VG=`lvs --noheadings -o vg_name "$DISK" | tr -d ' '`
LV=`lvs --noheadings -o lv_name "$DISK" | tr -d ' '`
}
function backup_vm {
# get a list of disks
DISKS=`virsh domblklist "$DOMAIN" --details \
| sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' \
| grep ^block \
| grep -v swap \
| awk '{printf "%s,%s ",$4, $3}'`
echo "backing up $DOMAIN: $DISKS"
trap "unfreeze_vm || true; delete_snapshots" INT TERM EXIT
# in case an earlier script crashed we have to clear snapshots
delete_snapshots
# freez vm
virsh suspend "$DOMAIN" > /dev/null || true
# create disk snapshots
for i in $DISKS; do
extract_lvm
lvcreate -L16G -s -n "backup-$DEVICE" "$DISK" > /dev/null
done
# dump vm config
virsh dumpxml "$DOMAIN" > "$DOMAIN_MOUNTBASE/config.xml"
unfreeze_vm
trap "delete_snapshots" INT TERM EXIT
# mount disks snapshots
for i in $DISKS; do
extract_lvm
SNAPSHOT="/dev/$VG/backup-$DEVICE"
fsck -y "$SNAPSHOT" > /dev/null 2> /dev/null
(
mkdir "$DOMAIN_MOUNTBASE/$DEVICE"
mount -o ro "$SNAPSHOT" "$DOMAIN_MOUNTBASE/$DEVICE"
) 2> /dev/null
done
{% if backup_backend == 'restic' %}
# restic backend
source /etc/backup-client/restic.env
restic backup \
--verbose \
--host "$DOMAIN" \
--exclude-file "/etc/backup-client/vms/$DOMAIN/exclude_files" \
"$DOMAIN_MOUNTBASE"
{% endif %}
# delete snapshot
delete_snapshots;
trap - INT TERM EXIT
}
test -f "/etc/backup-client/vms/$DOMAIN/enabled" && backup_vm || echo "Backup for $DOMAIN is disabled"
) 200>/var/lock/backup-vm.lock