From edb707e3b5c9cf38ea3f3f30867bd316fac45aab Mon Sep 17 00:00:00 2001 From: Tom Sydney Kerckhove Date: Mon, 10 Jun 2024 16:45:06 +0200 Subject: [PATCH] borgbackup: Use RequiresMountsFor to require that the repo is mounted --- nixos/modules/services/backup/borgbackup.nix | 3 +++ nixos/tests/borgbackup.nix | 26 ++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/nixos/modules/services/backup/borgbackup.nix b/nixos/modules/services/backup/borgbackup.nix index a3c0715c9e60..abb7925e0935 100644 --- a/nixos/modules/services/backup/borgbackup.nix +++ b/nixos/modules/services/backup/borgbackup.nix @@ -104,6 +104,9 @@ let --what="sleep" \ --why="Scheduled backup" \ '' + backupScript; + unitConfig = optionalAttrs (isLocalPath cfg.repo) { + RequiresMountsFor = [ cfg.repo ]; + }; serviceConfig = { User = cfg.user; Group = cfg.group; diff --git a/nixos/tests/borgbackup.nix b/nixos/tests/borgbackup.nix index 4160e727f047..af7c12009c36 100644 --- a/nixos/tests/borgbackup.nix +++ b/nixos/tests/borgbackup.nix @@ -7,6 +7,8 @@ let keepFile = "important_file"; keepFileData = "important_data"; localRepo = "/root/back:up"; + # a repository on a file system which is not mounted automatically + localRepoMount = "/noAutoMount"; archiveName = "my_archive"; remoteRepo = "borg@server:."; # No need to specify path privateKey = pkgs.writeText "id_ed25519" '' @@ -42,6 +44,12 @@ in { nodes = { client = { ... }: { + virtualisation.fileSystems.${localRepoMount} = { + device = "tmpfs"; + fsType = "tmpfs"; + options = [ "noauto" ]; + }; + services.borgbackup.jobs = { local = { @@ -65,6 +73,13 @@ in { startAt = [ ]; # Do not run automatically }; + localMount = { + paths = dataDir; + repo = localRepoMount; + encryption.mode = "none"; + startAt = [ ]; + }; + remote = { paths = dataDir; repo = remoteRepo; @@ -178,6 +193,17 @@ in { "cat /mnt/borg/${dataDir}/${keepFile}" ) + with subtest("localMount"): + # the file system for the repo should not be already mounted + client.fail("mount | grep ${localRepoMount}") + # ensure trying to write to the mountpoint before the fs is mounted fails + client.succeed("chattr +i ${localRepoMount}") + borg = "borg" + client.systemctl("start --wait borgbackup-job-localMount") + client.fail("systemctl is-failed borgbackup-job-localMount") + # Make sure exactly one archive has been created + assert int(client.succeed("{} list '${localRepoMount}' | wc -l".format(borg))) > 0 + with subtest("remote"): borg = "BORG_RSH='ssh -oStrictHostKeyChecking=no -i /root/id_ed25519' borg" server.wait_for_unit("sshd.service")