{ config, lib, pkgs, mkInstanceServices, ... }: let instanceType = lib.types.submodule { options = { maintenance = { schedule = lib.mkOption { type = lib.types.str; default = "*-*-* 6:00:00"; description = "kopia full maintenance schedule"; }; }; }; }; in { options.services.kopia.instances = lib.mkOption { type = lib.types.attrsOf instanceType; }; config = lib.mkIf config.services.kopia.enable ( let mkMaintenanceService = name: instance: lib.attrsets.nameValuePair "kopia-maintenance-${name}" { description = "Kopia ${name} maintenance service"; wants = [ "kopia-repository-${name}.service" ]; after = [ "kopia-repository-${name}.service" ]; conflicts = [ "kopia-snapshot-${name}.service" ]; script = '' ${pkgs.kopia}/bin/kopia maintenance run --full ''; 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"; }; }; mkMaintenanceTimer = name: instance: lib.attrsets.nameValuePair "kopia-maintenance-${name}" { description = "Kopia ${name} maintenance timer"; wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = instance.maintenance.schedule; }; }; in { # systemd service for repositories open systemd.services = mkInstanceServices config.services.kopia.instances mkMaintenanceService; systemd.timers = mkInstanceServices config.services.kopia.instances mkMaintenanceTimer; } ); }