diff options
author | Elis Hirwing <elis@hirwing.se> | 2021-07-25 18:31:19 +0200 |
---|---|---|
committer | Elis Hirwing <elis@hirwing.se> | 2021-07-26 11:04:28 +0200 |
commit | fa58d89b24611461304f591c64a5539bf1c13a7c (patch) | |
tree | 13dff3492c4b618ebe790836adbb6a9f34a79ee9 /nixos | |
parent | b9f98165ab22b3981d7017ce88f268c4176f8072 (diff) |
nixos/syncoid: Reformat file with nixpkgs-fmt
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/services/backup/syncoid.nix | 373 |
1 files changed, 196 insertions, 177 deletions
diff --git a/nixos/modules/services/backup/syncoid.nix b/nixos/modules/services/backup/syncoid.nix index 71007f6c38e23..61a905a488ac6 100644 --- a/nixos/modules/services/backup/syncoid.nix +++ b/nixos/modules/services/backup/syncoid.nix @@ -8,206 +8,213 @@ let # Extract local dasaset names (so no datasets containing "@") localDatasetName = d: optionals (d != null) ( let m = builtins.match "([^/@]+[^@]*)" d; in - optionals (m != null) m); + optionals (m != null) m + ); # Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html escapeUnitName = name: lib.concatMapStrings (s: if lib.isList s then "-" else s) - (builtins.split "[^a-zA-Z0-9_.\\-]+" name); + (builtins.split "[^a-zA-Z0-9_.\\-]+" name); # Function to build "zfs allow" and "zfs unallow" commands for the # filesystems we've delegated permissions to. buildAllowCommand = zfsAction: permissions: dataset: lib.escapeShellArgs [ # Here we explicitly use the booted system to guarantee the stable API needed by ZFS - "-+/run/booted-system/sw/bin/zfs" zfsAction - cfg.user (concatStringsSep "," permissions) dataset + "-+/run/booted-system/sw/bin/zfs" + zfsAction + cfg.user + (concatStringsSep "," permissions) + dataset ]; -in { +in +{ - # Interface + # Interface - options.services.syncoid = { - enable = mkEnableOption "Syncoid ZFS synchronization service"; + options.services.syncoid = { + enable = mkEnableOption "Syncoid ZFS synchronization service"; - interval = mkOption { - type = types.str; - default = "hourly"; - example = "*-*-* *:15:00"; - description = '' - Run syncoid at this interval. The default is to run hourly. + interval = mkOption { + type = types.str; + default = "hourly"; + example = "*-*-* *:15:00"; + description = '' + Run syncoid at this interval. The default is to run hourly. - The format is described in - <citerefentry><refentrytitle>systemd.time</refentrytitle> - <manvolnum>7</manvolnum></citerefentry>. - ''; - }; - - user = mkOption { - type = types.str; - default = "syncoid"; - example = "backup"; - description = '' - The user for the service. ZFS privilege delegation will be - automatically configured for any local pools used by syncoid if this - option is set to a user other than root. The user will be given the - "hold" and "send" privileges on any pool that has datasets being sent - and the "create", "mount", "receive", and "rollback" privileges on - any pool that has datasets being received. - ''; - }; + The format is described in + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>7</manvolnum></citerefentry>. + ''; + }; - group = mkOption { - type = types.str; - default = "syncoid"; - example = "backup"; - description = "The group for the service."; - }; + user = mkOption { + type = types.str; + default = "syncoid"; + example = "backup"; + description = '' + The user for the service. ZFS privilege delegation will be + automatically configured for any local pools used by syncoid if this + option is set to a user other than root. The user will be given the + "hold" and "send" privileges on any pool that has datasets being sent + and the "create", "mount", "receive", and "rollback" privileges on + any pool that has datasets being received. + ''; + }; - sshKey = mkOption { - type = types.nullOr types.path; - # Prevent key from being copied to store - apply = mapNullable toString; - default = null; - description = '' - SSH private key file to use to login to the remote system. Can be - overridden in individual commands. - ''; - }; + group = mkOption { + type = types.str; + default = "syncoid"; + example = "backup"; + description = "The group for the service."; + }; - commonArgs = mkOption { - type = types.listOf types.str; - default = []; - example = [ "--no-sync-snap" ]; - description = '' - Arguments to add to every syncoid command, unless disabled for that - command. See - <link xlink:href="https://github.com/jimsalterjrs/sanoid/#syncoid-command-line-options"/> - for available options. - ''; - }; + sshKey = mkOption { + type = types.nullOr types.path; + # Prevent key from being copied to store + apply = mapNullable toString; + default = null; + description = '' + SSH private key file to use to login to the remote system. Can be + overridden in individual commands. + ''; + }; - service = mkOption { - type = types.attrs; - default = {}; - description = '' - Systemd configuration common to all syncoid services. - ''; - }; + commonArgs = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "--no-sync-snap" ]; + description = '' + Arguments to add to every syncoid command, unless disabled for that + command. See + <link xlink:href="https://github.com/jimsalterjrs/sanoid/#syncoid-command-line-options"/> + for available options. + ''; + }; - commands = mkOption { - type = types.attrsOf (types.submodule ({ name, ... }: { - options = { - source = mkOption { - type = types.str; - example = "pool/dataset"; - description = '' - Source ZFS dataset. Can be either local or remote. Defaults to - the attribute name. - ''; - }; + service = mkOption { + type = types.attrs; + default = { }; + description = '' + Systemd configuration common to all syncoid services. + ''; + }; - target = mkOption { - type = types.str; - example = "user@server:pool/dataset"; - description = '' - Target ZFS dataset. Can be either local - (<replaceable>pool/dataset</replaceable>) or remote - (<replaceable>user@server:pool/dataset</replaceable>). - ''; - }; + commands = mkOption { + type = types.attrsOf (types.submodule ({ name, ... }: { + options = { + source = mkOption { + type = types.str; + example = "pool/dataset"; + description = '' + Source ZFS dataset. Can be either local or remote. Defaults to + the attribute name. + ''; + }; - recursive = mkEnableOption ''the transfer of child datasets''; + target = mkOption { + type = types.str; + example = "user@server:pool/dataset"; + description = '' + Target ZFS dataset. Can be either local + (<replaceable>pool/dataset</replaceable>) or remote + (<replaceable>user@server:pool/dataset</replaceable>). + ''; + }; - sshKey = mkOption { - type = types.nullOr types.path; - # Prevent key from being copied to store - apply = mapNullable toString; - description = '' - SSH private key file to use to login to the remote system. - Defaults to <option>services.syncoid.sshKey</option> option. - ''; - }; + recursive = mkEnableOption ''the transfer of child datasets''; - sendOptions = mkOption { - type = types.separatedString " "; - default = ""; - example = "Lc e"; - description = '' - Advanced options to pass to zfs send. Options are specified - without their leading dashes and separated by spaces. - ''; - }; + sshKey = mkOption { + type = types.nullOr types.path; + # Prevent key from being copied to store + apply = mapNullable toString; + description = '' + SSH private key file to use to login to the remote system. + Defaults to <option>services.syncoid.sshKey</option> option. + ''; + }; - recvOptions = mkOption { - type = types.separatedString " "; - default = ""; - example = "ux recordsize o compression=lz4"; - description = '' - Advanced options to pass to zfs recv. Options are specified - without their leading dashes and separated by spaces. - ''; - }; + sendOptions = mkOption { + type = types.separatedString " "; + default = ""; + example = "Lc e"; + description = '' + Advanced options to pass to zfs send. Options are specified + without their leading dashes and separated by spaces. + ''; + }; - useCommonArgs = mkOption { - type = types.bool; - default = true; - description = '' - Whether to add the configured common arguments to this command. - ''; - }; + recvOptions = mkOption { + type = types.separatedString " "; + default = ""; + example = "ux recordsize o compression=lz4"; + description = '' + Advanced options to pass to zfs recv. Options are specified + without their leading dashes and separated by spaces. + ''; + }; - service = mkOption { - type = types.attrs; - default = {}; - description = '' - Systemd configuration specific to this syncoid service. - ''; - }; + useCommonArgs = mkOption { + type = types.bool; + default = true; + description = '' + Whether to add the configured common arguments to this command. + ''; + }; - extraArgs = mkOption { - type = types.listOf types.str; - default = []; - example = [ "--sshport 2222" ]; - description = "Extra syncoid arguments for this command."; - }; + service = mkOption { + type = types.attrs; + default = { }; + description = '' + Systemd configuration specific to this syncoid service. + ''; }; - config = { - source = mkDefault name; - sshKey = mkDefault cfg.sshKey; + + extraArgs = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "--sshport 2222" ]; + description = "Extra syncoid arguments for this command."; }; - })); - default = {}; - example = literalExample '' - { - "pool/test".target = "root@target:pool/test"; - } - ''; - description = "Syncoid commands to run."; - }; + }; + config = { + source = mkDefault name; + sshKey = mkDefault cfg.sshKey; + }; + })); + default = { }; + example = literalExample '' + { + "pool/test".target = "root@target:pool/test"; + } + ''; + description = "Syncoid commands to run."; }; + }; - # Implementation + # Implementation - config = mkIf cfg.enable { - users = { - users = mkIf (cfg.user == "syncoid") { - syncoid = { - group = cfg.group; - isSystemUser = true; - # For syncoid to be able to create /var/lib/syncoid/.ssh/ - # and to use custom ssh_config or known_hosts. - home = "/var/lib/syncoid"; - createHome = false; - }; - }; - groups = mkIf (cfg.group == "syncoid") { - syncoid = {}; + config = mkIf cfg.enable { + users = { + users = mkIf (cfg.user == "syncoid") { + syncoid = { + group = cfg.group; + isSystemUser = true; + # For syncoid to be able to create /var/lib/syncoid/.ssh/ + # and to use custom ssh_config or known_hosts. + home = "/var/lib/syncoid"; + createHome = false; }; }; + groups = mkIf (cfg.group == "syncoid") { + syncoid = { }; + }; + }; - systemd.services = mapAttrs' (name: c: + systemd.services = mapAttrs' + (name: c: nameValuePair "syncoid-${escapeUnitName name}" (mkMerge [ - { description = "Syncoid ZFS synchronization from ${c.source} to ${c.target}"; + { + description = "Syncoid ZFS synchronization from ${c.source} to ${c.target}"; after = [ "zfs.target" ]; startAt = cfg.interval; # syncoid may need zpool to get feature@extensible_dataset @@ -226,11 +233,15 @@ in { ++ optional c.recursive "-r" ++ optionals (c.sshKey != null) [ "--sshkey" c.sshKey ] ++ c.extraArgs - ++ [ "--sendoptions" c.sendOptions - "--recvoptions" c.recvOptions - "--no-privilege-elevation" - c.source c.target - ]); + ++ [ + "--sendoptions" + c.sendOptions + "--recvoptions" + c.recvOptions + "--no-privilege-elevation" + c.source + c.target + ]); User = cfg.user; Group = cfg.group; StateDirectory = [ "syncoid" ]; @@ -246,7 +257,7 @@ in { # systemd-analyze security | grep syncoid-'*' AmbientCapabilities = ""; CapabilityBoundingSet = ""; - DeviceAllow = ["/dev/zfs"]; + DeviceAllow = [ "/dev/zfs" ]; LockPersonality = true; MemoryDenyWriteExecute = true; NoNewPrivileges = true; @@ -272,7 +283,7 @@ in { 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/${escapeUnitName name}" ]; MountAPIVFS = true; # Create RootDirectory= in the host's mount namespace. RuntimeDirectory = [ "syncoid/${escapeUnitName name}" ]; @@ -283,8 +294,15 @@ in { # perf stat -x, 2>perf.log -e 'syscalls:sys_enter_*' syncoid … # awk >perf.syscalls -F "," '$1 > 0 {sub("syscalls:sys_enter_","",$3); print $3}' perf.log # systemd-analyze syscall-filter | grep -v -e '#' | sed -e ':loop; /^[^ ]/N; s/\n //; t loop' | grep $(printf ' -e \\<%s\\>' $(cat perf.syscalls)) | cut -f 1 -d ' ' - "~@aio" "~@chown" "~@keyring" "~@memlock" "~@privileged" - "~@resources" "~@setuid" "~@sync" "~@timer" + "~@aio" + "~@chown" + "~@keyring" + "~@memlock" + "~@privileged" + "~@resources" + "~@setuid" + "~@sync" + "~@timer" ]; SystemCallArchitectures = "native"; # This is for BindPaths= and BindReadOnlyPaths= @@ -294,8 +312,9 @@ in { } cfg.service c.service - ])) cfg.commands; - }; + ])) + cfg.commands; + }; - meta.maintainers = with maintainers; [ julm lopsided98 ]; - } + meta.maintainers = with maintainers; [ julm lopsided98 ]; +} |