Initial commit
This commit is contained in:
commit
420be44f56
11 changed files with 432 additions and 0 deletions
6
templates/backup-all-vms.j2
Executable file
6
templates/backup-all-vms.j2
Executable 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
15
templates/backup-cronjob.j2
Executable 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
13
templates/backup-full.j2
Executable 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
19
templates/backup-retention.j2
Executable 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
22
templates/backup-standalone.j2
Executable 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
95
templates/backup-vm.j2
Executable 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue