Merge pull request #308829 from r-ryantm/auto-update/qlog
[NixPkgs.git] / nixos / tests / restic.nix
blob4111720cf6be85a6f7c079bdd822087222435a59
1 import ./make-test-python.nix (
2   { pkgs, ... }:
4   let
5     remoteRepository = "/root/restic-backup";
6     remoteFromFileRepository = "/root/restic-backup-from-file";
7     remoteNoInitRepository = "/root/restic-backup-no-init";
8     rcloneRepository = "rclone:local:/root/restic-rclone-backup";
10     backupPrepareCommand = ''
11       touch /root/backupPrepareCommand
12       test ! -e /root/backupCleanupCommand
13     '';
15     backupCleanupCommand = ''
16       rm /root/backupPrepareCommand
17       touch /root/backupCleanupCommand
18     '';
20     testDir = pkgs.stdenvNoCC.mkDerivation {
21       name = "test-files-to-backup";
22       unpackPhase = "true";
23       installPhase = ''
24         mkdir $out
25         echo some_file > $out/some_file
26         echo some_other_file > $out/some_other_file
27         mkdir $out/a_dir
28         echo a_file > $out/a_dir/a_file
29       '';
30     };
32     passwordFile = "${pkgs.writeText "password" "correcthorsebatterystaple"}";
33     paths = [ "/opt" ];
34     exclude = [ "/opt/excluded_file_*" ];
35     pruneOpts = [
36       "--keep-daily 2"
37       "--keep-weekly 1"
38       "--keep-monthly 1"
39       "--keep-yearly 99"
40     ];
41   in
42   {
43     name = "restic";
45     meta = with pkgs.lib.maintainers; {
46       maintainers = [ bbigras i077 ];
47     };
49     nodes = {
50       server =
51         { pkgs, ... }:
52         {
53           services.restic.backups = {
54             remotebackup = {
55               inherit passwordFile paths exclude pruneOpts backupPrepareCommand backupCleanupCommand;
56               repository = remoteRepository;
57               initialize = true;
58               timerConfig = null; # has no effect here, just checking that it doesn't break the service
59             };
60             remote-from-file-backup = {
61               inherit passwordFile exclude pruneOpts;
62               initialize = true;
63               repositoryFile = pkgs.writeText "repositoryFile" remoteFromFileRepository;
64               paths = [ "/opt/a_dir" ];
65               dynamicFilesFrom = ''
66                 find /opt -mindepth 1 -maxdepth 1 ! -name a_dir # all files in /opt except for a_dir
67               '';
68             };
69             remote-noinit-backup = {
70               inherit passwordFile exclude pruneOpts paths;
71               initialize = false;
72               repository = remoteNoInitRepository;
73             };
74             rclonebackup = {
75               inherit passwordFile paths exclude pruneOpts;
76               initialize = true;
77               repository = rcloneRepository;
78               rcloneConfig = {
79                 type = "local";
80                 one_file_system = true;
81               };
83               # This gets overridden by rcloneConfig.type
84               rcloneConfigFile = pkgs.writeText "rclone.conf" ''
85                 [local]
86                 type=ftp
87               '';
88             };
89             remoteprune = {
90               inherit passwordFile;
91               repository = remoteRepository;
92               pruneOpts = [ "--keep-last 1" ];
93             };
94             custompackage = {
95               inherit passwordFile paths;
96               repository = "some-fake-repository";
97               package = pkgs.writeShellScriptBin "restic" ''
98                 echo "$@" >> /root/fake-restic.log;
99               '';
101               pruneOpts = [ "--keep-last 1" ];
102               checkOpts = [ "--some-check-option" ];
103             };
104           };
106           environment.sessionVariables.RCLONE_CONFIG_LOCAL_TYPE = "local";
107         };
108     };
110     testScript = ''
111       server.start()
112       server.wait_for_unit("dbus.socket")
113       server.fail(
114           "restic-remotebackup snapshots",
115           'restic-remote-from-file-backup snapshots"',
116           "restic-rclonebackup snapshots",
117           "grep 'backup.* /opt' /root/fake-restic.log",
118       )
119       server.succeed(
120           # set up
121           "cp -rT ${testDir} /opt",
122           "touch /opt/excluded_file_1 /opt/excluded_file_2",
123           "mkdir -p /root/restic-rclone-backup",
124           "restic-remote-noinit-backup init",
126           # test that remotebackup runs custom commands and produces a snapshot
127           "timedatectl set-time '2016-12-13 13:45'",
128           "systemctl start restic-backups-remotebackup.service",
129           "rm /root/backupCleanupCommand",
130           'restic-remotebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 1"',
132           # test that restoring that snapshot produces the same directory
133           "mkdir /tmp/restore-1",
134           "restic-remotebackup restore latest -t /tmp/restore-1",
135           "diff -ru ${testDir} /tmp/restore-1/opt",
137           # test that remote-from-file-backup produces a snapshot
138           "systemctl start restic-backups-remote-from-file-backup.service",
139           'restic-remote-from-file-backup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 1"',
141           # test that remote-noinit-backup produces a snapshot
142           "systemctl start restic-backups-remote-noinit-backup.service",
143           'restic-remote-noinit-backup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 1"',
145           # test that restoring that snapshot produces the same directory
146           "mkdir /tmp/restore-2",
147           "${pkgs.restic}/bin/restic -r ${remoteRepository} -p ${passwordFile} restore latest -t /tmp/restore-2",
148           "diff -ru ${testDir} /tmp/restore-2/opt",
150           # test that rclonebackup produces a snapshot
151           "systemctl start restic-backups-rclonebackup.service",
152           'restic-rclonebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 1"',
154           # test that custompackage runs both `restic backup` and `restic check` with reasonable commandlines
155           "systemctl start restic-backups-custompackage.service",
156           "grep 'backup' /root/fake-restic.log",
157           "grep 'check.* --some-check-option' /root/fake-restic.log",
159           # test that we can create four snapshots in remotebackup and rclonebackup
160           "timedatectl set-time '2017-12-13 13:45'",
161           "systemctl start restic-backups-remotebackup.service",
162           "rm /root/backupCleanupCommand",
163           "systemctl start restic-backups-rclonebackup.service",
165           "timedatectl set-time '2018-12-13 13:45'",
166           "systemctl start restic-backups-remotebackup.service",
167           "rm /root/backupCleanupCommand",
168           "systemctl start restic-backups-rclonebackup.service",
170           "timedatectl set-time '2018-12-14 13:45'",
171           "systemctl start restic-backups-remotebackup.service",
172           "rm /root/backupCleanupCommand",
173           "systemctl start restic-backups-rclonebackup.service",
175           "timedatectl set-time '2018-12-15 13:45'",
176           "systemctl start restic-backups-remotebackup.service",
177           "rm /root/backupCleanupCommand",
178           "systemctl start restic-backups-rclonebackup.service",
180           "timedatectl set-time '2018-12-16 13:45'",
181           "systemctl start restic-backups-remotebackup.service",
182           "rm /root/backupCleanupCommand",
183           "systemctl start restic-backups-rclonebackup.service",
185           'restic-remotebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 4"',
186           'restic-rclonebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 4"',
188           # test that remoteprune brings us back to 1 snapshot in remotebackup
189           "systemctl start restic-backups-remoteprune.service",
190           'restic-remotebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 1"',
192       )
193     '';
194   }