{ pkgs, config, lib, ... }: with lib; let cfg = config.eboskma.programs.rclone; rcloneConnectionString = mount: let type = mount.remoteConfig.type; config = builtins.removeAttrs mount.remoteConfig [ "type" ]; connectionStringOptions = mapAttrsToList (key: value: "${key}=${builtins.toJSON value}") config; in ":${type},${builtins.concatStringsSep "," connectionStringOptions}:${mount.remote}"; rcloneRemote = with types; attrsOf (oneOf [ str int bool ]); rcloneMount = with types; submodule { options = { remoteConfig = mkOption { description = "Configuration for the remote to use"; type = rcloneRemote; }; remote = mkOption { description = "Remote path"; type = str; }; local = mkOption { description = "Local mountpoint"; type = path; }; }; }; in { options.eboskma.programs.rclone = { enable = mkEnableOption "rclone"; mounts = mkOption { description = "Mount remotes on a local path"; type = with types; listOf rcloneMount; default = [ ]; }; }; config = mkIf (cfg.enable) { home.packages = [ pkgs.rclone ]; systemd.user.services = builtins.listToAttrs (builtins.map (mount: let localPath = toString mount.local; unitName = builtins.replaceStrings [ "/" ] [ "-" ] (builtins.substring 1 (builtins.stringLength localPath) localPath); in { name = "rclone-${unitName}"; value = { Unit = { Description = "rclone mount ${unitName}"; After = [ "network.target" ]; AssertPathIsDirectory = (toString mount.local); }; Service = { Environment = [ "PATH=/run/wrappers/bin:$PATH" ]; ExecStart = "${pkgs.rclone}/bin/rclone mount --vfs-cache-mode full --vfs-cache-poll-interval 5s --poll-interval 5s --dir-cache-time 10s --umask 022 --allow-other ${rcloneConnectionString mount} ${mount.local}"; ExecStop = "/run/wrappers/bin/fusermount -zu ${mount.local}"; Restart = "on-failure"; RestartSec = 10; }; Install = { WantedBy = [ "default.target" ]; }; }; }) cfg.mounts); }; }