diff options
-rwxr-xr-x | systemd-zfs-partition-backup.sh | 117 | ||||
-rw-r--r-- | systemd-zfs-partition-backup/AUR/PKGBUILD | 5 | ||||
-rwxr-xr-x | systemd-zfs-partition-backup/AUR/getsha256sum.sh | 21 |
3 files changed, 90 insertions, 53 deletions
diff --git a/systemd-zfs-partition-backup.sh b/systemd-zfs-partition-backup.sh index 91acdfc..e40c241 100755 --- a/systemd-zfs-partition-backup.sh +++ b/systemd-zfs-partition-backup.sh | |||
@@ -1,75 +1,90 @@ | |||
1 | #!/usr/bin/bash | 1 | #!/usr/bin/bash |
2 | logger "================================================================================" | 2 | # Written in 2020 by Max Christian Pohle <webmaster@coderonline.de> |
3 | 3 | ||
4 | # BACKUP_NAME=$ID_SERIAL-part$ID_PART_ENTRY_NUMBER | 4 | # check for a configuration file and source it in if its there |
5 | BACKUP_NAME=$(echo $1 | sed -e 's/\\x2d/-/g') | 5 | test -f /etc/default/systemd-zfs-partition-backup &&\ |
6 | MOUNT_TARGET=/media/$BACKUP_NAME | 6 | source /etc/default/systemd-zfs-partition-backup |
7 | |||
8 | DISK_NAME=$1 | ||
9 | DISK_NAME_ESCAPED=$(systemd-escape "$DISK_NAME") | ||
10 | |||
11 | logger "Disk: $DISK_NAME" | ||
12 | logger " : $DISK_NAME_ESCAPED (escaped)" | ||
13 | |||
14 | function beep() { | ||
15 | test -f /usr/bin/beep &&\ | ||
16 | env -u SUDO_GID -u SUDO_COMMAND -u SUDO_USER -u SUDO_UID /usr/bin/beep $@ | ||
17 | } | ||
7 | 18 | ||
8 | function fail() { | 19 | function fail() { |
9 | logger -s -t "$0" "Backup '$1' -> '$2' failed." | 20 | # logger -s -t "$0" "Backup '$1' -> '$2' failed." |
10 | sudo -u max beep -f 40 -l 500 | 21 | logger -s "$@" |
22 | beep -f 40 -l 500 | ||
11 | # sudo -u max beep -f 523 -l 150 -n -f 54 -l 600 | 23 | # sudo -u max beep -f 523 -l 150 -n -f 54 -l 600 |
12 | } | 24 | } |
13 | 25 | ||
14 | function start() { | 26 | function start() { |
15 | DEVNAME=$(echo $1 | sed 's/-/\\x2d/') | 27 | systemctl start media-$DISK_NAME_ESCAPED.automount ||\ |
16 | systemctl restart media-$DEVNAME.automount | 28 | (fail "could not start disk with service media-$DISK_NAME_ESCAPED.automount"; exit 1) |
17 | |||
18 | logger -t "$0" "Backup '$1' -> '$2' started." | ||
19 | sudo -u max beep -f 147 -l 120 -n -f 294 -l 200 -n -f 831 | ||
20 | } | 29 | } |
21 | 30 | ||
22 | function stop() { | 31 | function stop() { |
23 | DEVNAME=$(echo $1 | sed 's/-/\\x2d/') | 32 | systemctl stop media-$DISK_NAME_ESCAPED.automount ||\ |
24 | systemctl stop media-$DEVNAME.automount | 33 | (fail "could not stop disk with service media-$DISK_NAME_ESCAPED.automount"; exit 1) |
25 | |||
26 | logger -t "$0" "Backup '$1' -> '$2' finished." | ||
27 | sudo -u max beep -f 831 -l 120 -n -f 294 -l 200 -n -f 147 | ||
28 | } | 34 | } |
29 | 35 | ||
30 | function zfs_snapshot() { | ||
31 | zfs diff $LAST_SNAPSHOT > $ZFS_PATH/backup-differences.txt | ||
32 | zfs snap media-backup/$BACKUP_NAME@$(date +%Y-%m-%d--%H-%M) | ||
33 | echo "Here comes a list of changes since your last backup: $LAST_SNAPSHOT" | mailx -A typesafe -a $ZFS_PATH/backup-differences.txt -s 'Backup overview' max@entwicklerseite.de | ||
34 | } | ||
35 | 36 | ||
36 | start $1 | 37 | # iterate over all datasets |
38 | for i in $(zfs list -H -o name); | ||
39 | do | ||
40 | # compare the 'tail' of the PATH against the disk name... | ||
41 | if [ "$(basename $i)" == "$DISK_NAME" ]; then | ||
42 | start $DISK_NAME | ||
43 | |||
44 | DISK_MOUNTPOINT="/media/$DISK_NAME" | ||
45 | if ! findmnt $DISK_MOUNTPOINT; then | ||
46 | logger -s "Expected to find disk '$DISK_NAME' mounted under '$DISK_MOUNTPOINT'. But it is not there. Aborting backup." | ||
47 | beep -f 40 -l 500 | ||
48 | exit 1 | ||
49 | fi | ||
50 | |||
51 | DATASET=$i | ||
52 | DATASET_LAST_SNAPSHOT=$(zfs list -t snap -o name -s creation "$DATASET" | tail -n1) ||\ | ||
53 | (fail "we could not find a previous backup. Backup may still be possible (first time backup?)") | ||
54 | |||
55 | ZFS_MOUNTPOINT=$(zfs get mountpoint -H -o value "$DATASET") ||\ | ||
56 | (fail "could not determine mountpoint for dataset '$DATASET'"; exit 1) | ||
57 | |||
58 | # sanity check: is it really mounted? | ||
59 | findmnt -no source "$ZFS_MOUNTPOINT" ||\ | ||
60 | (fail "Dataset $DATASET is not mounted at $ZFS_MOUNTPOINT" ; exit 1) | ||
37 | 61 | ||
38 | if ! findmnt $MOUNT_TARGET; then | 62 | logger -s "Backup from '$DISK_MOUNTPOINT' -> '$ZFS_MOUNTPOINT' possible. Starting in 10 seconds..." |
39 | logger "$MOUNT_TARGET is not mounted. Cannot back it up." | ||
40 | exit 0 | ||
41 | fi | ||
42 | 63 | ||
43 | logger ">> Inspecting $BACKUP_NAME" | 64 | beep -f 147 -l 120 -n -f 294 -l 200 -n -f 831 |
44 | ZFS_PATH=$(zfs get mountpoint -H -o value media-backup/$BACKUP_NAME) || fail "$MOUNT_TARGET" "(no zfs dataset found)" | ||
45 | ZFS_MOUNTPATH=$(findmnt -no source $ZFS_PATH) || fail "$ZFS_PATH (not mounted)" "(no association)" | ||
46 | LAST_SNAPSHOT=$(zfs list -t snap -o name -s creation media-backup/$BACKUP_NAME | tail -n1) | ||
47 | 65 | ||
66 | set -x | ||
67 | rsync -ahoi -x --delete --info=all \ | ||
68 | "$DISK_MOUNTPOINT" "$ZFS_MOUNTPOINT" \ | ||
69 | 2>&1 | tee $ZFS_MOUNTPOINT/backup-report.txt | ||
70 | set +x | ||
48 | 71 | ||
49 | # Make sure, that we are really writing where a mountpoint is | 72 | zfs snap $DATASET@$(date +%Y-%m-%d--%H-%M-%S) ||\ |
50 | if [ "$ZFS_PATH" == "/$ZFS_MOUNTPATH" ]; then | 73 | (fail "Backup successful, but a snapshot of the dataset '$DATASET' was impossible :(") |
51 | sudo -u max beep -f 831 | ||
52 | logger "We can start $MOUNT_TARGET -> $ZFS_PATH" | ||
53 | rsync -ahoi -x --delete --info=all \ | ||
54 | "/media/$BACKUP_NAME/" \ | ||
55 | "$ZFS_PATH" \ | ||
56 | 2>&1 | tee $ZFS_PATH/backup-report.txt && zfs_snapshot | ||
57 | 74 | ||
58 | else | ||
59 | fail $ZFS_PATH $ZFS_MOUNTPATH | ||
60 | exit 1 | ||
61 | fi | ||
62 | 75 | ||
76 | if [ -n "$SYSTEMD_ZFS_PARTITION_BACKUP_DIFF_FILENAME" ]; then | ||
77 | zfs diff $DATASET_LAST_SNAPSHOT > $ZFS_MOUNTPOINT_VERIFIED/"$SYSTEMD_ZFS_PARTITION_BACKUP_DIFF_FILENAME" | ||
63 | 78 | ||
79 | if [ -n "$SYSTEMD_ZFS_PARTITION_BACKUP_EMAIL" ]; then | ||
80 | logger -s "Here comes a list of changes since your last backup: $LAST_SNAPSHOT" |\ | ||
81 | mailx -A typesafe -a $ZFS_MOUNTPOINT_VERIFIED/"$SYSTEMD_ZFS_PARTITION_BACKUP_DIFF_FILENAME" -s 'Backup overview' "$SYSTEMD_ZFS_PARTITION_BACKUP_EMAIL" | ||
82 | fi | ||
83 | fi | ||
64 | 84 | ||
65 | stop $1 | 85 | stop $DISK_NAME |
66 | 86 | ||
67 | # sleep a second so that /dev/disk/by-id/*-part become available | 87 | beep -f 831 -l 120 -n -f 294 -l 200 -n -f 147 |
68 | # sleep 1 | 88 | fi |
89 | done | ||
69 | 90 | ||
70 | # DISK=$(readlink -f /dev/disk/by-id/$ID_BUS-$ID_SERIAL) | ||
71 | # if ! [ -e "$DISK" ]; then | ||
72 | # fail | ||
73 | # logger "$DISK: Disk not there :(" | ||
74 | # exit 1 | ||
75 | # fi | ||
diff --git a/systemd-zfs-partition-backup/AUR/PKGBUILD b/systemd-zfs-partition-backup/AUR/PKGBUILD index f9d7315..918497f 100644 --- a/systemd-zfs-partition-backup/AUR/PKGBUILD +++ b/systemd-zfs-partition-backup/AUR/PKGBUILD | |||
@@ -12,8 +12,9 @@ depends=( | |||
12 | 'kbd' | 12 | 'kbd' |
13 | 'mkinitcpio' | 13 | 'mkinitcpio' |
14 | ) | 14 | ) |
15 | source=("http://git.entwicklerseite.de/zfs-bash-tools/snapshot/zfs-bash-tools-master.tar.bz2") | 15 | source=("http://git.entwicklerseite.de/zfs-bash-tools/snapshot/zfs-bash-tools-master.tar.gz") |
16 | sha256sums=('a734c145709687c5621f430d3baec3105977984dfbb35348beab4b793aeb8e1b') | 16 | sha256sums=('80c5a14dbbccc1f0164557cf2f4f31ab45c3b08aa577e60a54d198bac01ca91b') |
17 | echo "test" | ||
17 | 18 | ||
18 | package() { | 19 | package() { |
19 | install -D zfs-bash-tools-master/${pkgname}.sh ../pkg/${pkgname}/usr/bin/${pkgname}.sh | 20 | install -D zfs-bash-tools-master/${pkgname}.sh ../pkg/${pkgname}/usr/bin/${pkgname}.sh |
diff --git a/systemd-zfs-partition-backup/AUR/getsha256sum.sh b/systemd-zfs-partition-backup/AUR/getsha256sum.sh new file mode 100755 index 0000000..92760b3 --- /dev/null +++ b/systemd-zfs-partition-backup/AUR/getsha256sum.sh | |||
@@ -0,0 +1,21 @@ | |||
1 | #!/usr/bin/bash | ||
2 | # source PKGBUILD | ||
3 | # function allsha() { | ||
4 | # for i in $source | ||
5 | # do | ||
6 | # printf "'%s' " "$(wget -q -O- "$i" | sha256sum | awk '/-$/{ print $1 }')" | ||
7 | # done | ||
8 | # } | ||
9 | # | ||
10 | # allsha | tee /tmp/output.txt | ||
11 | |||
12 | |||
13 | ARCHIVE=$(mktemp --suffix=.tar.bz2) | ||
14 | |||
15 | cd $(git rev-parse --show-toplevel) | ||
16 | git archive -o "$ARCHIVE" master | ||
17 | cd - > /dev/null | ||
18 | |||
19 | cat $ARCHIVE | sha256sum | awk '/-$/{ print $1 }' | ||
20 | rm $ARCHIVE | ||
21 | |||