1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 { pkgs, ... }:
{
environment.systemPackages = [ (pkgs.writeShellScriptBin "backupToSSD" ''
set -euo pipefail
IFS=$'\n\t'
function repeatCharacter {
local count="$1";
local character="$2";
for (( i = 0; i < "$count"; ++i ))
do
echo -n "$character";
done
echo "";
}
function printEnd {
echo "";
}
function printStep {
repeatCharacter $(expr ''${#1} + 3) "#";
echo -e "$1";
repeatCharacter $(expr ''${#1} + 3) "#";
}
function checkRequirements {
# check if root
if [ "$USER" != "root" ]; then
echo "This script needs to be executed by root!";
exit;
fi
# check for disk
if [ ! -e /dev/disk/by-uuid/f5e319eb-a68b-4b21-9154-73404acb8bd1 ]; then
echo "Backup drive is not connected!";
exit;
fi
}
function mountDrive {
printStep "Mount backup-drive!"
mkdir -p /mnt/backup;
${pkgs.cryptsetup}/bin/cryptsetup luksOpen /dev/disk/by-uuid/f5e319eb-a68b-4b21-9154-73404acb8bd1 backup;
mount /dev/mapper/backup /mnt/backup;
printEnd;
}
function unmountDrive {
sync;
if grep -qs '/dev/mapper/backup ' /proc/mounts; then
printStep "Unmount backup-drive!";
umount /dev/mapper/backup;
${pkgs.cryptsetup}/bin/cryptsetup luksClose backup;
sync;
fi
echo "done!";
}
function copyResticRepos {
printStep "Copying /var/lib/restic to the backup-drive";
${pkgs.rsync}/bin/rsync -ah --partial --delete --info=progress2 /nix/persist/var/lib/restic/ /mnt/backup/restic-servers/;
sync;
printEnd;
}
function resticBackupFolder {
printStep "Backing up '$2' to the backup-drive";
mkdir -p /mnt/backup/restic-$HOSTNAME;
# check if password-file exists, if not create it
if [ ! -e /mnt/backup/restic-$HOSTNAME/$1.restic-passwd ]; then
echo -e "$(${pkgs.pwgen}/bin/pwgen -N1 -B 32)" > /mnt/backup/restic-$HOSTNAME/$1.restic-passwd;
sync;
fi
# check if restic repo is initialized, if not initialize it
if ! ${pkgs.restic}/bin/restic --cleanup-cache --password-file /mnt/backup/restic-$HOSTNAME/$1.restic-passwd --repo /mnt/backup/restic-$HOSTNAME/$1 snapshots &>/dev/null; then
${pkgs.restic}/bin/restic --quiet --cleanup-cache --password-file /mnt/backup/restic-$HOSTNAME/$1.restic-passwd --repo /mnt/backup/restic-$HOSTNAME/$1 \
init;
sync;
fi;
#do the backup
${pkgs.restic}/bin/restic --cleanup-cache --password-file /mnt/backup/restic-$HOSTNAME/$1.restic-passwd --repo /mnt/backup/restic-$HOSTNAME/$1 \
backup $2;
sync;
#cleanup
${pkgs.restic}/bin/restic --cleanup-cache --password-file /mnt/backup/restic-$HOSTNAME/$1.restic-passwd --repo /mnt/backup/restic-$HOSTNAME/$1 \
forget --keep-within-daily 14d --keep-within-weekly 2m --keep-within-monthly 2y --keep-within-yearly 99y;
${pkgs.restic}/bin/restic --cleanup-cache --password-file /mnt/backup/restic-$HOSTNAME/$1.restic-passwd --repo /mnt/backup/restic-$HOSTNAME/$1 \
prune;
sync;
printEnd;
}
trap unmountDrive EXIT;
checkRequirements;
mountDrive;
copyResticRepos;
#restic backups
resticBackupFolder audiobooks /nix/persist/home/katja/syncthing/Audiobooks;
resticBackupFolder bahn-richtlinien /nix/persist/home/katja/syncthing/Bahn-Richtlinien;
resticBackupFolder documents /nix/persist/home/katja/syncthing/Documents;
resticBackupFolder media-legacy /nix/persist/home/katja/syncthing/Media\ \(legacy\);
resticBackupFolder music /nix/persist/home/katja/syncthing/Music;
resticBackupFolder music-originals /nix/persist/home/katja/syncthing/Music\ \(Originals\);
resticBackupFolder pictures /nix/persist/home/katja/syncthing/Pictures;
resticBackupFolder videos /nix/persist/home/katja/syncthing/Videos;
resticBackupFolder wiki /nix/persist/home/katja/syncthing/Wiki;
'') ];
}