From 1774b61cfe4c4454caf3629e966a44ae9c8f3344 Mon Sep 17 00:00:00 2001 From: Pierre Penninckx Date: Thu, 29 Aug 2024 00:12:45 -0700 Subject: [PATCH] Make backup cli tool correctly use secrets (#284) --- modules/blocks/restic.nix | 31 +++++++++++++++++++++------ modules/blocks/restic/docs/default.md | 4 ++++ test/blocks/restic.nix | 2 +- test/services/vaultwarden.nix | 2 +- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/modules/blocks/restic.nix b/modules/blocks/restic.nix index ab9dbce..5b0cbd2 100644 --- a/modules/blocks/restic.nix +++ b/modules/blocks/restic.nix @@ -123,6 +123,8 @@ let }; repoSlugName = name: builtins.replaceStrings ["/" ":"] ["_" "_"] (lib.strings.removePrefix "/" name); + backupName = name: repository: "${name}_${repoSlugName repository.path}"; + fullName = name: repository: "restic-backups-${name}_${repoSlugName repository.path}"; in { options.shb.restic = { @@ -221,7 +223,7 @@ in let mkRepositorySettings = name: instance: repository: let - serviceName = "restic-backups-${name}_${repoSlugName repository.path}"; + serviceName = fullName name repository; in { ${serviceName} = lib.mkMerge [ @@ -263,12 +265,29 @@ in lib.mkMerge (lib.flatten (lib.attrsets.mapAttrsToList mkSettings enabledInstances)); } { + system.activationScripts = let + mkEnv = name: instance: repository: + lib.nameValuePair "${fullName name repository}_gen" + (shblib.replaceSecrets { + userConfig = repository.secrets // { + RESTIC_PASSWORD_FILE = instance.passphraseFile; + RESTIC_REPOSITORY = repository.path; + }; + resultPath = "/run/secrets_restic_env/${fullName name repository}"; + generator = name: v: pkgs.writeText (fullName name repository) (lib.generators.toINIWithGlobalSection {} { globalSection = v; }); + user = instance.user; + }); + mkSettings = name: instance: builtins.map (mkEnv name instance) instance.repositories; + in + lib.listToAttrs (lib.flatten (lib.attrsets.mapAttrsToList mkSettings cfg.instances)); + environment.systemPackages = let - mkResticBinary = name: instance: repository: pkgs.writeShellScriptBin "restic-${name}_${repoSlugName repository.path}" '' - export RESTIC_PASSWORD_FILE=${instance.passphraseFile} - export RESTIC_REPOSITORY=${repository.path} - ${pkgs.restic}/bin/restic $@ - ''; + mkResticBinary = name: instance: repository: + pkgs.writeShellScriptBin (fullName name repository) '' + export $(grep -v '^#' "/run/secrets_restic_env/${fullName name repository}" \ + | xargs -d '\n') + ${pkgs.restic}/bin/restic $@ + ''; mkSettings = name: instance: builtins.map (mkResticBinary name instance) instance.repositories; in lib.flatten (lib.attrsets.mapAttrsToList mkSettings cfg.instances); diff --git a/modules/blocks/restic/docs/default.md b/modules/blocks/restic/docs/default.md index cad52b9..6fb9479 100644 --- a/modules/blocks/restic/docs/default.md +++ b/modules/blocks/restic/docs/default.md @@ -234,6 +234,10 @@ One can then restore a backup with: restic-myfolder1_srv_pool1_backups restore latest -t / ``` +### Troubleshooting {#blocks-restic-maintenance-troubleshooting} + +In case something bad happens with a backup, the [official documentation](https://restic.readthedocs.io/en/stable/077_troubleshooting.html) has a lot of tips. + ## Options Reference {#blocks-restic-options} ```{=include=} options diff --git a/test/blocks/restic.nix b/test/blocks/restic.nix index c9e6b8e..23c671e 100644 --- a/test/blocks/restic.nix +++ b/test/blocks/restic.nix @@ -20,7 +20,7 @@ let shb.restic.instances."testinstance" = { enable = true; - passphraseFile = pkgs.writeText "passphrase" "PassPhrase"; + passphraseFile = toString (pkgs.writeText "passphrase" "PassPhrase"); sourceDirectories = [ "/opt/files/A" diff --git a/test/services/vaultwarden.nix b/test/services/vaultwarden.nix index 8979b7f..9398b07 100644 --- a/test/services/vaultwarden.nix +++ b/test/services/vaultwarden.nix @@ -94,7 +94,7 @@ let ]; shb.restic.instances."testinstance" = config.shb.vaultwarden.backup // { enable = true; - passphraseFile = pkgs.writeText "passphrase" "PassPhrase"; + passphraseFile = toString (pkgs.writeText "passphrase" "PassPhrase"); repositories = [ { path = "/opt/repos/A";