nixos/services.syncoid: remove with lib;
This commit is contained in:
committed by
Jörg Thalheim
parent
48d46271cb
commit
8442ed34ac
@@ -1,14 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.syncoid;
|
||||
|
||||
# Extract local dasaset names (so no datasets containing "@")
|
||||
localDatasetName = d: optionals (d != null) (
|
||||
localDatasetName = d: lib.optionals (d != null) (
|
||||
let m = builtins.match "([^/@]+[^@]*)" d; in
|
||||
optionals (m != null) m
|
||||
lib.optionals (m != null) m
|
||||
);
|
||||
|
||||
# Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
|
||||
@@ -35,7 +32,7 @@ let
|
||||
"/run/booted-system/sw/bin/zfs"
|
||||
"allow"
|
||||
cfg.user
|
||||
(concatStringsSep "," permissions)
|
||||
(lib.concatStringsSep "," permissions)
|
||||
dataset
|
||||
]}
|
||||
${lib.optionalString ((builtins.dirOf dataset) != ".") ''
|
||||
@@ -44,7 +41,7 @@ let
|
||||
"/run/booted-system/sw/bin/zfs"
|
||||
"allow"
|
||||
cfg.user
|
||||
(concatStringsSep "," permissions)
|
||||
(lib.concatStringsSep "," permissions)
|
||||
# Remove the last part of the path
|
||||
(builtins.dirOf dataset)
|
||||
]}
|
||||
@@ -66,14 +63,14 @@ let
|
||||
"/run/booted-system/sw/bin/zfs"
|
||||
"unallow"
|
||||
cfg.user
|
||||
(concatStringsSep "," permissions)
|
||||
(lib.concatStringsSep "," permissions)
|
||||
dataset
|
||||
]}
|
||||
${lib.optionalString ((builtins.dirOf dataset) != ".") (lib.escapeShellArgs [
|
||||
"/run/booted-system/sw/bin/zfs"
|
||||
"unallow"
|
||||
cfg.user
|
||||
(concatStringsSep "," permissions)
|
||||
(lib.concatStringsSep "," permissions)
|
||||
# Remove the last part of the path
|
||||
(builtins.dirOf dataset)
|
||||
])}
|
||||
@@ -85,12 +82,12 @@ in
|
||||
# Interface
|
||||
|
||||
options.services.syncoid = {
|
||||
enable = mkEnableOption "Syncoid ZFS synchronization service";
|
||||
enable = lib.mkEnableOption "Syncoid ZFS synchronization service";
|
||||
|
||||
package = lib.mkPackageOption pkgs "sanoid" {};
|
||||
|
||||
interval = mkOption {
|
||||
type = types.str;
|
||||
interval = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "hourly";
|
||||
example = "*-*-* *:15:00";
|
||||
description = ''
|
||||
@@ -101,8 +98,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "syncoid";
|
||||
example = "backup";
|
||||
description = ''
|
||||
@@ -115,15 +112,15 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "syncoid";
|
||||
example = "backup";
|
||||
description = "The group for the service.";
|
||||
};
|
||||
|
||||
sshKey = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
sshKey = lib.mkOption {
|
||||
type = with lib.types; nullOr (coercedTo path toString str);
|
||||
default = null;
|
||||
description = ''
|
||||
SSH private key file to use to login to the remote system. Can be
|
||||
@@ -131,8 +128,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
localSourceAllow = mkOption {
|
||||
type = types.listOf types.str;
|
||||
localSourceAllow = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
# Permissions snapshot and destroy are in case --no-sync-snap is not used
|
||||
default = [ "bookmark" "hold" "send" "snapshot" "destroy" "mount" ];
|
||||
description = ''
|
||||
@@ -143,8 +140,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
localTargetAllow = mkOption {
|
||||
type = types.listOf types.str;
|
||||
localTargetAllow = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "change-key" "compression" "create" "mount" "mountpoint" "receive" "rollback" ];
|
||||
example = [ "create" "mount" "receive" "rollback" ];
|
||||
description = ''
|
||||
@@ -158,8 +155,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
commonArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
commonArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "--no-sync-snap" ];
|
||||
description = ''
|
||||
@@ -170,19 +167,19 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
service = mkOption {
|
||||
type = types.attrs;
|
||||
service = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = { };
|
||||
description = ''
|
||||
Systemd configuration common to all syncoid services.
|
||||
'';
|
||||
};
|
||||
|
||||
commands = mkOption {
|
||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||
commands = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
source = mkOption {
|
||||
type = types.str;
|
||||
source = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "pool/dataset";
|
||||
description = ''
|
||||
Source ZFS dataset. Can be either local or remote. Defaults to
|
||||
@@ -190,8 +187,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
target = mkOption {
|
||||
type = types.str;
|
||||
target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "user@server:pool/dataset";
|
||||
description = ''
|
||||
Target ZFS dataset. Can be either local
|
||||
@@ -200,18 +197,18 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
recursive = mkEnableOption ''the transfer of child datasets'';
|
||||
recursive = lib.mkEnableOption ''the transfer of child datasets'';
|
||||
|
||||
sshKey = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
sshKey = lib.mkOption {
|
||||
type = with lib.types; nullOr (coercedTo path toString str);
|
||||
description = ''
|
||||
SSH private key file to use to login to the remote system.
|
||||
Defaults to {option}`services.syncoid.sshKey` option.
|
||||
'';
|
||||
};
|
||||
|
||||
localSourceAllow = mkOption {
|
||||
type = types.listOf types.str;
|
||||
localSourceAllow = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
Permissions granted for the {option}`services.syncoid.user` user
|
||||
for local source datasets. See
|
||||
@@ -221,8 +218,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
localTargetAllow = mkOption {
|
||||
type = types.listOf types.str;
|
||||
localTargetAllow = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
Permissions granted for the {option}`services.syncoid.user` user
|
||||
for local target datasets. See
|
||||
@@ -234,8 +231,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
sendOptions = mkOption {
|
||||
type = types.separatedString " ";
|
||||
sendOptions = lib.mkOption {
|
||||
type = lib.types.separatedString " ";
|
||||
default = "";
|
||||
example = "Lc e";
|
||||
description = ''
|
||||
@@ -244,8 +241,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
recvOptions = mkOption {
|
||||
type = types.separatedString " ";
|
||||
recvOptions = lib.mkOption {
|
||||
type = lib.types.separatedString " ";
|
||||
default = "";
|
||||
example = "ux recordsize o compression=lz4";
|
||||
description = ''
|
||||
@@ -254,38 +251,38 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
useCommonArgs = mkOption {
|
||||
type = types.bool;
|
||||
useCommonArgs = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to add the configured common arguments to this command.
|
||||
'';
|
||||
};
|
||||
|
||||
service = mkOption {
|
||||
type = types.attrs;
|
||||
service = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = { };
|
||||
description = ''
|
||||
Systemd configuration specific to this syncoid service.
|
||||
'';
|
||||
};
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "--sshport 2222" ];
|
||||
description = "Extra syncoid arguments for this command.";
|
||||
};
|
||||
};
|
||||
config = {
|
||||
source = mkDefault name;
|
||||
sshKey = mkDefault cfg.sshKey;
|
||||
localSourceAllow = mkDefault cfg.localSourceAllow;
|
||||
localTargetAllow = mkDefault cfg.localTargetAllow;
|
||||
source = lib.mkDefault name;
|
||||
sshKey = lib.mkDefault cfg.sshKey;
|
||||
localSourceAllow = lib.mkDefault cfg.localSourceAllow;
|
||||
localTargetAllow = lib.mkDefault cfg.localTargetAllow;
|
||||
};
|
||||
}));
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
"pool/test".target = "root@target:pool/test";
|
||||
}
|
||||
@@ -296,9 +293,9 @@ in
|
||||
|
||||
# Implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
users = {
|
||||
users = mkIf (cfg.user == "syncoid") {
|
||||
users = lib.mkIf (cfg.user == "syncoid") {
|
||||
syncoid = {
|
||||
group = cfg.group;
|
||||
isSystemUser = true;
|
||||
@@ -308,14 +305,14 @@ in
|
||||
createHome = false;
|
||||
};
|
||||
};
|
||||
groups = mkIf (cfg.group == "syncoid") {
|
||||
groups = lib.mkIf (cfg.group == "syncoid") {
|
||||
syncoid = { };
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = mapAttrs'
|
||||
systemd.services = lib.mapAttrs'
|
||||
(name: c:
|
||||
nameValuePair "syncoid-${escapeUnitName name}" (mkMerge [
|
||||
lib.nameValuePair "syncoid-${lib.escapeUnitName name}" (lib.mkMerge [
|
||||
{
|
||||
description = "Syncoid ZFS synchronization from ${c.source} to ${c.target}";
|
||||
after = [ "zfs.target" ];
|
||||
@@ -330,9 +327,9 @@ in
|
||||
(map (buildUnallowCommand c.localSourceAllow) (localDatasetName c.source)) ++
|
||||
(map (buildUnallowCommand c.localTargetAllow) (localDatasetName c.target));
|
||||
ExecStart = lib.escapeShellArgs ([ "${cfg.package}/bin/syncoid" ]
|
||||
++ optionals c.useCommonArgs cfg.commonArgs
|
||||
++ optional c.recursive "-r"
|
||||
++ optionals (c.sshKey != null) [ "--sshkey" c.sshKey ]
|
||||
++ lib.optionals c.useCommonArgs cfg.commonArgs
|
||||
++ lib.optional c.recursive "-r"
|
||||
++ lib.optionals (c.sshKey != null) [ "--sshkey" c.sshKey ]
|
||||
++ c.extraArgs
|
||||
++ [
|
||||
"--sendoptions"
|
||||
@@ -364,7 +361,7 @@ in
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
PrivateNetwork = mkDefault false;
|
||||
PrivateNetwork = lib.mkDefault false;
|
||||
PrivateUsers = false; # Enabling this breaks on zfs-2.2.0
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
@@ -379,15 +376,15 @@ in
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RootDirectory = "/run/syncoid/${escapeUnitName name}";
|
||||
RootDirectory = "/run/syncoid/${lib.escapeUnitName name}";
|
||||
RootDirectoryStartOnly = true;
|
||||
BindPaths = [ "/dev/zfs" ];
|
||||
BindReadOnlyPaths = [ builtins.storeDir "/etc" "/run" "/bin/sh" ];
|
||||
# Avoid useless mounting of RootDirectory= in the own RootDirectory= of ExecStart='s mount namespace.
|
||||
InaccessiblePaths = [ "-+/run/syncoid/${escapeUnitName name}" ];
|
||||
InaccessiblePaths = [ "-+/run/syncoid/${lib.escapeUnitName name}" ];
|
||||
MountAPIVFS = true;
|
||||
# Create RootDirectory= in the host's mount namespace.
|
||||
RuntimeDirectory = [ "syncoid/${escapeUnitName name}" ];
|
||||
RuntimeDirectory = [ "syncoid/${lib.escapeUnitName name}" ];
|
||||
RuntimeDirectoryMode = "700";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
@@ -416,5 +413,5 @@ in
|
||||
cfg.commands;
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ julm lopsided98 ];
|
||||
meta.maintainers = with lib.maintainers; [ julm lopsided98 ];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user