From 9c9bec28a4d7eecf490d8c97c9ebba5a6376b666 Mon Sep 17 00:00:00 2001 From: Iurii Tatishchev Date: Sun, 23 Oct 2022 14:29:01 -0700 Subject: [PATCH] WIP: ZFS backup implementation --- roles/common/tasks/main.yml | 1 + roles/common/templates/zfs-send-daily | 13 +++++++++ roles/common/templates/zfsbackup/Dockerfile | 7 +++++ roles/common/templates/zfsbackup/cron.sh | 4 +++ .../common/templates/zfsbackup/run-backup.sh | 29 +++++++++++++++++++ 5 files changed, 54 insertions(+) create mode 100644 roles/common/templates/zfs-send-daily create mode 100644 roles/common/templates/zfsbackup/Dockerfile create mode 100755 roles/common/templates/zfsbackup/cron.sh create mode 100755 roles/common/templates/zfsbackup/run-backup.sh diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 13c323c..cbe40ed 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -16,6 +16,7 @@ - docker-fish-completion - docker-compose-fish-completion - zfs + - zfs-auto-snapshot state: latest update_cache: yes register: apk_installs diff --git a/roles/common/templates/zfs-send-daily b/roles/common/templates/zfs-send-daily new file mode 100644 index 0000000..d870a24 --- /dev/null +++ b/roles/common/templates/zfs-send-daily @@ -0,0 +1,13 @@ +#!/bin/sh + +destination_connection=ssh root@truenas.lab.home +destination_dataset=Mass-Storage-New/Backup + +# Wait for zfs-auto-snapshot +sleep 1 + +dataset="dock/volumes" + +latest_snap=$(zfs list -t snap -Hp -o name -S creation $dataset | head -1 | tr -d '\n') + +zfs send $latest_snap | $destination_connection zfs recv -o encry diff --git a/roles/common/templates/zfsbackup/Dockerfile b/roles/common/templates/zfsbackup/Dockerfile new file mode 100644 index 0000000..0da9459 --- /dev/null +++ b/roles/common/templates/zfsbackup/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.10-alpine +RUN \ + apk add openssh && \ + pip install zfs-autobackup && \ + ln -s /run-backup.sh /etc/periodic/daily/ +COPY ["cron.sh", "run-backup.sh", "/"] +CMD ["/cron.sh"] diff --git a/roles/common/templates/zfsbackup/cron.sh b/roles/common/templates/zfsbackup/cron.sh new file mode 100755 index 0000000..4dfa411 --- /dev/null +++ b/roles/common/templates/zfsbackup/cron.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -eu + +exec busybox crond -f -l 0 -L /dev/stdout diff --git a/roles/common/templates/zfsbackup/run-backup.sh b/roles/common/templates/zfsbackup/run-backup.sh new file mode 100755 index 0000000..e348d47 --- /dev/null +++ b/roles/common/templates/zfsbackup/run-backup.sh @@ -0,0 +1,29 @@ +#!/bin/sh +set -eu + +echo "running backup job" +date -Iminutes + +if [ ! -d ~/.ssh ]; then echo "error: $(realpath ~/.ssh) directory does not exist"; exit 1; fi + +host_ip=$(ip r | head -1 | cut -d' ' -f3 | tr -d '\n') +host=root@"$host_ip" +remote=root@truenas.lab.home + +if ! ssh -q "$host" exit; then echo "error: not able to ssh into host of container $host"; exit 1; fi +if ! ssh -q "$remote" exit; then echo "error: not able to ssh into backup remote $remote"; exit 1; fi + +hostname=$(ssh "$host" hostname | tr -d '\n') +remote_dataset=Mass-Storage-New/Backup/$hostname +zfs_prop_name="nas" # autobackup:nas = true + +zfs-autobackup \ +--snapshot-format "{}_%Y-%m-%d_%H-%M_%S" \ +--encrypt \ +--ssh-source "$host" \ +--ssh-target "$remote" \ +"$zfs_prop_name" \ +"$remote_dataset" + +echo "ran backup job" +date -Iminutes