From 50823a746ef6ccedcc2ca6195f79d856793e68c3 Mon Sep 17 00:00:00 2001 From: Simon Bruder Date: Thu, 22 Aug 2024 16:13:13 +0200 Subject: [PATCH] restic: Prepare for additional backups --- machines/fuuko/configuration.nix | 29 ++++++----- machines/fuuko/services/photoprism.nix | 2 +- machines/hiroshi/configuration.nix | 5 +- machines/hitagi/configuration.nix | 13 +++-- machines/koyomi/configuration.nix | 5 +- machines/mayushii/configuration.nix | 7 ++- machines/nunotaba/configuration.nix | 7 ++- machines/renge/configuration.nix | 5 +- machines/vueko/configuration.nix | 5 +- modules/restic/default.nix | 71 +++++++++++++++++++++++++- modules/restic/system.nix | 54 ++------------------ 11 files changed, 123 insertions(+), 80 deletions(-) diff --git a/machines/fuuko/configuration.nix b/machines/fuuko/configuration.nix index e3aa00d..2aee6b3 100644 --- a/machines/fuuko/configuration.nix +++ b/machines/fuuko/configuration.nix @@ -19,20 +19,23 @@ wireguard.home.enable = true; nginx.hardening.enable = true; printing.server.enable = true; - restic.system = { + restic = { enable = true; - qos = true; - extraPaths = [ - "/data" - ]; - extraExcludes = [ - "/data/cold/media/video" - "/data/cold/misc" - "/data/cold/torrent" - "/data/hot/torrent" - "/data/media/video" - "/data/torrent" - ]; + backups.system = { + enable = true; + qos = true; + extraPaths = [ + "/data" + ]; + extraExcludes = [ + "/data/cold/media/video" + "/data/cold/misc" + "/data/cold/torrent" + "/data/hot/torrent" + "/data/media/video" + "/data/torrent" + ]; + }; }; unfree.allowSoftware = true; }; diff --git a/machines/fuuko/services/photoprism.nix b/machines/fuuko/services/photoprism.nix index 0d77a28..0d175d1 100644 --- a/machines/fuuko/services/photoprism.nix +++ b/machines/fuuko/services/photoprism.nix @@ -13,7 +13,7 @@ }; }; - sbruder.restic.system.extraExcludes = [ + sbruder.restic.backups.system.extraExcludes = [ "/var/lib/private/photoprism" ]; diff --git a/machines/hiroshi/configuration.nix b/machines/hiroshi/configuration.nix index a1cecd8..02a9a52 100644 --- a/machines/hiroshi/configuration.nix +++ b/machines/hiroshi/configuration.nix @@ -12,7 +12,10 @@ sbruder = { full = false; - restic.system.enable = true; + restic = { + enable = true; + backups.system.enable = true; + }; wireguard.home.enable = true; infovhost.enable = true; nginx = { diff --git a/machines/hitagi/configuration.nix b/machines/hitagi/configuration.nix index 52903de..7938e81 100644 --- a/machines/hitagi/configuration.nix +++ b/machines/hitagi/configuration.nix @@ -19,12 +19,15 @@ gui.enable = true; media-proxy.enable = true; podman.enable = true; - restic.system = { + restic = { enable = true; - qos = true; - extraPaths = [ - "/data" - ]; + backups.system = { + enable = true; + qos = true; + extraPaths = [ + "/data" + ]; + }; }; unfree.allowSoftware = true; wireguard.home.enable = true; diff --git a/machines/koyomi/configuration.nix b/machines/koyomi/configuration.nix index a56d7be..1be0998 100644 --- a/machines/koyomi/configuration.nix +++ b/machines/koyomi/configuration.nix @@ -12,7 +12,10 @@ ]; sbruder = { - restic.system.enable = true; + restic = { + enable = true; + backups.system.enable = true; + }; wireguard.home.enable = true; podman.enable = true; }; diff --git a/machines/mayushii/configuration.nix b/machines/mayushii/configuration.nix index 225b3a8..e6d0a6b 100644 --- a/machines/mayushii/configuration.nix +++ b/machines/mayushii/configuration.nix @@ -19,9 +19,12 @@ gui.enable = true; media-proxy.enable = true; podman.enable = true; - restic.system = { + restic = { enable = true; - qos = true; + backups.system = { + enable = true; + qos = true; + }; }; unfree.allowSoftware = true; wireguard.home.enable = true; diff --git a/machines/nunotaba/configuration.nix b/machines/nunotaba/configuration.nix index ff5295b..6f5f88f 100644 --- a/machines/nunotaba/configuration.nix +++ b/machines/nunotaba/configuration.nix @@ -13,9 +13,12 @@ sbruder = { gui.enable = true; - restic.system = { + restic = { enable = true; - qos = true; + backups.system = { + enable = true; + qos = true; + }; }; unfree.allowSoftware = true; wireguard.home.enable = true; diff --git a/machines/renge/configuration.nix b/machines/renge/configuration.nix index a969ffe..581d790 100644 --- a/machines/renge/configuration.nix +++ b/machines/renge/configuration.nix @@ -27,9 +27,10 @@ sbruder = { nginx.hardening.enable = true; - restic.system = { + restic = { enable = true; - prune = true; + backups.system.enable = true; + prune.enable = true; }; wireguard.home.enable = true; infovhost.enable = true; diff --git a/machines/vueko/configuration.nix b/machines/vueko/configuration.nix index 9c30cd2..f1bb296 100644 --- a/machines/vueko/configuration.nix +++ b/machines/vueko/configuration.nix @@ -17,7 +17,10 @@ sbruder = { nginx.hardening.enable = true; - restic.system.enable = true; + restic = { + enable = true; + backups.system.enable = true; + }; wireguard.home.enable = true; full = false; infovhost.enable = true; diff --git a/modules/restic/default.nix b/modules/restic/default.nix index 4345245..0da377e 100644 --- a/modules/restic/default.nix +++ b/modules/restic/default.nix @@ -1,9 +1,78 @@ -# SPDX-FileCopyrightText: 2020-2021 Simon Bruder +# SPDX-FileCopyrightText: 2020-2024 Simon Bruder # # SPDX-License-Identifier: AGPL-3.0-or-later +{ config, lib, pkgs, ... }: +let + cfg = config.sbruder.restic; + + sftpTarget = "u313368-sub4@u313368-sub4.your-storagebox.de"; + sftpPort = 23; + repository = "sftp://${sftpTarget}:${toString sftpPort}/personal"; + + mkPruneConfig = { tag, timerConfig }: { + inherit repository timerConfig; + passwordFile = config.sops.secrets.restic-password.path; + paths = [ ]; + extraOptions = [ + "-o" + "sftp.command='ssh -i ${config.sops.secrets.restic-ssh-key.path} -p ${toString sftpPort} ${sftpTarget} -s sftp'" + ]; + pruneOpts = [ + "--compression auto" + "--keep-daily 7" + "--keep-monthly 12" + "--keep-weekly 5" + "--keep-yearly 10" + "--tag ${tag}" + "--verbose" + ]; + }; +in { imports = [ ./system.nix ]; + + options.sbruder.restic = { + enable = lib.mkEnableOption "restic"; + authScript.enable = (lib.mkEnableOption "script to use restic as user without dealing with authentication") // { + default = cfg.enable && config.sbruder.gui.enable; + }; + prune.enable = lib.mkEnableOption "pruning"; + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + { + sops.secrets = { + restic-password = { }; + restic-repository = { }; + }; + } + (lib.mkIf cfg.authScript.enable { + environment.systemPackages = [ + (pkgs.writeShellScriptBin "restic-auth" '' + ${pkgs.restic}/bin/restic \ + --password-command="pass data/backup/restic-nixos" \ + --repo "${repository}" \ + $@ + '') + ]; + }) + (lib.mkIf cfg.prune.enable { + sops.secrets.restic-ssh-key = { + sopsFile = ../../machines/${config.networking.hostName}/secrets.yaml; + }; + + services.restic.backups = { + system-prune = mkPruneConfig { + tag = "system"; + timerConfig = { + OnCalendar = "*-1/2-07 03:00:00"; + RandomizedDelaySec = "4h"; + }; + }; + }; + }) + ]); } diff --git a/modules/restic/system.nix b/modules/restic/system.nix index 82d2c99..5ce1a85 100644 --- a/modules/restic/system.nix +++ b/modules/restic/system.nix @@ -4,11 +4,8 @@ { pkgs, config, lib, ... }: let - cfg = config.sbruder.restic.system; + cfg = config.sbruder.restic.backups.system; - sftpTarget = "u313368-sub4@u313368-sub4.your-storagebox.de"; - sftpPort = 23; - repository = "sftp://${sftpTarget}:${toString sftpPort}/personal"; excludes = [ # Caches "/home/*/Downloads/" @@ -37,14 +34,6 @@ let ] ++ cfg.extraExcludes; excludesFile = pkgs.writeText "excludes.txt" (lib.concatStringsSep "\n" excludes); - # script to use restic as user without dealing with authentication - authScript = pkgs.writeShellScriptBin "restic-auth" '' - ${pkgs.restic}/bin/restic \ - --password-command="pass data/backup/restic-nixos" \ - --repo "${repository}" \ - $@ - ''; - # HACK: NixOS’ nftables implementation runs nft -c inside the build sandbox, # where the target host’s cgroups are not available, # and therefore fails. @@ -65,8 +54,8 @@ let ''; in { - options.sbruder.restic.system = { - enable = lib.mkEnableOption "restic"; + options.sbruder.restic.backups.system = { + enable = lib.mkEnableOption "restic system backup"; timerConfig = lib.mkOption { type = with lib.types; attrsOf str; default = { @@ -88,19 +77,9 @@ in default = null; }; qos = (lib.mkEnableOption "QoS marking (DSCP AF12) of outgoing packets") // { default = !(isNull cfg.uploadLimit); }; - prune = lib.mkEnableOption "pruning"; }; config = lib.mkIf cfg.enable { - sops.secrets = { - restic-password = { }; - restic-repository = { }; - } // lib.optionalAttrs cfg.prune { - restic-ssh-key = { - sopsFile = ../../machines/${config.networking.hostName}/secrets.yaml; - }; - }; - services.restic.backups.system = { inherit (cfg) timerConfig; repositoryFile = config.sops.secrets.restic-repository.path; @@ -134,32 +113,5 @@ in "IOSchedulingPriority" = 7; Slice = "restic.slice"; }; - - services.restic.backups.system-prune = lib.mkIf cfg.prune { - inherit repository; - passwordFile = config.sops.secrets.restic-password.path; - timerConfig = { - OnCalendar = "*-1/2-07 03:00:00"; - RandomizedDelaySec = "4h"; - }; - paths = [ ]; - extraOptions = [ - "-o" - "sftp.command='ssh -i ${config.sops.secrets.restic-ssh-key.path} -p ${toString sftpPort} ${sftpTarget} -s sftp'" - ]; - pruneOpts = [ - "--compression auto" - "--keep-daily 7" - "--keep-monthly 12" - "--keep-weekly 5" - "--keep-yearly 10" - "--tag system" - "--verbose" - ] ++ lib.optional (cfg.uploadLimit != null) "--limit-upload=${toString cfg.uploadLimit}"; - }; - - environment.systemPackages = [ - authScript - ]; }; }