diff options
author | Parnell Springmeyer <parnell@digitalmentat.com> | 2017-01-25 11:08:05 -0800 |
---|---|---|
committer | Parnell Springmeyer <parnell@digitalmentat.com> | 2017-01-25 11:08:05 -0800 |
commit | bae00e8aa8f3faff90e28e19cd5074b8c26d0d0e (patch) | |
tree | 56abaf30f11ad2f24b9fb7729f74c5fff50fbd93 /nixos/modules/tasks | |
parent | 1f9494b752082ec3ac048e56d1c6364a2e23a675 (diff) | |
parent | 104c3db6594043dbb81005303f055b02145305a5 (diff) | |
download | nixlib-bae00e8aa8f3faff90e28e19cd5074b8c26d0d0e.tar nixlib-bae00e8aa8f3faff90e28e19cd5074b8c26d0d0e.tar.gz nixlib-bae00e8aa8f3faff90e28e19cd5074b8c26d0d0e.tar.bz2 nixlib-bae00e8aa8f3faff90e28e19cd5074b8c26d0d0e.tar.lz nixlib-bae00e8aa8f3faff90e28e19cd5074b8c26d0d0e.tar.xz nixlib-bae00e8aa8f3faff90e28e19cd5074b8c26d0d0e.tar.zst nixlib-bae00e8aa8f3faff90e28e19cd5074b8c26d0d0e.zip |
setcap-wrapper: Merging with upstream master and resolving conflicts
Diffstat (limited to 'nixos/modules/tasks')
-rw-r--r-- | nixos/modules/tasks/filesystems.nix | 15 | ||||
-rw-r--r-- | nixos/modules/tasks/filesystems/nfs.nix | 16 | ||||
-rw-r--r-- | nixos/modules/tasks/filesystems/zfs.nix | 50 | ||||
-rw-r--r-- | nixos/modules/tasks/network-interfaces-scripted.nix | 108 | ||||
-rw-r--r-- | nixos/modules/tasks/network-interfaces-systemd.nix | 2 | ||||
-rw-r--r-- | nixos/modules/tasks/network-interfaces.nix | 555 |
6 files changed, 408 insertions, 338 deletions
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 9ab1baeacb98..49ba66ad50af 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -18,7 +18,7 @@ let prioOption = prio: optionalString (prio != null) " pri=${toString prio}"; - specialFSTypes = [ "proc" "sysfs" "tmpfs" "devtmpfs" "devpts" ]; + specialFSTypes = [ "proc" "sysfs" "tmpfs" "ramfs" "devtmpfs" "devpts" ]; coreFileSystemOpts = { name, config, ... }: { @@ -258,7 +258,7 @@ in let mountPoint' = "${escapeSystemdPath fs.mountPoint}.mount"; device' = escapeSystemdPath fs.device; - device'' = "${device}.device"; + device'' = "${device'}.device"; in nameValuePair "mkfs-${device'}" { description = "Initialisation of Filesystem ${fs.device}"; wantedBy = [ mountPoint' ]; @@ -286,11 +286,18 @@ in # Sync mount options with systemd's src/core/mount-setup.c: mount_table. boot.specialFileSystems = { "/proc" = { fsType = "proc"; options = [ "nosuid" "noexec" "nodev" ]; }; - "/sys" = { fsType = "sysfs"; options = [ "nosuid" "noexec" "nodev" ]; }; - "/run" = { fsType = "tmpfs"; options = [ "nosuid" "nodev" "strictatime" "mode=755" "size=${config.boot.runSize}" ]; }; + "/run" = { fsType = "tmpfs"; options = [ "nodev" "strictatime" "mode=755" "size=${config.boot.runSize}" ]; }; "/dev" = { fsType = "devtmpfs"; options = [ "nosuid" "strictatime" "mode=755" "size=${config.boot.devSize}" ]; }; "/dev/shm" = { fsType = "tmpfs"; options = [ "nosuid" "nodev" "strictatime" "mode=1777" "size=${config.boot.devShmSize}" ]; }; "/dev/pts" = { fsType = "devpts"; options = [ "nosuid" "noexec" "mode=620" "gid=${toString config.ids.gids.tty}" ]; }; + + # To hold secrets that shouldn't be written to disk (generally used for NixOps, harmless elsewhere) + "/run/keys" = { fsType = "ramfs"; options = [ "nosuid" "nodev" "mode=750" "gid=${toString config.ids.gids.keys}" ]; }; + } // optionalAttrs (!config.boot.isContainer) { + # systemd-nspawn populates /sys by itself, and remounting it causes all + # kinds of weird issues (most noticeably, waiting for host disk device + # nodes). + "/sys" = { fsType = "sysfs"; options = [ "nosuid" "noexec" "nodev" ]; }; }; }; diff --git a/nixos/modules/tasks/filesystems/nfs.nix b/nixos/modules/tasks/filesystems/nfs.nix index e454eca3a0e5..e9a7ccc721a9 100644 --- a/nixos/modules/tasks/filesystems/nfs.nix +++ b/nixos/modules/tasks/filesystems/nfs.nix @@ -38,15 +38,17 @@ in default = null; example = 4000; description = '' - Use fixed port for rpc.statd, useful if NFS server is behind firewall. + Use a fixed port for <command>rpc.statd</command>. This is + useful if the NFS server is behind a firewall. ''; }; lockdPort = mkOption { default = null; example = 4001; description = '' - Use fixed port for NFS lock manager kernel module (lockd/nlockmgr), - useful if NFS server is behind firewall. + Use a fixed port for the NFS lock manager kernel module + (<literal>lockd/nlockmgr</literal>). This is useful if the + NFS server is behind a firewall. ''; }; }; @@ -68,13 +70,16 @@ in boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ]; + # FIXME: should use upstream units from nfs-utils. + systemd.services.statd = { description = "NFSv3 Network Status Monitor"; path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ]; - wantedBy = [ "remote-fs-pre.target" ]; + wants = [ "remote-fs-pre.target" ]; before = [ "remote-fs-pre.target" ]; + wantedBy = [ "remote-fs.target" ]; requires = [ "basic.target" "rpcbind.service" ]; after = [ "basic.target" "rpcbind.service" ]; @@ -100,8 +105,9 @@ in path = [ pkgs.sysvtools pkgs.utillinux ]; - wantedBy = [ "remote-fs-pre.target" ]; + wants = [ "remote-fs-pre.target" ]; before = [ "remote-fs-pre.target" ]; + wantedBy = [ "remote-fs.target" ]; requires = [ "rpcbind.service" ]; after = [ "rpcbind.service" ]; diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index c5f41cc338cf..045cbeb7cff8 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -22,12 +22,18 @@ let kernel = config.boot.kernelPackages; - splKernelPkg = kernel.spl; - zfsKernelPkg = kernel.zfs; - zfsUserPkg = pkgs.zfs; + packages = if config.boot.zfs.enableUnstable then { + spl = kernel.splUnstable; + zfs = kernel.zfsUnstable; + zfsUser = pkgs.zfsUnstable; + } else { + spl = kernel.spl; + zfs = kernel.zfs; + zfsUser = pkgs.zfs; + }; autosnapPkg = pkgs.zfstools.override { - zfs = zfsUserPkg; + zfs = packages.zfsUser; }; zfsAutoSnap = "${autosnapPkg}/bin/zfs-auto-snapshot"; @@ -54,6 +60,18 @@ in options = { boot.zfs = { + enableUnstable = mkOption { + type = types.bool; + default = false; + description = '' + Use the unstable zfs package. This might be an option, if the latest + kernel is not yet supported by a published release of ZFS. Enabling + this option will install a development version of ZFS on Linux. The + version will have already passed an extensive test suite, but it is + more likely to hit an undiscovered bug compared to running a released + version of ZFS on Linux. + ''; + }; extraPools = mkOption { type = types.listOf types.str; @@ -218,16 +236,16 @@ in boot = { kernelModules = [ "spl" "zfs" ] ; - extraModulePackages = [ splKernelPkg zfsKernelPkg ]; + extraModulePackages = with packages; [ spl zfs ]; }; boot.initrd = mkIf inInitrd { kernelModules = [ "spl" "zfs" ]; extraUtilsCommands = '' - copy_bin_and_libs ${zfsUserPkg}/sbin/zfs - copy_bin_and_libs ${zfsUserPkg}/sbin/zdb - copy_bin_and_libs ${zfsUserPkg}/sbin/zpool + copy_bin_and_libs ${packages.zfsUser}/sbin/zfs + copy_bin_and_libs ${packages.zfsUser}/sbin/zdb + copy_bin_and_libs ${packages.zfsUser}/sbin/zpool ''; extraUtilsCommandsTest = mkIf inInitrd '' @@ -264,14 +282,14 @@ in zfsSupport = true; }; - environment.etc."zfs/zed.d".source = "${zfsUserPkg}/etc/zfs/zed.d/*"; + environment.etc."zfs/zed.d".source = "${packages.zfsUser}/etc/zfs/zed.d/*"; - system.fsPackages = [ zfsUserPkg ]; # XXX: needed? zfs doesn't have (need) a fsck - environment.systemPackages = [ zfsUserPkg ] - ++ optional enableAutoSnapshots autosnapPkg; # so the user can run the command to see flags + system.fsPackages = [ packages.zfsUser ]; # XXX: needed? zfs doesn't have (need) a fsck + environment.systemPackages = [ packages.zfsUser ] + ++ optional enableAutoSnapshots autosnapPkg; # so the user can run the command to see flags - services.udev.packages = [ zfsUserPkg ]; # to hook zvol naming, etc. - systemd.packages = [ zfsUserPkg ]; + services.udev.packages = [ packages.zfsUser ]; # to hook zvol naming, etc. + systemd.packages = [ packages.zfsUser ]; systemd.services = let getPoolFilesystems = pool: @@ -298,7 +316,7 @@ in RemainAfterExit = true; }; script = '' - zpool_cmd="${zfsUserPkg}/sbin/zpool" + zpool_cmd="${packages.zfsUser}/sbin/zpool" ("$zpool_cmd" list "${pool}" >/dev/null) || "$zpool_cmd" import -d ${cfgZfs.devNodes} -N ${optionalString cfgZfs.forceImportAll "-f"} "${pool}" ''; }; @@ -314,7 +332,7 @@ in RemainAfterExit = true; }; script = '' - ${zfsUserPkg}/sbin/zfs set nixos:shutdown-time="$(date)" "${pool}" + ${packages.zfsUser}/sbin/zfs set nixos:shutdown-time="$(date)" "${pool}" ''; }; diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index c960e401f9b1..c50ea5c79643 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -46,6 +46,23 @@ in systemd.services = let + deviceDependency = dev: + if (config.boot.isContainer == false) + then + # Trust udev when not in the container + optional (dev != null) (subsystemDevice dev) + else + # When in the container, check whether the interface is built from other definitions + if (hasAttr dev cfg.bridges) || + (hasAttr dev cfg.bonds) || + (hasAttr dev cfg.macvlans) || + (hasAttr dev cfg.sits) || + (hasAttr dev cfg.vlans) || + (hasAttr dev cfg.vswitches) || + (hasAttr dev cfg.wlanInterfaces) + then [ "${dev}-netdev.service" ] + else []; + networkLocalCommands = { after = [ "network-setup.service" ]; bindsTo = [ "network-setup.service" ]; @@ -54,16 +71,22 @@ in networkSetup = { description = "Networking Setup"; - after = [ "network-interfaces.target" "network-pre.target" ]; - before = [ "network.target" ]; - wantedBy = [ "network.target" ]; + after = [ "network-pre.target" "systemd-udevd.service" "systemd-sysctl.service" ]; + before = [ "network.target" "shutdown.target" ]; + wants = [ "network.target" ]; + conflicts = [ "shutdown.target" ]; + wantedBy = [ "multi-user.target" ]; unitConfig.ConditionCapability = "CAP_NET_ADMIN"; path = [ pkgs.iproute ]; - serviceConfig.Type = "oneshot"; - serviceConfig.RemainAfterExit = true; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + unitConfig.DefaultDependencies = false; script = '' @@ -108,10 +131,14 @@ in in nameValuePair "network-addresses-${i.name}" { description = "Address configuration of ${i.name}"; - wantedBy = [ "network-interfaces.target" ]; - before = [ "network-interfaces.target" ]; - bindsTo = [ (subsystemDevice i.name) ]; - after = [ (subsystemDevice i.name) "network-pre.target" ]; + wantedBy = [ "network-setup.service" ]; + # propagate stop and reload from network-setup + partOf = [ "network-setup.service" ]; + # order before network-setup because the routes that are configured + # there may need ip addresses configured + before = [ "network-setup.service" ]; + bindsTo = deviceDependency i.name; + after = [ "network-pre.target" ] ++ (deviceDependency i.name); serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -129,21 +156,11 @@ in echo "checking ip ${address}..." if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then echo "added ip ${address}..." - restart_network_setup=true elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then echo "failed to add ${address}" exit 1 fi - '') - + optionalString (ips != [ ]) - '' - if [ "$restart_network_setup" = "true" ]; then - # Ensure that the default gateway remains set. - # (Flushing this interface may have removed it.) - ${config.systemd.package}/bin/systemctl try-restart --no-block network-setup.service - fi - ${config.systemd.package}/bin/systemctl start ip-up.target - ''; + ''); preStop = flip concatMapStrings (ips) (ip: let address = "${ip.address}/${toString ip.prefixLength}"; @@ -157,10 +174,11 @@ in createTunDevice = i: nameValuePair "${i.name}-netdev" { description = "Virtual Network Interface ${i.name}"; - requires = [ "dev-net-tun.device" ]; + bindsTo = [ "dev-net-tun.device" ]; after = [ "dev-net-tun.device" "network-pre.target" ]; - wantedBy = [ "network.target" (subsystemDevice i.name) ]; - before = [ "network-interfaces.target" (subsystemDevice i.name) ]; + wantedBy = [ "network-setup.service" (subsystemDevice i.name) ]; + partOf = [ "network-setup.service" ]; + before = [ "network-setup.service" (subsystemDevice i.name) ]; path = [ pkgs.iproute ]; serviceConfig = { Type = "oneshot"; @@ -178,15 +196,15 @@ in createBridgeDevice = n: v: nameValuePair "${n}-netdev" (let - deps = map subsystemDevice v.interfaces; + deps = concatLists (map deviceDependency v.interfaces); in { description = "Bridge Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps ++ optional v.rstp "mstpd.service"; - partOf = optional v.rstp "mstpd.service"; + partOf = [ "network-setup.service" ] ++ optional v.rstp "mstpd.service"; after = [ "network-pre.target" "mstpd.service" ] ++ deps ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -219,15 +237,15 @@ in createVswitchDevice = n: v: nameValuePair "${n}-netdev" (let - deps = map subsystemDevice v.interfaces; + deps = concatLists (map deviceDependency v.interfaces); ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules; in { description = "Open vSwitch Interface ${n}"; - wantedBy = [ "network.target" "vswitchd.service" ] ++ deps; + wantedBy = [ "network-setup.service" "vswitchd.service" ] ++ deps; bindsTo = [ "vswitchd.service" (subsystemDevice n) ] ++ deps; - partOf = [ "vswitchd.service" ]; + partOf = [ "network-setup.service" "vswitchd.service" ]; after = [ "network-pre.target" "vswitchd.service" ] ++ deps; - before = [ "network-interfaces.target" ]; + before = [ "network-setup.service" ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute config.virtualisation.vswitch.package ]; @@ -252,14 +270,15 @@ in createBondDevice = n: v: nameValuePair "${n}-netdev" (let - deps = map subsystemDevice v.interfaces; + deps = concatLists (map deviceDependency v.interfaces); in { description = "Bond Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps; + partOf = [ "network-setup.service" ]; after = [ "network-pre.target" ] ++ deps ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute pkgs.gawk ]; @@ -289,13 +308,14 @@ in createMacvlanDevice = n: v: nameValuePair "${n}-netdev" (let - deps = [ (subsystemDevice v.interface) ]; + deps = deviceDependency v.interface; in { description = "Vlan Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps; + partOf = [ "network-setup.service" ]; after = [ "network-pre.target" ] ++ deps; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -313,13 +333,14 @@ in createSitDevice = n: v: nameValuePair "${n}-netdev" (let - deps = optional (v.dev != null) (subsystemDevice v.dev); + deps = deviceDependency v.dev; in { description = "6-to-4 Tunnel Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps; + partOf = [ "network-setup.service" ]; after = [ "network-pre.target" ] ++ deps; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -340,13 +361,14 @@ in createVlanDevice = n: v: nameValuePair "${n}-netdev" (let - deps = [ (subsystemDevice v.interface) ]; + deps = deviceDependency v.interface; in { description = "Vlan Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps; + partOf = [ "network-setup.service" ]; after = [ "network-pre.target" ] ++ deps; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix index 301ee43fd0e5..974041d7e1a5 100644 --- a/nixos/modules/tasks/network-interfaces-systemd.nix +++ b/nixos/modules/tasks/network-interfaces-systemd.nix @@ -43,7 +43,7 @@ in message = "networking.bridges.${n}.rstp is not supported by networkd."; }); - systemd.services.dhcpcd.enable = mkDefault false; + networking.dhcpcd.enable = mkDefault false; systemd.services.network-local-commands = { after = [ "systemd-networkd.service" ]; diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 1e0b874297a2..a69435ff5937 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -97,21 +97,22 @@ let addrOpts = v: assert v == 4 || v == 6; - { - address = mkOption { - type = types.str; - description = '' - IPv${toString v} address of the interface. Leave empty to configure the - interface using DHCP. - ''; - }; + { options = { + address = mkOption { + type = types.str; + description = '' + IPv${toString v} address of the interface. Leave empty to configure the + interface using DHCP. + ''; + }; - prefixLength = mkOption { - type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128)); - description = '' - Subnet mask of the interface, specified as the number of - bits in the prefix (<literal>${if v == 4 then "24" else "64"}</literal>). - ''; + prefixLength = mkOption { + type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128)); + description = '' + Subnet mask of the interface, specified as the number of + bits in the prefix (<literal>${if v == 4 then "24" else "64"}</literal>). + ''; + }; }; }; @@ -141,8 +142,7 @@ let { address = "10.0.0.1"; prefixLength = 16; } { address = "192.168.1.1"; prefixLength = 24; } ]; - type = types.listOf types.optionSet; - options = addrOpts 4; + type = with types; listOf (submodule (addrOpts 4)); description = '' List of IPv4 addresses that will be statically assigned to the interface. ''; @@ -154,8 +154,7 @@ let { address = "fdfd:b3f0:482::1"; prefixLength = 48; } { address = "2001:1470:fffd:2098::e006"; prefixLength = 64; } ]; - type = types.listOf types.optionSet; - options = addrOpts 6; + type = with types; listOf (submodule (addrOpts 6)); description = '' List of IPv6 addresses that will be statically assigned to the interface. ''; @@ -231,7 +230,7 @@ let type = types.bool; description = '' Whether this interface is virtual and should be created by tunctl. - This is mainly useful for creating bridges between a host a virtual + This is mainly useful for creating bridges between a host and a virtual network such as VPN or a virtual machine. ''; }; @@ -246,7 +245,7 @@ let virtualType = mkOption { default = null; - type = types.nullOr (types.addCheck types.str (v: v == "tun" || v == "tap")); + type = with types; nullOr (enum [ "tun" "tap" ]); description = '' The explicit type of interface to create. Accepts tun or tap strings. Also accepts null to implicitly detect the type of device. @@ -311,9 +310,9 @@ in generate a random 32-bit ID using the following commands: <literal>cksum /etc/machine-id | while read c rest; do printf "%x" $c; done</literal> - + (this derives it from the machine-id that systemd generates) or - + <literal>head -c4 /dev/urandom | od -A none -t x4</literal> ''; }; @@ -391,7 +390,7 @@ in }; networking.localCommands = mkOption { - type = types.str; + type = types.lines; default = ""; example = "text=anything; echo You can put $text here."; description = '' @@ -415,8 +414,7 @@ in <option>networking.useDHCP</option> is true, then every interface not listed here will be configured using DHCP. ''; - type = types.loaOf types.optionSet; - options = [ interfaceOpts ]; + type = with types; loaOf (submodule interfaceOpts); }; networking.vswitches = mkOption { @@ -434,53 +432,55 @@ in interface. ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { + options = { - interfaces = mkOption { - example = [ "eth0" "eth1" ]; - type = types.listOf types.str; - description = - "The physical network interfaces connected by the vSwitch."; - }; + interfaces = mkOption { + example = [ "eth0" "eth1" ]; + type = types.listOf types.str; + description = + "The physical network interfaces connected by the vSwitch."; + }; - controllers = mkOption { - type = types.listOf types.str; - default = []; - example = [ "ptcp:6653:[::1]" ]; - description = '' - Specify the controller targets. For the allowed options see <literal>man 8 ovs-vsctl</literal>. - ''; - }; + controllers = mkOption { + type = types.listOf types.str; + default = []; + example = [ "ptcp:6653:[::1]" ]; + description = '' + Specify the controller targets. For the allowed options see <literal>man 8 ovs-vsctl</literal>. + ''; + }; - openFlowRules = mkOption { - type = types.lines; - default = ""; - example = '' - actions=normal - ''; - description = '' - OpenFlow rules to insert into the Open vSwitch. All <literal>openFlowRules</literal> are - loaded with <literal>ovs-ofctl</literal> within one atomic operation. - ''; - }; + openFlowRules = mkOption { + type = types.lines; + default = ""; + example = '' + actions=normal + ''; + description = '' + OpenFlow rules to insert into the Open vSwitch. All <literal>openFlowRules</literal> are + loaded with <literal>ovs-ofctl</literal> within one atomic operation. + ''; + }; + + extraOvsctlCmds = mkOption { + type = types.lines; + default = ""; + example = '' + set-fail-mode <switch_name> secure + set Bridge <switch_name> stp_enable=true + ''; + description = '' + Commands to manipulate the Open vSwitch database. Every line executed with <literal>ovs-vsctl</literal>. + All commands are bundled together with the operations for adding the interfaces + into one atomic operation. + ''; + }; - extraOvsctlCmds = mkOption { - type = types.lines; - default = ""; - example = '' - set-fail-mode <switch_name> secure - set Bridge <switch_name> stp_enable=true - ''; - description = '' - Commands to manipulate the Open vSwitch database. Every line executed with <literal>ovs-vsctl</literal>. - All commands are bundled together with the operations for adding the interfaces - into one atomic operation. - ''; }; - }; + }); }; @@ -499,25 +499,27 @@ in bridge's network interface. ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { + options = { - interfaces = mkOption { - example = [ "eth0" "eth1" ]; - type = types.listOf types.str; - description = - "The physical network interfaces connected by the bridge."; - }; + interfaces = mkOption { + example = [ "eth0" "eth1" ]; + type = types.listOf types.str; + description = + "The physical network interfaces connected by the bridge."; + }; + + rstp = mkOption { + example = true; + default = false; + type = types.bool; + description = "Whether the bridge interface should enable rstp."; + }; - rstp = mkOption { - example = true; - default = false; - type = types.bool; - description = "Whether the bridge interface should enable rstp."; }; - }; + }); }; @@ -538,65 +540,66 @@ in name specifying the name of the bond's network interface ''; - type = types.attrsOf types.optionSet; - - options = { - - interfaces = mkOption { - example = [ "enp4s0f0" "enp4s0f1" "wlan0" ]; - type = types.listOf types.str; - description = "The interfaces to bond together"; - }; + type = with types; attrsOf (submodule { - lacp_rate = mkOption { - default = null; - example = "fast"; - type = types.nullOr types.str; - description = '' - Option specifying the rate in which we'll ask our link partner - to transmit LACPDU packets in 802.3ad mode. - ''; - }; + options = { - miimon = mkOption { - default = null; - example = 100; - type = types.nullOr types.int; - description = '' - Miimon is the number of millisecond in between each round of polling - by the device driver for failed links. By default polling is not - enabled and the driver is trusted to properly detect and handle - failure scenarios. - ''; - }; + interfaces = mkOption { + example = [ "enp4s0f0" "enp4s0f1" "wlan0" ]; + type = types.listOf types.str; + description = "The interfaces to bond together"; + }; - mode = mkOption { - default = null; - example = "active-backup"; - type = types.nullOr types.str; - description = '' - The mode which the bond will be running. The default mode for - the bonding driver is balance-rr, optimizing for throughput. - More information about valid modes can be found at - https://www.kernel.org/doc/Documentation/networking/bonding.txt - ''; - }; + lacp_rate = mkOption { + default = null; + example = "fast"; + type = types.nullOr types.str; + description = '' + Option specifying the rate in which we'll ask our link partner + to transmit LACPDU packets in 802.3ad mode. + ''; + }; + + miimon = mkOption { + default = null; + example = 100; + type = types.nullOr types.int; + description = '' + Miimon is the number of millisecond in between each round of polling + by the device driver for failed links. By default polling is not + enabled and the driver is trusted to properly detect and handle + failure scenarios. + ''; + }; + + mode = mkOption { + default = null; + example = "active-backup"; + type = types.nullOr types.str; + description = '' + The mode which the bond will be running. The default mode for + the bonding driver is balance-rr, optimizing for throughput. + More information about valid modes can be found at + https://www.kernel.org/doc/Documentation/networking/bonding.txt + ''; + }; + + xmit_hash_policy = mkOption { + default = null; + example = "layer2+3"; + type = types.nullOr types.str; + description = '' + Selects the transmit hash policy to use for slave selection in + balance-xor, 802.3ad, and tlb modes. + ''; + }; - xmit_hash_policy = mkOption { - default = null; - example = "layer2+3"; - type = types.nullOr types.str; - description = '' - Selects the transmit hash policy to use for slave selection in - balance-xor, 802.3ad, and tlb modes. - ''; }; - }; + }); }; networking.macvlans = mkOption { - type = types.attrsOf types.optionSet; default = { }; example = literalExample { wan = { @@ -608,26 +611,28 @@ in This option allows you to define macvlan interfaces which should be automatically created. ''; - options = { - - interface = mkOption { - example = "enp4s0"; - type = types.str; - description = "The interface the macvlan will transmit packets through."; - }; + type = with types; attrsOf (submodule { + options = { + + interface = mkOption { + example = "enp4s0"; + type = types.str; + description = "The interface the macvlan will transmit packets through."; + }; + + mode = mkOption { + default = null; + type = types.nullOr types.str; + example = "vepa"; + description = "The mode of the macvlan device."; + }; - mode = mkOption { - default = null; - type = types.nullOr types.str; - example = "vepa"; - description = "The mode of the macvlan device."; }; - }; + }); }; networking.sits = mkOption { - type = types.attrsOf types.optionSet; default = { }; example = literalExample { hurricane = { @@ -644,46 +649,49 @@ in description = '' This option allows you to define 6-to-4 interfaces which should be automatically created. ''; - options = { - - remote = mkOption { - type = types.nullOr types.str; - default = null; - example = "10.0.0.1"; - description = '' - The address of the remote endpoint to forward traffic over. - ''; - }; - - local = mkOption { - type = types.nullOr types.str; - default = null; - example = "10.0.0.22"; - description = '' - The address of the local endpoint which the remote - side should send packets to. - ''; - }; - - ttl = mkOption { - type = types.nullOr types.int; - default = null; - example = 255; - description = '' - The time-to-live of the connection to the remote tunnel endpoint. - ''; - }; + type = with types; attrsOf (submodule { + options = { + + remote = mkOption { + type = types.nullOr types.str; + default = null; + example = "10.0.0.1"; + description = '' + The address of the remote endpoint to forward traffic over. + ''; + }; + + local = mkOption { + type = types.nullOr types.str; + default = null; + example = "10.0.0.22"; + description = '' + The address of the local endpoint which the remote + side should send packets to. + ''; + }; + + ttl = mkOption { + type = types.nullOr types.int; + default = null; + example = 255; + description = '' + The time-to-live of the connection to the remote tunnel endpoint. + ''; + }; + + dev = mkOption { + type = types.nullOr types.str; + default = null; + example = "enp4s0f0"; + description = '' + The underlying network device on which the tunnel resides. + ''; + }; - dev = mkOption { - type = types.nullOr types.str; - default = null; - example = "enp4s0f0"; - description = '' - The underlying network device on which the tunnel resides. - ''; }; - }; + }); }; networking.vlans = mkOption { @@ -706,23 +714,26 @@ in specifying the name of the vlan interface. ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { + options = { - id = mkOption { - example = 1; - type = types.int; - description = "The vlan identifier"; - }; + id = mkOption { + example = 1; + type = types.int; + description = "The vlan identifier"; + }; + + interface = mkOption { + example = "enp4s0"; + type = types.str; + description = "The interface the vlan will transmit packets through."; + }; - interface = mkOption { - example = "enp4s0"; - type = types.str; - description = "The interface the vlan will transmit packets through."; }; - }; + }); + }; networking.wlanInterfaces = mkOption { @@ -760,73 +771,69 @@ in would have to be created explicitly. ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { - - device = mkOption { - type = types.string; - example = "wlp6s0"; - description = "The name of the underlying hardware WLAN device as assigned by <literal>udev</literal>."; - }; - - type = mkOption { - type = types.string; - default = "managed"; - example = "ibss"; - description = '' - The type of the WLAN interface. The type has to be either <literal>managed</literal>, - <literal>ibss</literal>, <literal>monitor</literal>, <literal>mesh</literal> or <literal>wds</literal>. - Also, the type has to be supported by the underlying hardware of the device. - ''; - }; + options = { - meshID = mkOption { - type = types.nullOr types.string; - default = null; - description = "MeshID of interface with type <literal>mesh</literal>."; - }; + device = mkOption { + type = types.string; + example = "wlp6s0"; + description = "The name of the underlying hardware WLAN device as assigned by <literal>udev</literal>."; + }; - flags = mkOption { - type = types.nullOr types.string; - default = null; - example = "control"; - description = '' - Flags for interface of type <literal>monitor</literal>. The valid flags are: - none: no special flags - fcsfail: show frames with FCS errors - control: show control frames - otherbss: show frames from other BSSes - cook: use cooked mode - active: use active mode (ACK incoming unicast packets) - ''; - }; + type = mkOption { + type = types.enum [ "managed" "ibss" "monitor" "mesh" "wds" ]; + default = "managed"; + example = "ibss"; + description = '' + The type of the WLAN interface. + The type has to be supported by the underlying hardware of the device. + ''; + }; + + meshID = mkOption { + type = types.nullOr types.string; + default = null; + description = "MeshID of interface with type <literal>mesh</literal>."; + }; + + flags = mkOption { + type = with types; nullOr (enum [ "none" "fcsfail" "control" "otherbss" "cook" "active" ]); + default = null; + example = "control"; + description = '' + Flags for interface of type <literal>monitor</literal>. + ''; + }; + + fourAddr = mkOption { + type = types.nullOr types.bool; + default = null; + description = "Whether to enable <literal>4-address mode</literal> with type <literal>managed</literal>."; + }; + + mac = mkOption { + type = types.nullOr types.str; + default = null; + example = "02:00:00:00:00:01"; + description = '' + MAC address to use for the device. If <literal>null</literal>, then the MAC of the + underlying hardware WLAN device is used. + + INFO: Locally administered MAC addresses are of the form: + <itemizedlist> + <listitem><para>x2:xx:xx:xx:xx:xx</para></listitem> + <listitem><para>x6:xx:xx:xx:xx:xx</para></listitem> + <listitem><para>xA:xx:xx:xx:xx:xx</para></listitem> + <listitem><para>xE:xx:xx:xx:xx:xx</para></listitem> + </itemizedlist> + ''; + }; - fourAddr = mkOption { - type = types.nullOr types.bool; - default = null; - description = "Whether to enable <literal>4-address mode</literal> with type <literal>managed</literal>."; }; - mac = mkOption { - type = types.nullOr types.str; - default = null; - example = "02:00:00:00:00:01"; - description = '' - MAC address to use for the device. If <literal>null</literal>, then the MAC of the - underlying hardware WLAN device is used. - - INFO: Locally administered MAC addresses are of the form: - <itemizedlist> - <listitem><para>x2:xx:xx:xx:xx:xx</para></listitem> - <listitem><para>x6:xx:xx:xx:xx:xx</para></listitem> - <listitem><para>xA:xx:xx:xx:xx:xx</para></listitem> - <listitem><para>xE:xx:xx:xx:xx:xx</para></listitem> - </itemizedlist> - ''; - }; + }); - }; }; networking.useDHCP = mkOption { @@ -938,20 +945,23 @@ in domainname "${cfg.domain}" ''; - environment.etc = mkIf (cfg.hostId != null) - [ - { - target = "hostid"; - source = pkgs.runCommand "gen-hostid" {} '' - hi="${cfg.hostId}" - ${if pkgs.stdenv.isBigEndian then '' - echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > $out - '' else '' - echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > $out - ''} - ''; - } - ]; + environment.etc."hostid" = mkIf (cfg.hostId != null) + { source = pkgs.runCommand "gen-hostid" {} '' + hi="${cfg.hostId}" + ${if pkgs.stdenv.isBigEndian then '' + echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > $out + '' else '' + echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > $out + ''} + ''; + }; + + # static hostname configuration needed for hostnamectl and the + # org.freedesktop.hostname1 dbus service (both provided by systemd) + environment.etc."hostname" = mkIf (cfg.hostName != "") + { + text = cfg.hostName + "\n"; + }; environment.systemPackages = [ pkgs.host @@ -967,8 +977,10 @@ in ] ++ bridgeStp; + # The network-interfaces target is kept for backwards compatibility. + # New modules must NOT use it. systemd.targets."network-interfaces" = - { description = "All Network Interfaces"; + { description = "All Network Interfaces (deprecated)"; wantedBy = [ "network.target" ]; before = [ "network.target" ]; after = [ "network-pre.target" ]; @@ -991,12 +1003,17 @@ in ''; }; } // (listToAttrs (flip map interfaces (i: + let + deviceDependency = if config.boot.isContainer + then [] + else [ (subsystemDevice i.name) ]; + in nameValuePair "network-link-${i.name}" { description = "Link configuration of ${i.name}"; wantedBy = [ "network-interfaces.target" ]; before = [ "network-interfaces.target" ]; - bindsTo = [ (subsystemDevice i.name) ]; - after = [ (subsystemDevice i.name) "network-pre.target" ]; + bindsTo = deviceDependency; + after = [ "network-pre.target" ] ++ deviceDependency; path = [ pkgs.iproute ]; serviceConfig = { Type = "oneshot"; |