aboutsummaryrefslogtreecommitdiff
path: root/modules/backup/repositories.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/backup/repositories.nix')
-rw-r--r--modules/backup/repositories.nix144
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;
+ };
+}