diff options
| author | Franck Cuny <franck@fcuny.net> | 2025-11-03 07:23:57 -0800 |
|---|---|---|
| committer | Franck Cuny <franck@fcuny.net> | 2025-11-03 07:23:57 -0800 |
| commit | 8eebaf8cee812bd07d8d890040e403bacb1777fb (patch) | |
| tree | 2991267489e3387e1c36a718a54b35fa2b695937 /modules/nixos/backups.nix | |
| parent | fix remote script (diff) | |
| download | infra-8eebaf8cee812bd07d8d890040e403bacb1777fb.tar.gz | |
consolidate all modules under modules/
Diffstat (limited to 'modules/nixos/backups.nix')
| -rw-r--r-- | modules/nixos/backups.nix | 210 |
1 files changed, 0 insertions, 210 deletions
diff --git a/modules/nixos/backups.nix b/modules/nixos/backups.nix deleted file mode 100644 index 78b3144..0000000 --- a/modules/nixos/backups.nix +++ /dev/null @@ -1,210 +0,0 @@ -# Some examples for how to use this module -# -# Host with media files - backup /media only locally -# my.modules.backups = { -# enable = true; -# passwordFile = config.age.secrets.restic_password.path -# local.paths = [ "/media" "/home" "/var/lib/important" ]; -# remote.paths = [ "/home" "/var/lib/important" ]; # Excludes /media -# }; -# -# Another example - different exclusions for local vs remote -# my.modules.backups = { -# enable = true; -# passwordFile = config.age.secrets.restic_password.path -# local.paths = [ "/home" "/var/cache/downloads" ]; -# local.exclude = [ "*.tmp" ]; -# remote.paths = [ "/home" ]; # Skip cache directory for remote -# remote.exclude = [ "*.tmp" "*.log" ]; # More aggressive exclusions for remote -# }; -{ - pkgs, - config, - lib, - ... -}: -let - cfg = config.my.modules.backups; - - # Helper scripts for easy backup access - restic-local = pkgs.writeShellScriptBin "restic-local" '' - export RESTIC_REPOSITORY="${cfg.localBasePath}/${config.networking.hostName}" - export RESTIC_PASSWORD_FILE="${cfg.passwordFile}" - exec ${pkgs.restic}/bin/restic "$@" - ''; - - restic-remote = pkgs.writeShellScriptBin "restic-remote" '' - export RESTIC_REPOSITORY="${cfg.remoteBaseRepository}:/${config.networking.hostName}/" - export RESTIC_PASSWORD_FILE="${cfg.passwordFile}" - ${lib.optionalString (cfg.remote.environmentFile != null) '' - source ${cfg.remote.environmentFile} - ''} - exec ${pkgs.restic}/bin/restic "$@" - ''; - - # Common backup options shared between local and remote - backupOptions = { - paths = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - description = "Paths to backup"; - example = [ - "/home" - "/var/lib/important-data" - ]; - }; - - exclude = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - description = "Paths to exclude from backup"; - example = [ - "*.tmp" - "/var/cache" - ]; - }; - - extraBackupArgs = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ - "--exclude-caches" - "--compression=max" - ]; - description = "Additional arguments to pass to restic backup"; - }; - - pruneOpts = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ - "--keep-daily 7" - "--keep-weekly 4" - "--keep-monthly 3" - ]; - description = "Pruning options for old backups"; - }; - - timerConfig = lib.mkOption { - type = lib.types.attrs; - default = { - OnCalendar = "daily"; - RandomizedDelaySec = "5m"; - }; - description = "Systemd timer configuration"; - }; - }; -in -{ - options.my.modules.backups = { - enable = lib.mkEnableOption "backups"; - - passwordFile = lib.mkOption { - type = lib.types.str; - default = config.age.secrets.restic_password.path; - description = "Path to file containing restic repository password"; - example = "/run/secrets/restic-password"; - }; - - localBasePath = lib.mkOption { - type = lib.types.str; - default = "/data/backups"; - description = "Base path for local backup repositories"; - example = "/mnt/backup-drive/backups"; - }; - - remoteBaseRepository = lib.mkOption { - type = lib.types.str; - default = "gs:fcuny-infra-backups"; - description = "Base repository URL for remote backups"; - example = "s3:my-backup-bucket"; - }; - - local = backupOptions; - - remote = backupOptions // { - timerConfig = lib.mkOption { - type = lib.types.attrs; - default = { - OnCalendar = "daily"; - # No randomized delay for remote to avoid overlap with local - }; - description = "Systemd timer configuration for remote backups"; - }; - - googleProjectId = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = "fcuny-infra"; - description = "Google Cloud project ID for GCS backups"; - example = "my-backup-project"; - }; - - googleCredentialsFile = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = config.age.secrets.restic_gcs_credentials.path; - description = "Path to Google Cloud service account credentials file"; - example = "/run/secrets/gcs-credentials"; - }; - - environmentFile = lib.mkOption { - type = lib.types.nullOr lib.types.path; - default = - if cfg.remote.googleProjectId != null && cfg.remote.googleCredentialsFile != null then - pkgs.writeText "restic-gcs-env" '' - GOOGLE_PROJECT_ID=${cfg.remote.googleProjectId} - GOOGLE_APPLICATION_CREDENTIALS=${cfg.remote.googleCredentialsFile} - '' - else - null; - description = "Environment file for remote backup authentication"; - }; - }; - - helpers = lib.mkOption { - type = lib.types.bool; - default = true; - description = "Install helper scripts (restic-local, restic-remote)"; - }; - }; - - config = lib.mkIf cfg.enable { - environment.systemPackages = [ - pkgs.restic - ] - ++ lib.optionals cfg.helpers [ - restic-local - restic-remote - ]; - - services.restic.backups = lib.mkMerge [ - # Local backup configuration - only if paths are specified - (lib.mkIf (cfg.local.paths != [ ]) { - local = { - initialize = true; - repository = "${cfg.localBasePath}/${config.networking.hostName}"; - passwordFile = cfg.passwordFile; - paths = cfg.local.paths; - exclude = cfg.local.exclude; - extraBackupArgs = cfg.local.extraBackupArgs; - timerConfig = cfg.local.timerConfig; - pruneOpts = cfg.local.pruneOpts; - }; - }) - - # Remote backup configuration - only if paths are specified - (lib.mkIf (cfg.remote.paths != [ ]) { - remote = { - initialize = true; - repository = "${cfg.remoteBaseRepository}:/${config.networking.hostName}/"; - passwordFile = cfg.passwordFile; - paths = cfg.remote.paths; - exclude = cfg.remote.exclude; - extraBackupArgs = cfg.remote.extraBackupArgs; - timerConfig = cfg.remote.timerConfig; - pruneOpts = cfg.remote.pruneOpts; - } - // lib.optionalAttrs (cfg.remote.environmentFile != null) { - environmentFile = toString cfg.remote.environmentFile; - }; - }) - ]; - }; -} |
