{ pkgs, lib, config, mkInstanceServices, ... }: let snapshotType = lib.types.submodule { options = { paths = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; description = "snapshoted paths"; }; schedule = lib.mkOption { type = lib.types.str; default = "*-*-* 4:00:00"; description = "Snapshot schedule"; }; }; }; instanceType = lib.types.submodule { options = { snapshots = lib.mkOption { type = snapshotType; }; }; }; in { options.services.kopia.instances = lib.mkOption { type = lib.types.attrsOf instanceType; }; config = lib.mkIf config.services.kopia.enable ( let mkSnapshotService = # refactor with mkRepositoryArgs name: instance: lib.attrsets.nameValuePair "kopia-snapshot-${name}" { description = "Kopia S3 snapshot service"; wants = [ "kopia-repository-${name}.service" ]; after = [ "kopia-repository-${name}.service" ]; script = lib.strings.concatLines ( lib.lists.forEach instance.snapshots.paths (x: '' ${pkgs.kopia}/bin/kopia snapshot create ${x} --description "Snapshot for ${name}" '') ); serviceConfig = { Type = "simple"; User = "${instance.user}"; WorkingDirectory = "~"; SetLoginEnvironment = true; # retry on failure Restart = "on-failure"; # wait 30 seconds before restarting RestartSec = "30"; # lower priority Nice = "-19"; IOSchedulingClass = "idle"; }; unitConfig = { # limit the number of restarts to 5 in 1 day StartLimitInterval = "1d"; StartLimitBurst = "5"; }; }; mkSnapshotTimer = name: instance: lib.attrsets.nameValuePair "kopia-snapshot-${name}" { description = "Kopia S3 snapshot timer"; wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = instance.snapshots.schedule; }; }; in { # systemd service for repositories open systemd.services = mkInstanceServices config.services.kopia.instances mkSnapshotService; systemd.timers = mkInstanceServices config.services.kopia.instances mkSnapshotTimer; } ); }