{ config, lib, pkgs, ... }: with lib; let cfg = config.services.rclone-sync; makeNameSafe = name: builtins.replaceStrings [ "/" ":" ] [ "-" "-" ] name; daemonService = sync_config: lib.mkMerge [ { serviceConfig = { Type = "oneshot"; User = if cfg.user != null then "${cfg.user}" else "root"; ExecStart = "${pkgs.rclone}/bin/rclone sync ${sync_config.source} ${sync_config.dest} -P"; }; } sync_config.serviceConfig ]; in { options = { services.rclone-sync = { enable = mkOption { type = types.bool; default = false; }; user = mkOption { type = types.str; default = null; }; sync_jobs = mkOption { type = types.listOf (types.submodule { options = { source = mkOption { type = types.str; }; dest = mkOption { type = types.str; }; timerConfig = mkOption { type = types.attrs; }; serviceConfig = mkOption { type = types.attrs; }; }; }); default = [ ]; }; }; }; config = mkMerge [ (mkIf (cfg.enable && cfg.sync_jobs != [ ]) { systemd.services = listToAttrs (map (job: { name = "rclone-sync-${makeNameSafe job.source}-${makeNameSafe job.dest}"; value = daemonService job; }) cfg.sync_jobs); systemd.timers = listToAttrs (map (job: let name = "rclone-sync-${makeNameSafe job.source}-${makeNameSafe job.dest}"; in { inherit name; value = { wantedBy = [ "timers.target" ]; partOf = [ "${name}.service" ]; timerConfig = job.timerConfig; }; }) cfg.sync_jobs); }) ]; }