{ config, lib, pkgs, ... }: with lib; let cfg = config.services.rclone-sync; daemonService = sync_config: { serviceConfig = lib.mkMerge [ { Type = "oneshot"; User = if cfg.user != null then "${cfg.user}" else "root"; ExecStart = "${pkgs.rclone}/bin/rclone sync ${sync_config.source} ${sync_config.dest} ${lib.concatStringsSep " " sync_config.extraArgs} -P"; } (lib.mkIf sync_config.autoRestart { TimeoutSec = 60; Restart = "on-failure"; }) 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;}; id = mkOption {type = types.str;}; extraArgs = mkOption { type = types.listOf types.str; default = []; }; autoRestart = mkOption { type = types.bool; default = true; }; timerConfig = mkOption { type = types.attrs; default = { OnStartupSec = "60"; OnCalendar = "4h"; }; }; serviceConfig = mkOption { type = types.attrs; default = {}; }; }; }); default = []; }; }; }; config = mkMerge [ (mkIf (cfg.enable && cfg.sync_jobs != []) { environment.systemPackages = [ (pkgs.writeShellScriptBin "rclone-sync-all" (lib.concatStringsSep "\n" (map ( job: '' ${pkgs.rclone}/bin/rclone sync ${job.source} ${job.dest} ${lib.concatStringsSep " " job.extraArgs} -P $@ '' ) cfg.sync_jobs))) ] ++ ( map ( job: pkgs.writeShellScriptBin "rclone-manual-sync-${job.id}" '' exec ${pkgs.rclone}/bin/rclone sync ${job.source} ${job.dest} ${lib.concatStringsSep " " job.extraArgs} -P $@ '' ) cfg.sync_jobs ); systemd.services = listToAttrs (map (job: { name = "rclone-sync-${job.id}"; value = daemonService job; }) cfg.sync_jobs); systemd.timers = listToAttrs (map (job: let name = "rclone-sync-${job.id}"; in { inherit name; value = { wantedBy = ["timers.target"]; partOf = ["${name}.service"]; timerConfig = job.timerConfig; }; }) cfg.sync_jobs); }) ]; }