{ 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-serve; daemonService = serveConfig: mkMerge [ { wantedBy = ["multi-user.target"]; after = ["network.target"]; wants = ["network.target"]; serviceConfig = { Type = "simple"; Restart = "on-failure"; RestartSec = "10s"; User = serveConfig.user; ExecStart = "${pkgs.rclone}/bin/rclone serve ${serveConfig.type} ${serveConfig.remote} ${ concatStringsSep " " serveConfig.extraArgs }"; }; } serveConfig.serviceConfig ]; in { options = { services.rclone-serve = { enable = mkOption { type = types.bool; default = false; }; remotes = mkOption { type = types.listOf (types.submodule { options = { id = mkOption { type = types.str; # TODO: add a assertion for this description = "ID for the serve systemd unit; doesn't need to be unique as long as there is no other with same ID and same remote"; }; remote = mkOption { type = types.str; }; type = mkOption { type = types.str; default = "webdav"; }; user = mkOption { type = types.str; default = "root"; }; serviceConfig = mkOption { type = types.attrs; default = {}; }; extraArgs = mkOption { type = types.listOf types.str; default = []; }; }; }); default = []; }; }; }; config = mkMerge [ (mkIf (cfg.enable && cfg.remotes != []) { systemd.services = listToAttrs (map (remote: { name = "rclone-serve-${remote.type}-${remote.id}"; value = daemonService remote; }) cfg.remotes); }) ]; }