From f02407bfca65b343add090a2554b583bfdd6f415 Mon Sep 17 00:00:00 2001 From: Joseph Hanson Date: Sun, 9 Feb 2025 19:26:53 -0600 Subject: [PATCH] mkRestic modifications, will add mkBorg later and use that instead. --- nixos/modules/nixos/lib.nix | 209 ++++++++++++++++++------------------ 1 file changed, 107 insertions(+), 102 deletions(-) diff --git a/nixos/modules/nixos/lib.nix b/nixos/modules/nixos/lib.nix index 579be82..6cfd4a0 100644 --- a/nixos/modules/nixos/lib.nix +++ b/nixos/modules/nixos/lib.nix @@ -3,44 +3,43 @@ config, pkgs, ... -}: -{ - +}: { # container builder - lib.mySystem.mkContainer = - options: - ( - let - containerExtraOptions = - lib.optionals (lib.attrsets.attrByPath [ "caps" "privileged" ] false options) [ "--privileged" ] - ++ lib.optionals (lib.attrsets.attrByPath [ "caps" "readOnly" ] false options) [ "--read-only" ] - ++ lib.optionals (lib.attrsets.attrByPath [ "caps" "tmpfs" ] false options) ( - map (folders: "--tmpfs=${folders}") options.caps.tmpfsFolders - ) - ++ lib.optionals (lib.attrsets.attrByPath [ "caps" "noNewPrivileges" ] false options) [ - "--security-opt=no-new-privileges" - ] - ++ lib.optionals (lib.attrsets.attrByPath [ "caps" "dropAll" ] false options) [ "--cap-drop=ALL" ]; - in - { - ${options.app} = { - image = "${options.image}"; - user = "${options.user}:${options.group}"; - environment = { + lib.mySystem.mkContainer = options: ( + let + containerExtraOptions = + lib.optionals (lib.attrsets.attrByPath ["caps" "privileged"] false options) ["--privileged"] + ++ lib.optionals (lib.attrsets.attrByPath ["caps" "readOnly"] false options) ["--read-only"] + ++ lib.optionals (lib.attrsets.attrByPath ["caps" "tmpfs"] false options) ( + map (folders: "--tmpfs=${folders}") options.caps.tmpfsFolders + ) + ++ lib.optionals (lib.attrsets.attrByPath ["caps" "noNewPrivileges"] false options) [ + "--security-opt=no-new-privileges" + ] + ++ lib.optionals (lib.attrsets.attrByPath ["caps" "dropAll"] false options) ["--cap-drop=ALL"]; + in { + ${options.app} = { + image = "${options.image}"; + user = "${options.user}:${options.group}"; + environment = + { TZ = config.time.timeZone; - } // lib.attrsets.attrByPath [ "env" ] { } options; - dependsOn = lib.attrsets.attrByPath [ "dependsOn" ] [ ] options; - entrypoint = lib.attrsets.attrByPath [ "entrypoint" ] null options; - cmd = lib.attrsets.attrByPath [ "cmd" ] [ ] options; - environmentFiles = lib.attrsets.attrByPath [ "envFiles" ] [ ] options; - volumes = [ + } + // lib.attrsets.attrByPath ["env"] {} options; + dependsOn = lib.attrsets.attrByPath ["dependsOn"] [] options; + entrypoint = lib.attrsets.attrByPath ["entrypoint"] null options; + cmd = lib.attrsets.attrByPath ["cmd"] [] options; + environmentFiles = lib.attrsets.attrByPath ["envFiles"] [] options; + volumes = + [ "/etc/localtime:/etc/localtime:ro" - ] ++ lib.attrsets.attrByPath [ "volumes" ] [ ] options; - ports = lib.attrsets.attrByPath [ "ports" ] [ ] options; - extraOptions = containerExtraOptions; - }; - } - ); + ] + ++ lib.attrsets.attrByPath ["volumes"] [] options; + ports = lib.attrsets.attrByPath ["ports"] [] options; + extraOptions = containerExtraOptions; + }; + } + ); ## Creates a standardized restic backup configuration for both local and remote backups per app. # One S3 bucket per server. Each app has its own repository in the bucket. @@ -76,73 +75,79 @@ # This creates two backup jobs: # - nextcloud-local: backs up to local storage # - nextcloud-remote: backs up to remote storage (e.g. S3) - lib.mySystem.mkRestic = - options: - let - # excludePaths is optional - excludePaths = if builtins.hasAttr "excludePaths" options then options.excludePaths else [ ]; - # Decide which mutually exclusive options to use - remoteResticTemplateFile = - if builtins.hasAttr "remoteResticTemplateFile" options then - options.remoteResticTemplateFile - else - null; - remoteResticTemplate = - if builtins.hasAttr "remoteResticTemplate" options then options.remoteResticTemplate else null; - # 2:05 daily backup with 3h random delay - timerConfig = { - OnCalendar = "06:05"; # night snap is taken at 02:10 - Persistent = true; - RandomizedDelaySec = "30m"; - }; - # 7 daily, 5 weekly, 12 monthly backups - pruneOpts = [ - "--keep-daily 7" - "--keep-weekly 5" - ]; - # Initialize the repository if it doesn't exist - initialize = true; - # Only one backup is ever running at a time it's safe to say that we can remove stale locks - backupPrepareCommand = '' - # remove stale locks - this avoids some occasional annoyance - # - ${pkgs.restic}/bin/restic unlock --remove-all || true - ''; - in - { - # local backup - "${options.app}-local" = { - inherit - pruneOpts - timerConfig - initialize - backupPrepareCommand - ; - inherit (options) user passwordFile environmentFile; - # Move the path to the zfs snapshot path - paths = map (x: "${config.mySystem.services.zfs-nightly-snap.mountPath}/${x}") options.paths; - exclude = map ( + lib.mySystem.mkRestic = options: let + # excludePaths is optional + excludePaths = + if builtins.hasAttr "excludePaths" options + then options.excludePaths + else []; + # Decide which mutually exclusive options to use + remoteResticTemplateFile = + if builtins.hasAttr "remoteResticTemplateFile" options + then options.remoteResticTemplateFile + else null; + remoteResticTemplate = + if builtins.hasAttr "remoteResticTemplate" options + then options.remoteResticTemplate + else null; + # 2:05 daily backup with 3h random delay + timerConfig = null; + #{ + #OnCalendar = "00:20"; # night snap is taken at 02:10 + #Persistent = true; + #RandomizedDelaySec = "30m"; + #}; + # 7 daily, 5 weekly, 12 monthly backups + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + ]; + # Initialize the repository if it doesn't exist + initialize = true; + # Only one backup is ever running at a time it's safe to say that we can remove stale locks + backupPrepareCommand = '' + # remove stale locks - this avoids some occasional annoyance + # + ${pkgs.restic}/bin/restic unlock --remove-all || true + ''; + in { + # local backup + "${options.app}-local" = { + inherit + pruneOpts + timerConfig + initialize + backupPrepareCommand + ; + inherit (options) user passwordFile environmentFile; + # Move the path to the zfs snapshot path + paths = map (x: "${config.mySystem.services.zfs-nightly-snap.mountPath}/${x}") options.paths; + exclude = + map ( x: "${config.mySystem.services.zfs-nightly-snap.mountPath}/${x}" - ) options.excludePaths; - repository = "${options.localResticTemplate}"; - }; - - # remote backup - "${options.app}-remote" = { - inherit - pruneOpts - timerConfig - initialize - backupPrepareCommand - ; - inherit (options) user passwordFile environmentFile; - # Move the path to the zfs snapshot path - paths = map (x: "${config.mySystem.services.zfs-nightly-snap.mountPath}/${x}") options.paths; - repository = remoteResticTemplate; - repositoryFile = remoteResticTemplateFile; - exclude = map ( - x: "${config.mySystem.services.zfs-nightly-snap.mountPath}/${x}" - ) options.excludePaths; - }; + ) + options.excludePaths; + repository = "${options.localResticTemplate}"; }; + + # remote backup + "${options.app}-remote" = { + inherit + pruneOpts + timerConfig + initialize + backupPrepareCommand + ; + inherit (options) user passwordFile environmentFile; + # Move the path to the zfs snapshot path + paths = map (x: "${config.mySystem.services.zfs-nightly-snap.mountPath}/${x}") options.paths; + repository = remoteResticTemplate; + repositoryFile = remoteResticTemplateFile; + exclude = + map ( + x: "${config.mySystem.services.zfs-nightly-snap.mountPath}/${x}" + ) + options.excludePaths; + }; + }; }