{ 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.b2.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; }; }