diff options
Diffstat (limited to 'modules/backup/repositories.nix')
| -rw-r--r-- | modules/backup/repositories.nix | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/modules/backup/repositories.nix b/modules/backup/repositories.nix new file mode 100644 index 0000000..9ee2b3e --- /dev/null +++ b/modules/backup/repositories.nix @@ -0,0 +1,144 @@ +{ + pkgs, + lib, + config, + mkInstanceServices, + ... +}: +let + s3RepositoryType = lib.types.submodule { + options = { + bucket = lib.mkOption { + type = lib.types.str; + default = "default-bucket-value"; + description = "Bucket name for S3 repository."; + }; + region = lib.mkOption { + type = lib.types.str; + default = "eu-central-003"; + description = "Region for S3 repository."; + }; + endpoint = lib.mkOption { + type = lib.types.str; + default = "https://s3.eu-central-003.backblazeb2.com"; + description = "Endpoint for S3 repository."; + }; + disableTLS = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Disable TLS for S3 repository."; + }; + }; + }; + + b2RepositoryType = lib.types.submodule { + options = { + bucket = lib.mkOption { + type = lib.types.str; + default = "default-bucket-value"; + description = "Bucket name for S3 repository."; + }; + }; + }; + + instanceType = lib.types.submodule { + options = { + repository = lib.mkOption { + type = lib.types.attrTag { + s3 = lib.mkOption { + type = s3RepositoryType; + }; + b2 = lib.mkOption { + type = b2RepositoryType; + }; + }; + }; + }; + }; +in +{ + options.services.kopia.instances = lib.mkOption { + type = lib.types.attrsOf instanceType; + }; + + config = lib.mkIf config.services.kopia.enable { + # systemd service for repositories open + systemd.services = + let + mkRepositoryArgs = + name: instance: + ( + if lib.hasAttr "s3" instance.repository then + [ + "--bucket" + instance.repository.s3.bucket + "--endpoint" + instance.repository.s3.endpoint + "--region" + instance.repository.s3.region + ] + ++ (lib.optional (instance.repository.s3.disableTLS) "--disable-tls") + else if lib.hasAttr "b2" instance.repository then + [ "--bucket" instance.repository.s3.bucket ] + else + throw "Unsupported repository type for Kopia instance ${name}" + ); + + mkRepository = + let + mkTemplateRepository = + type: envs: name: instance: + lib.attrsets.nameValuePair "kopia-repository-${name}" { + description = "Kopia ${type} repository service"; + serviceConfig = + let + startScript = pkgs.writeShellScript "start-repository.sh" '' + # Check required environment variables + for var in KOPIA_PASSWORD ${toString envs}; do + if [[ -z "''${!var}" ]]; then + echo "''$var is not set, exiting." + exit 1 + fi + done + + if ! ${pkgs.kopia}/bin/kopia repository connect ${type} ${lib.concatStringsSep " " (mkRepositoryArgs name instance)}; then + ${pkgs.kopia}/bin/kopia repository create ${type} ${lib.concatStringsSep " " (mkRepositoryArgs name instance)}; + fi + ''; + + stopScript = pkgs.writeShellScript "stop-repository.sh" '' + ${pkgs.kopia}/bin/kopia repository disconnect + ''; + in + { + Type = "oneshot"; + User = "${instance.user}"; + WorkingDirectory = "~"; + SetLoginEnvironment = true; + EnvironmentFile = lib.mkIf (instance.environmentFile != null) instance.environmentFile; + RemainAfterExit = true; + ExecStart = "${startScript}"; + ExecStop = "${stopScript}"; + }; + }; + + mkS3Repository = mkTemplateRepository "S3" [ "AWS_ACCESS_KEY_ID" "AWS_SECRET_ACCESS_KEY" ]; + mkB2Repository = mkTemplateRepository "B2" [ "B2_KEY_ID" "B2_KEY" ]; + + dispatch = { + s3 = mkS3Repository; + b2 = mkB2Repository; + }; + in + name: instance: + let + repoType = builtins.head (lib.attrNames instance.repository); + in + if lib.hasAttr repoType dispatch then + dispatch.${repoType} name instance + else + throw "Unsupported repository type for Kopia instance ${name}"; + in + mkInstanceServices config.services.kopia.instances mkRepository; + }; +} |
