{ 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 ); }; }