217 lines
5.6 KiB
Nix
217 lines
5.6 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
let
|
|
cfg = config.programs.rclone;
|
|
targetName = "rclone";
|
|
|
|
mkSystemdDependencyOption =
|
|
{ default, ... }: lib.mkOption {
|
|
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
|
description = "The systemd services this sync depends on.";
|
|
example = {
|
|
secrets = [
|
|
"sops-nix.service"
|
|
];
|
|
};
|
|
inherit default;
|
|
};
|
|
|
|
mkProvider =
|
|
{
|
|
secretLoader ? ({ ... }: ""),
|
|
envLoader ? ({ ... }: { }),
|
|
configLoader ? ({ ... }: { }),
|
|
options ? {},
|
|
...
|
|
}: {
|
|
inherit
|
|
secretLoader
|
|
envLoader
|
|
configLoader
|
|
options
|
|
;
|
|
};
|
|
|
|
mkWebdavOptions = { vendorName }: {
|
|
username = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "The name of the user to log in to ${vendorName}.";
|
|
};
|
|
|
|
password = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.str;
|
|
description = "The password for logging in to ${vendorName}.";
|
|
default = null;
|
|
};
|
|
|
|
passwordFile = lib.mkOption {
|
|
type = lib.types.nullOr (lib.types.either lib.types.path lib.types.str);
|
|
description = "A path to a file to read the password from for logging in to ${vendorName}.";
|
|
default = null;
|
|
};
|
|
};
|
|
|
|
mkOwncloudOptions =
|
|
{ vendorName ? "Nextcloud" }: (mkWebdavOptions { inherit vendorName; }) // {
|
|
baseUrl = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "The base URL of the ${vendorName} server.";
|
|
};
|
|
};
|
|
|
|
syncProviders = {
|
|
nextcloud = mkProvider {
|
|
options = lib.types.submodule (
|
|
(mkOwncloudOptions { }));
|
|
};
|
|
|
|
proton = mkProvider {};
|
|
manual = mkProvider {};
|
|
};
|
|
|
|
syncType = lib.types.submodule (
|
|
{ config, name, ... }: {
|
|
options = {
|
|
type = lib.mkOption {
|
|
description = "The type of the sync";
|
|
type = lib.types.enum (builtins.attrNames syncProviders);
|
|
default = "manual";
|
|
};
|
|
|
|
autoStart = lib.mkOption {
|
|
type = lib.types.bool;
|
|
description = "Whether to start this sync automatically.";
|
|
default = true;
|
|
};
|
|
|
|
providerOptions = lib.mkOption {
|
|
description = "The options of the sync";
|
|
type = lib.types.oneOf [
|
|
(builtins.map
|
|
(provider: provider.options)
|
|
syncProviders)
|
|
];
|
|
};
|
|
|
|
systemdDependencies = mkSystemdDependencyOption {
|
|
default = cfg.systemdDependencies;
|
|
};
|
|
|
|
environment = lib.mkOption {
|
|
type = lib.types.attrsOf lib.types.envVar;
|
|
description = "The environment variables to pass to the service.";
|
|
default = {};
|
|
};
|
|
|
|
secretsScript = lib.mkOption {
|
|
type = lib.types.lines;
|
|
description = "A script for loading secrets before launching the sync.";
|
|
default = [];
|
|
};
|
|
|
|
config = lib.mkOption {
|
|
type = lib.types.attrs;
|
|
description = "The rclone config to use for creating the mount.";
|
|
visible = false;
|
|
};
|
|
};
|
|
|
|
config = {
|
|
environment = syncProviders.${config.type}.envLoader config;
|
|
secretsScript = syncProviders.${config.type}.secretLoader config;
|
|
config = syncProviders.${config.type}.configLoader config;
|
|
};
|
|
});
|
|
in {
|
|
options = {
|
|
programs.rclone = {
|
|
enable = lib.mkEnableOption "rclone";
|
|
|
|
systemdDependencies = mkSystemdDependencyOption {
|
|
default = {};
|
|
};
|
|
|
|
configs = lib.mkOption {
|
|
type = lib.types.attrsOf syncType;
|
|
description = "The synchronizations to set up.";
|
|
default = {};
|
|
};
|
|
};
|
|
};
|
|
|
|
config = {
|
|
home.packages = lib.optional cfg.enable pkgs.rclone;
|
|
|
|
systemd.user = lib.optionalAttrs cfg.enable {
|
|
enable = true;
|
|
|
|
services = {
|
|
rclone = {
|
|
Unit = {
|
|
Description = "rclone Starter";
|
|
Documentation = "man:rclone(1)";
|
|
};
|
|
|
|
Service = {
|
|
Type = "simple";
|
|
|
|
ExecStartPre =
|
|
let
|
|
script = pkgs.writeShellScriptBin "rclone-pre" ''
|
|
sleep 10
|
|
'';
|
|
in
|
|
(lib.getExe script);
|
|
|
|
ExecStart =
|
|
let
|
|
script = pkgs.writeShellScriptBin "rclone" ''
|
|
systemctl --user start rclone.target
|
|
'';
|
|
in
|
|
(lib.getExe script);
|
|
};
|
|
};
|
|
} // (
|
|
lib.attrsets.concatMapAttrs
|
|
(name: sync:
|
|
let
|
|
serviceName = "rclone-sync-${name}";
|
|
in {
|
|
${serviceName} = {
|
|
Unit = {
|
|
Description = "${sync.type}";
|
|
};
|
|
|
|
Service = {
|
|
Environment = lib.mapAttrsToList
|
|
(key: val: (lib.escapeShellArg "${key}=${val}"))
|
|
sync.environment;
|
|
|
|
ExecStart =
|
|
let
|
|
script = pkgs.writeShellScriptBin serviceName ''
|
|
${sync.secretsScript}
|
|
bash -c echo hello world
|
|
'';
|
|
in
|
|
(lib.getExe script);
|
|
};
|
|
|
|
Install = {
|
|
WantedBy = lib.optional sync.autoStart "${targetName}.target";
|
|
After = builtins.concatLists(builtins.attrValues sync.systemdDependencies);
|
|
};
|
|
};
|
|
})
|
|
cfg.configs);
|
|
|
|
targets.${targetName} = {
|
|
Unit = {
|
|
Description = "rclone Mounts";
|
|
Documentation = "man:rclone(1)";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|