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