From f8dbe5f376978947067283c6d03087d7948c50de Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 19 Apr 2015 21:05:12 +0200 Subject: systemd: Move networkd into separate modules The systemd module was getting rather bloated. --- nixos/modules/module-list.nix | 3 + nixos/modules/system/boot/networkd.nix | 663 +++++++++++++++++++++ nixos/modules/system/boot/resolved.nix | 36 ++ nixos/modules/system/boot/systemd-unit-options.nix | 464 +------------- nixos/modules/system/boot/systemd.nix | 232 +------ nixos/modules/system/boot/timesyncd.nix | 38 ++ 6 files changed, 744 insertions(+), 692 deletions(-) create mode 100644 nixos/modules/system/boot/networkd.nix create mode 100644 nixos/modules/system/boot/resolved.nix create mode 100644 nixos/modules/system/boot/timesyncd.nix (limited to 'nixos') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 0c9c12962659..5451ef821425 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -414,6 +414,9 @@ ./system/boot/stage-1.nix ./system/boot/stage-2.nix ./system/boot/systemd.nix + ./system/boot/networkd.nix + ./system/boot/resolved.nix + ./system/boot/timesyncd.nix ./system/boot/tmp.nix ./system/etc/etc.nix ./system/upstart/upstart.nix diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix new file mode 100644 index 000000000000..34a8b3fe0f95 --- /dev/null +++ b/nixos/modules/system/boot/networkd.nix @@ -0,0 +1,663 @@ +{ config, lib, pkgs, ... }: + +with lib; +with import ./systemd-unit-options.nix { inherit config lib; }; + +let + + cfg = config.systemd.network; + + checkLink = checkUnitConfig "Link" [ + (assertOnlyFields [ + "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name" + "MTUBytes" "BitsPerSecond" "Duplex" "WakeOnLan" + ]) + (assertValueOneOf "MACAddressPolicy" ["persistent" "random"]) + (assertMacAddress "MACAddress") + (assertValueOneOf "NamePolicy" [ + "kernel" "database" "onboard" "slot" "path" "mac" + ]) + (assertByteFormat "MTUBytes") + (assertByteFormat "BitsPerSecond") + (assertValueOneOf "Duplex" ["half" "full"]) + (assertValueOneOf "WakeOnLan" ["phy" "magic" "off"]) + ]; + + checkNetdev = checkUnitConfig "Netdev" [ + (assertOnlyFields [ + "Description" "Name" "Kind" "MTUBytes" "MACAddress" + ]) + (assertHasField "Name") + (assertHasField "Kind") + (assertValueOneOf "Kind" [ + "bridge" "bond" "vlan" "macvlan" "vxlan" "ipip" + "gre" "sit" "vti" "veth" "tun" "tap" "dummy" + ]) + (assertByteFormat "MTUBytes") + (assertMacAddress "MACAddress") + ]; + + checkVlan = checkUnitConfig "VLAN" [ + (assertOnlyFields ["Id"]) + (assertRange "Id" 0 4094) + ]; + + checkMacvlan = checkUnitConfig "MACVLAN" [ + (assertOnlyFields ["Mode"]) + (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"]) + ]; + + checkVxlan = checkUnitConfig "VXLAN" [ + (assertOnlyFields ["Id" "Group" "TOS" "TTL" "MacLearning"]) + (assertRange "TTL" 0 255) + (assertValueOneOf "MacLearning" boolValues) + ]; + + checkTunnel = checkUnitConfig "Tunnel" [ + (assertOnlyFields ["Local" "Remote" "TOS" "TTL" "DiscoverPathMTU"]) + (assertRange "TTL" 0 255) + (assertValueOneOf "DiscoverPathMTU" boolValues) + ]; + + checkPeer = checkUnitConfig "Peer" [ + (assertOnlyFields ["Name" "MACAddress"]) + (assertMacAddress "MACAddress") + ]; + + tunTapChecks = [ + (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "User" "Group"]) + (assertValueOneOf "OneQueue" boolValues) + (assertValueOneOf "MultiQueue" boolValues) + (assertValueOneOf "PacketInfo" boolValues) + ]; + + checkTun = checkUnitConfig "Tun" tunTapChecks; + + checkTap = checkUnitConfig "Tap" tunTapChecks; + + checkBond = checkUnitConfig "Bond" [ + (assertOnlyFields [ + "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec" + "UpDelaySec" "DownDelaySec" + ]) + (assertValueOneOf "Mode" [ + "balance-rr" "active-backup" "balance-xor" + "broadcast" "802.3ad" "balance-tlb" "balance-alb" + ]) + (assertValueOneOf "TransmitHashPolicy" [ + "layer2" "layer3+4" "layer2+3" "encap2+3" "802.3ad" "encap3+4" + ]) + (assertValueOneOf "LACPTransmitRate" ["slow" "fast"]) + ]; + + checkNetwork = checkUnitConfig "Network" [ + (assertOnlyFields [ + "Description" "DHCP" "DHCPServer" "IPv4LL" "IPv4LLRoute" + "LLMNR" "Domains" "Bridge" "Bond" + ]) + (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"]) + (assertValueOneOf "DHCPServer" boolValues) + (assertValueOneOf "IPv4LL" boolValues) + (assertValueOneOf "IPv4LLRoute" boolValues) + (assertValueOneOf "LLMNR" boolValues) + ]; + + checkAddress = checkUnitConfig "Address" [ + (assertOnlyFields ["Address" "Peer" "Broadcast" "Label"]) + (assertHasField "Address") + ]; + + checkRoute = checkUnitConfig "Route" [ + (assertOnlyFields ["Gateway" "Destination" "Metric"]) + (assertHasField "Gateway") + ]; + + checkDhcp = checkUnitConfig "DHCP" [ + (assertOnlyFields [ + "UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes" + "CriticalConnections" "VendorClassIdentifier" "RequestBroadcast" + "RouteMetric" + ]) + (assertValueOneOf "UseDNS" boolValues) + (assertValueOneOf "UseMTU" boolValues) + (assertValueOneOf "SendHostname" boolValues) + (assertValueOneOf "UseHostname" boolValues) + (assertValueOneOf "UseDomains" boolValues) + (assertValueOneOf "UseRoutes" boolValues) + (assertValueOneOf "CriticalConnections" boolValues) + (assertValueOneOf "RequestBroadcast" boolValues) + ]; + + commonNetworkOptions = { + + enable = mkOption { + default = false; + type = types.bool; + description = '' + Whether to manage network configuration using systemd-network. + ''; + }; + + matchConfig = mkOption { + default = {}; + example = { Name = "eth0"; }; + type = types.attrsOf unitOption; + description = '' + Each attribute in this set specifies an option in the + [Match] section of the unit. See + systemd.link5 + systemd.netdev5 + systemd.network5 + for details. + ''; + }; + + }; + + linkOptions = commonNetworkOptions // { + + linkConfig = mkOption { + default = {}; + example = { MACAddress = "00:ff:ee:aa:cc:dd"; }; + type = types.addCheck (types.attrsOf unitOption) checkLink; + description = '' + Each attribute in this set specifies an option in the + [Link] section of the unit. See + systemd.link + 5 for details. + ''; + }; + + }; + + netdevOptions = commonNetworkOptions // { + + netdevConfig = mkOption { + default = {}; + example = { Name = "mybridge"; Kind = "bridge"; }; + type = types.addCheck (types.attrsOf unitOption) checkNetdev; + description = '' + Each attribute in this set specifies an option in the + [Netdev] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + vlanConfig = mkOption { + default = {}; + example = { Id = "4"; }; + type = types.addCheck (types.attrsOf unitOption) checkVlan; + description = '' + Each attribute in this set specifies an option in the + [VLAN] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + macvlanConfig = mkOption { + default = {}; + example = { Mode = "private"; }; + type = types.addCheck (types.attrsOf unitOption) checkMacvlan; + description = '' + Each attribute in this set specifies an option in the + [MACVLAN] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + vxlanConfig = mkOption { + default = {}; + example = { Id = "4"; }; + type = types.addCheck (types.attrsOf unitOption) checkVxlan; + description = '' + Each attribute in this set specifies an option in the + [VXLAN] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + tunnelConfig = mkOption { + default = {}; + example = { Remote = "192.168.1.1"; }; + type = types.addCheck (types.attrsOf unitOption) checkTunnel; + description = '' + Each attribute in this set specifies an option in the + [Tunnel] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + peerConfig = mkOption { + default = {}; + example = { Name = "veth2"; }; + type = types.addCheck (types.attrsOf unitOption) checkPeer; + description = '' + Each attribute in this set specifies an option in the + [Peer] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + tunConfig = mkOption { + default = {}; + example = { User = "openvpn"; }; + type = types.addCheck (types.attrsOf unitOption) checkTun; + description = '' + Each attribute in this set specifies an option in the + [Tun] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + tapConfig = mkOption { + default = {}; + example = { User = "openvpn"; }; + type = types.addCheck (types.attrsOf unitOption) checkTap; + description = '' + Each attribute in this set specifies an option in the + [Tap] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + bondConfig = mkOption { + default = {}; + example = { Mode = "802.3ad"; }; + type = types.addCheck (types.attrsOf unitOption) checkBond; + description = '' + Each attribute in this set specifies an option in the + [Bond] section of the unit. See + systemd.netdev + 5 for details. + ''; + }; + + }; + + addressOptions = { + + addressConfig = mkOption { + default = {}; + example = { Address = "192.168.0.100/24"; }; + type = types.addCheck (types.attrsOf unitOption) checkAddress; + description = '' + Each attribute in this set specifies an option in the + [Address] section of the unit. See + systemd.network + 5 for details. + ''; + }; + + }; + + routeOptions = { + + routeConfig = mkOption { + default = {}; + example = { Gateway = "192.168.0.1"; }; + type = types.addCheck (types.attrsOf unitOption) checkRoute; + description = '' + Each attribute in this set specifies an option in the + [Route] section of the unit. See + systemd.network + 5 for details. + ''; + }; + + }; + + networkOptions = commonNetworkOptions // { + + networkConfig = mkOption { + default = {}; + example = { Description = "My Network"; }; + type = types.addCheck (types.attrsOf unitOption) checkNetwork; + description = '' + Each attribute in this set specifies an option in the + [Network] section of the unit. See + systemd.network + 5 for details. + ''; + }; + + dhcpConfig = mkOption { + default = {}; + example = { UseDNS = true; UseRoutes = true; }; + type = types.addCheck (types.attrsOf unitOption) checkDhcp; + description = '' + Each attribute in this set specifies an option in the + [DHCP] section of the unit. See + systemd.network + 5 for details. + ''; + }; + + name = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The name of the network interface to match against. + ''; + }; + + DHCP = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Whether to enable DHCP on the interfaces matched. + ''; + }; + + domains = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + description = '' + A list of domains to pass to the network config. + ''; + }; + + address = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + A list of addresses to be added to the network section of the + unit. See systemd.network + 5 for details. + ''; + }; + + gateway = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + A list of gateways to be added to the network section of the + unit. See systemd.network + 5 for details. + ''; + }; + + dns = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + A list of dns servers to be added to the network section of the + unit. See systemd.network + 5 for details. + ''; + }; + + ntp = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + A list of ntp servers to be added to the network section of the + unit. See systemd.network + 5 for details. + ''; + }; + + vlan = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + A list of vlan interfaces to be added to the network section of the + unit. See systemd.network + 5 for details. + ''; + }; + + macvlan = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + A list of macvlan interfaces to be added to the network section of the + unit. See systemd.network + 5 for details. + ''; + }; + + vxlan = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + A list of vxlan interfaces to be added to the network section of the + unit. See systemd.network + 5 for details. + ''; + }; + + tunnel = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + A list of tunnel interfaces to be added to the network section of the + unit. See systemd.network + 5 for details. + ''; + }; + + addresses = mkOption { + default = [ ]; + type = types.listOf types.optionSet; + options = [ addressOptions ]; + description = '' + A list of address sections to be added to the unit. See + systemd.network + 5 for details. + ''; + }; + + routes = mkOption { + default = [ ]; + type = types.listOf types.optionSet; + options = [ routeOptions ]; + description = '' + A list of route sections to be added to the unit. See + systemd.network + 5 for details. + ''; + }; + + }; + + networkConfig = { name, config, ... }: { + config = { + matchConfig = optionalAttrs (config.name != null) { + Name = config.name; + }; + networkConfig = optionalAttrs (config.DHCP != null) { + DHCP = config.DHCP; + } // optionalAttrs (config.domains != null) { + Domains = concatStringsSep " " config.domains; + }; + }; + }; + + linkToUnit = name: def: + { inherit (def) enable; + text = commonMatchText def + + '' + [Link] + ${attrsToSection def.linkConfig} + ''; + }; + + netdevToUnit = name: def: + { inherit (def) enable; + text = commonMatchText def + + '' + [NetDev] + ${attrsToSection def.netdevConfig} + + ${optionalString (def.vlanConfig != { }) '' + [VLAN] + ${attrsToSection def.vlanConfig} + + ''} + ${optionalString (def.macvlanConfig != { }) '' + [MACVLAN] + ${attrsToSection def.macvlanConfig} + + ''} + ${optionalString (def.vxlanConfig != { }) '' + [VXLAN] + ${attrsToSection def.vxlanConfig} + + ''} + ${optionalString (def.tunnelConfig != { }) '' + [Tunnel] + ${attrsToSection def.tunnelConfig} + + ''} + ${optionalString (def.peerConfig != { }) '' + [Peer] + ${attrsToSection def.peerConfig} + + ''} + ${optionalString (def.tunConfig != { }) '' + [Tun] + ${attrsToSection def.tunConfig} + + ''} + ${optionalString (def.tapConfig != { }) '' + [Tap] + ${attrsToSection def.tapConfig} + + ''} + ${optionalString (def.bondConfig != { }) '' + [Bond] + ${attrsToSection def.bondConfig} + + ''} + ''; + }; + + networkToUnit = name: def: + { inherit (def) enable; + text = commonMatchText def + + '' + [Network] + ${attrsToSection def.networkConfig} + ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)} + ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)} + ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)} + ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)} + ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)} + ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)} + ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)} + ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)} + + ${optionalString (def.dhcpConfig != { }) '' + [DHCP] + ${attrsToSection def.dhcpConfig} + + ''} + ${flip concatMapStrings def.addresses (x: '' + [Address] + ${attrsToSection x.addressConfig} + + '')} + ${flip concatMapStrings def.routes (x: '' + [Route] + ${attrsToSection x.routeConfig} + + '')} + ''; + }; + +in + +{ + + options = { + + systemd.network.enable = mkOption { + default = false; + type = types.bool; + description = '' + Whether to enable networkd or not. + ''; + }; + + systemd.network.links = mkOption { + default = {}; + type = types.attrsOf types.optionSet; + options = [ linkOptions ]; + description = "Definition of systemd network links."; + }; + + systemd.network.netdevs = mkOption { + default = {}; + type = types.attrsOf types.optionSet; + options = [ netdevOptions ]; + description = "Definition of systemd network devices."; + }; + + systemd.network.networks = mkOption { + default = {}; + type = types.attrsOf types.optionSet; + options = [ networkOptions networkConfig ]; + description = "Definition of systemd networks."; + }; + + systemd.network.units = mkOption { + description = "Definition of networkd units."; + default = {}; + type = types.attrsOf types.optionSet; + options = { name, config, ... }: + { options = concreteUnitOptions; + config = { + unit = mkDefault (makeUnit name config); + }; + }; + }; + + }; + + config = mkIf config.systemd.network.enable { + + systemd.network.units = + mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links + // mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs + // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks; + + users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network; + users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network; + + systemd.services.systemd-networkd = { + wantedBy = [ "multi-user.target" ]; + before = [ "network-interfaces.target" ]; + restartTriggers = [ config.environment.etc."systemd/network".source ]; + }; + + systemd.services.systemd-networkd-wait-online = { + before = [ "network-online.target" "ip-up.target" ]; + wantedBy = [ "network-online.target" "ip-up.target" ]; + }; + + systemd.services."systemd-network-wait-online@" = { + description = "Wait for Network Interface %I to be Configured"; + conflicts = [ "shutdown.target" ]; + requisite = [ "systemd-networkd.service" ]; + after = [ "systemd-networkd.service" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I"; + }; + }; + + services.resolved.enable = mkDefault true; + services.timesyncd.enable = mkDefault config.services.ntp.enable; + + }; + +} diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix new file mode 100644 index 000000000000..cdc76d59f9a8 --- /dev/null +++ b/nixos/modules/system/boot/resolved.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + + options = { + + services.resolved.enable = mkOption { + default = false; + type = types.bool; + description = '' + Whether to enable the systemd DNS resolver daemon. + ''; + }; + + }; + + config = mkIf config.services.resolved.enable { + + systemd.services.systemd-resolved = { + wantedBy = [ "multi-user.target" ]; + restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ]; + }; + + environment.etc."systemd/resolved.conf".text = '' + [Resolve] + DNS=${concatStringsSep " " config.networking.nameservers} + ''; + + users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve; + users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve; + + }; + +} diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix index 2f4786c78966..785634cbf66a 100644 --- a/nixos/modules/system/boot/systemd-unit-options.nix +++ b/nixos/modules/system/boot/systemd-unit-options.nix @@ -62,126 +62,7 @@ let ]) ]; - checkLink = checkUnitConfig "Link" [ - (assertOnlyFields [ - "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name" - "MTUBytes" "BitsPerSecond" "Duplex" "WakeOnLan" - ]) - (assertValueOneOf "MACAddressPolicy" ["persistent" "random"]) - (assertMacAddress "MACAddress") - (assertValueOneOf "NamePolicy" [ - "kernel" "database" "onboard" "slot" "path" "mac" - ]) - (assertByteFormat "MTUBytes") - (assertByteFormat "BitsPerSecond") - (assertValueOneOf "Duplex" ["half" "full"]) - (assertValueOneOf "WakeOnLan" ["phy" "magic" "off"]) - ]; - - checkNetdev = checkUnitConfig "Netdev" [ - (assertOnlyFields [ - "Description" "Name" "Kind" "MTUBytes" "MACAddress" - ]) - (assertHasField "Name") - (assertHasField "Kind") - (assertValueOneOf "Kind" [ - "bridge" "bond" "vlan" "macvlan" "vxlan" "ipip" - "gre" "sit" "vti" "veth" "tun" "tap" "dummy" - ]) - (assertByteFormat "MTUBytes") - (assertMacAddress "MACAddress") - ]; - - checkVlan = checkUnitConfig "VLAN" [ - (assertOnlyFields ["Id"]) - (assertRange "Id" 0 4094) - ]; - - checkMacvlan = checkUnitConfig "MACVLAN" [ - (assertOnlyFields ["Mode"]) - (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"]) - ]; - - checkVxlan = checkUnitConfig "VXLAN" [ - (assertOnlyFields ["Id" "Group" "TOS" "TTL" "MacLearning"]) - (assertRange "TTL" 0 255) - (assertValueOneOf "MacLearning" boolValues) - ]; - - checkTunnel = checkUnitConfig "Tunnel" [ - (assertOnlyFields ["Local" "Remote" "TOS" "TTL" "DiscoverPathMTU"]) - (assertRange "TTL" 0 255) - (assertValueOneOf "DiscoverPathMTU" boolValues) - ]; - - checkPeer = checkUnitConfig "Peer" [ - (assertOnlyFields ["Name" "MACAddress"]) - (assertMacAddress "MACAddress") - ]; - - tunTapChecks = [ - (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "User" "Group"]) - (assertValueOneOf "OneQueue" boolValues) - (assertValueOneOf "MultiQueue" boolValues) - (assertValueOneOf "PacketInfo" boolValues) - ]; - - checkTun = checkUnitConfig "Tun" tunTapChecks; - - checkTap = checkUnitConfig "Tap" tunTapChecks; - - checkBond = checkUnitConfig "Bond" [ - (assertOnlyFields [ - "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec" - "UpDelaySec" "DownDelaySec" - ]) - (assertValueOneOf "Mode" [ - "balance-rr" "active-backup" "balance-xor" - "broadcast" "802.3ad" "balance-tlb" "balance-alb" - ]) - (assertValueOneOf "TransmitHashPolicy" [ - "layer2" "layer3+4" "layer2+3" "encap2+3" "802.3ad" "encap3+4" - ]) - (assertValueOneOf "LACPTransmitRate" ["slow" "fast"]) - ]; - - checkNetwork = checkUnitConfig "Network" [ - (assertOnlyFields [ - "Description" "DHCP" "DHCPServer" "IPv4LL" "IPv4LLRoute" - "LLMNR" "Domains" "Bridge" "Bond" - ]) - (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"]) - (assertValueOneOf "DHCPServer" boolValues) - (assertValueOneOf "IPv4LL" boolValues) - (assertValueOneOf "IPv4LLRoute" boolValues) - (assertValueOneOf "LLMNR" boolValues) - ]; - - checkAddress = checkUnitConfig "Address" [ - (assertOnlyFields ["Address" "Peer" "Broadcast" "Label"]) - (assertHasField "Address") - ]; - - checkRoute = checkUnitConfig "Route" [ - (assertOnlyFields ["Gateway" "Destination" "Metric"]) - (assertHasField "Gateway") - ]; - - checkDhcp = checkUnitConfig "DHCP" [ - (assertOnlyFields [ - "UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes" - "CriticalConnections" "VendorClassIdentifier" "RequestBroadcast" - "RouteMetric" - ]) - (assertValueOneOf "UseDNS" boolValues) - (assertValueOneOf "UseMTU" boolValues) - (assertValueOneOf "SendHostname" boolValues) - (assertValueOneOf "UseHostname" boolValues) - (assertValueOneOf "UseDomains" boolValues) - (assertValueOneOf "UseRoutes" boolValues) - (assertValueOneOf "CriticalConnections" boolValues) - (assertValueOneOf "RequestBroadcast" boolValues) - ]; +in rec { unitOption = mkOptionType { name = "systemd option"; @@ -195,8 +76,6 @@ let else mergeOneOption loc defs'; }; -in rec { - sharedOptions = { enable = mkOption { @@ -619,345 +498,4 @@ in rec { targetOptions = commonUnitOptions; - commonNetworkOptions = { - - enable = mkOption { - default = true; - type = types.bool; - description = '' - If set to false, this unit will be a symlink to - /dev/null. - ''; - }; - - matchConfig = mkOption { - default = {}; - example = { Name = "eth0"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Match] section of the unit. See - systemd.link5 - systemd.netdev5 - systemd.network5 - for details. - ''; - }; - - }; - - linkOptions = commonNetworkOptions // { - - linkConfig = mkOption { - default = {}; - example = { MACAddress = "00:ff:ee:aa:cc:dd"; }; - type = types.addCheck (types.attrsOf unitOption) checkLink; - description = '' - Each attribute in this set specifies an option in the - [Link] section of the unit. See - systemd.link - 5 for details. - ''; - }; - - }; - - netdevOptions = commonNetworkOptions // { - - netdevConfig = mkOption { - default = {}; - example = { Name = "mybridge"; Kind = "bridge"; }; - type = types.addCheck (types.attrsOf unitOption) checkNetdev; - description = '' - Each attribute in this set specifies an option in the - [Netdev] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - vlanConfig = mkOption { - default = {}; - example = { Id = "4"; }; - type = types.addCheck (types.attrsOf unitOption) checkVlan; - description = '' - Each attribute in this set specifies an option in the - [VLAN] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - macvlanConfig = mkOption { - default = {}; - example = { Mode = "private"; }; - type = types.addCheck (types.attrsOf unitOption) checkMacvlan; - description = '' - Each attribute in this set specifies an option in the - [MACVLAN] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - vxlanConfig = mkOption { - default = {}; - example = { Id = "4"; }; - type = types.addCheck (types.attrsOf unitOption) checkVxlan; - description = '' - Each attribute in this set specifies an option in the - [VXLAN] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - tunnelConfig = mkOption { - default = {}; - example = { Remote = "192.168.1.1"; }; - type = types.addCheck (types.attrsOf unitOption) checkTunnel; - description = '' - Each attribute in this set specifies an option in the - [Tunnel] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - peerConfig = mkOption { - default = {}; - example = { Name = "veth2"; }; - type = types.addCheck (types.attrsOf unitOption) checkPeer; - description = '' - Each attribute in this set specifies an option in the - [Peer] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - tunConfig = mkOption { - default = {}; - example = { User = "openvpn"; }; - type = types.addCheck (types.attrsOf unitOption) checkTun; - description = '' - Each attribute in this set specifies an option in the - [Tun] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - tapConfig = mkOption { - default = {}; - example = { User = "openvpn"; }; - type = types.addCheck (types.attrsOf unitOption) checkTap; - description = '' - Each attribute in this set specifies an option in the - [Tap] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - bondConfig = mkOption { - default = {}; - example = { Mode = "802.3ad"; }; - type = types.addCheck (types.attrsOf unitOption) checkBond; - description = '' - Each attribute in this set specifies an option in the - [Bond] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - }; - - addressOptions = { - - addressConfig = mkOption { - default = {}; - example = { Address = "192.168.0.100/24"; }; - type = types.addCheck (types.attrsOf unitOption) checkAddress; - description = '' - Each attribute in this set specifies an option in the - [Address] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - }; - - routeOptions = { - - routeConfig = mkOption { - default = {}; - example = { Gateway = "192.168.0.1"; }; - type = types.addCheck (types.attrsOf unitOption) checkRoute; - description = '' - Each attribute in this set specifies an option in the - [Route] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - }; - - networkOptions = commonNetworkOptions // { - - networkConfig = mkOption { - default = {}; - example = { Description = "My Network"; }; - type = types.addCheck (types.attrsOf unitOption) checkNetwork; - description = '' - Each attribute in this set specifies an option in the - [Network] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - dhcpConfig = mkOption { - default = {}; - example = { UseDNS = true; UseRoutes = true; }; - type = types.addCheck (types.attrsOf unitOption) checkDhcp; - description = '' - Each attribute in this set specifies an option in the - [DHCP] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - name = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - The name of the network interface to match against. - ''; - }; - - DHCP = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Whether to enable DHCP on the interfaces matched. - ''; - }; - - domains = mkOption { - type = types.nullOr (types.listOf types.str); - default = null; - description = '' - A list of domains to pass to the network config. - ''; - }; - - address = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of addresses to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - gateway = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of gateways to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - dns = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of dns servers to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - ntp = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of ntp servers to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - vlan = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of vlan interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - macvlan = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of macvlan interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - vxlan = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of vxlan interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - tunnel = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of tunnel interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - addresses = mkOption { - default = [ ]; - type = types.listOf types.optionSet; - options = [ addressOptions ]; - description = '' - A list of address sections to be added to the unit. See - systemd.network - 5 for details. - ''; - }; - - routes = mkOption { - default = [ ]; - type = types.listOf types.optionSet; - options = [ routeOptions ]; - description = '' - A list of route sections to be added to the unit. See - systemd.network - 5 for details. - ''; - }; - - }; - } diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 29c449d4d0be..4bd412014a54 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -301,19 +301,6 @@ let }; }; - networkConfig = { name, config, ... }: { - config = { - matchConfig = optionalAttrs (config.name != null) { - Name = config.name; - }; - networkConfig = optionalAttrs (config.DHCP != null) { - DHCP = config.DHCP; - } // optionalAttrs (config.domains != null) { - Domains = concatStringsSep " " config.domains; - }; - }; - }; - toOption = x: if x == true then "true" else if x == false then "false" @@ -412,98 +399,6 @@ let ${attrsToSection def.matchConfig} ''; - linkToUnit = name: def: - { inherit (def) enable; - text = commonMatchText def + - '' - [Link] - ${attrsToSection def.linkConfig} - ''; - }; - - netdevToUnit = name: def: - { inherit (def) enable; - text = commonMatchText def + - '' - [NetDev] - ${attrsToSection def.netdevConfig} - - ${optionalString (def.vlanConfig != { }) '' - [VLAN] - ${attrsToSection def.vlanConfig} - - ''} - ${optionalString (def.macvlanConfig != { }) '' - [MACVLAN] - ${attrsToSection def.macvlanConfig} - - ''} - ${optionalString (def.vxlanConfig != { }) '' - [VXLAN] - ${attrsToSection def.vxlanConfig} - - ''} - ${optionalString (def.tunnelConfig != { }) '' - [Tunnel] - ${attrsToSection def.tunnelConfig} - - ''} - ${optionalString (def.peerConfig != { }) '' - [Peer] - ${attrsToSection def.peerConfig} - - ''} - ${optionalString (def.tunConfig != { }) '' - [Tun] - ${attrsToSection def.tunConfig} - - ''} - ${optionalString (def.tapConfig != { }) '' - [Tap] - ${attrsToSection def.tapConfig} - - ''} - ${optionalString (def.bondConfig != { }) '' - [Bond] - ${attrsToSection def.bondConfig} - - ''} - ''; - }; - - networkToUnit = name: def: - { inherit (def) enable; - text = commonMatchText def + - '' - [Network] - ${attrsToSection def.networkConfig} - ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)} - ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)} - ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)} - ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)} - ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)} - ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)} - ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)} - ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)} - - ${optionalString (def.dhcpConfig != { }) '' - [DHCP] - ${attrsToSection def.dhcpConfig} - - ''} - ${flip concatMapStrings def.addresses (x: '' - [Address] - ${attrsToSection x.addressConfig} - - '')} - ${flip concatMapStrings def.routes (x: '' - [Route] - ${attrsToSection x.routeConfig} - - '')} - ''; - }; - generateUnits = type: units: upstreamUnits: upstreamWants: pkgs.runCommand "${type}-units" { preferLocalBuild = true; } '' mkdir -p $out @@ -683,47 +578,6 @@ in ''; }; - systemd.network.enable = mkOption { - default = false; - type = types.bool; - description = '' - Whether to enable networkd or not. - ''; - }; - - systemd.network.links = mkOption { - default = {}; - type = types.attrsOf types.optionSet; - options = [ linkOptions ]; - description = "Definition of systemd network links."; - }; - - systemd.network.netdevs = mkOption { - default = {}; - type = types.attrsOf types.optionSet; - options = [ netdevOptions ]; - description = "Definition of systemd network devices."; - }; - - systemd.network.networks = mkOption { - default = {}; - type = types.attrsOf types.optionSet; - options = [ networkOptions networkConfig ]; - description = "Definition of systemd networks."; - }; - - systemd.network.units = mkOption { - description = "Definition of networkd units."; - default = {}; - type = types.attrsOf types.optionSet; - options = { name, config, ... }: - { options = concreteUnitOptions; - config = { - unit = mkDefault (makeUnit name config); - }; - }; - }; - systemd.defaultUnit = mkOption { default = "multi-user.target"; type = types.str; @@ -807,22 +661,6 @@ in ''; }; - services.resolved.enable = mkOption { - default = false; - type = types.bool; - description = '' - Enables the systemd dns resolver daemon. - ''; - }; - - services.timesyncd.enable = mkOption { - default = false; - type = types.bool; - description = '' - Enables the systemd ntp client daemon. - ''; - }; - systemd.tmpfiles.rules = mkOption { type = types.listOf types.str; default = []; @@ -886,7 +724,7 @@ in ###### implementation - config = mkMerge [ { + config = { warnings = concatLists (mapAttrsToList (name: service: optional (service.serviceConfig.Type or "" == "oneshot" && service.serviceConfig.Restart or "no" != "no") @@ -899,6 +737,7 @@ in environment.etc."systemd/system".source = generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants; + # FIXME: move to networkd.nix. environment.etc."systemd/network".source = generateUnits "network" cfg.network.units [] []; @@ -979,11 +818,6 @@ in (v: let n = escapeSystemdPath v.where; in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); - systemd.network.units = - mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.network.links - // mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.network.netdevs - // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.network.networks; - systemd.user.units = mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets @@ -1006,15 +840,6 @@ in users.extraUsers.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway; users.extraGroups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway; - users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network; - users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network; - - users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve; - users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve; - - users.extraUsers.systemd-timesync.uid = config.ids.uids.systemd-timesync; - users.extraGroups.systemd-timesync.gid = config.ids.gids.systemd-timesync; - # Generate timer units for all services that have a ‘startAt’ value. systemd.timers = mapAttrs (name: service: @@ -1053,57 +878,6 @@ in systemd.services.systemd-remount-fs.restartIfChanged = false; systemd.services.systemd-journal-flush.restartIfChanged = false; - } - (mkIf config.systemd.network.enable { - systemd.services.systemd-networkd = { - wantedBy = [ "multi-user.target" ]; - before = [ "network-interfaces.target" ]; - restartTriggers = [ config.environment.etc."systemd/network".source ]; - }; - - systemd.services.systemd-networkd-wait-online = { - before = [ "network-online.target" "ip-up.target" ]; - wantedBy = [ "network-online.target" "ip-up.target" ]; - }; - - systemd.services."systemd-network-wait-online@" = { - description = "Wait for Network Interface %I to be Configured"; - conflicts = [ "shutdown.target" ]; - requisite = [ "systemd-networkd.service" ]; - after = [ "systemd-networkd.service" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I"; - }; - }; - - services.resolved.enable = mkDefault true; - services.timesyncd.enable = mkDefault config.services.ntp.enable; - }) - (mkIf config.services.resolved.enable { - systemd.services.systemd-resolved = { - wantedBy = [ "multi-user.target" ]; - restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ]; - }; - - environment.etc."systemd/resolved.conf".text = '' - [Resolve] - DNS=${concatStringsSep " " config.networking.nameservers} - ''; - }) - (mkIf config.services.timesyncd.enable { - systemd.services.systemd-timesyncd = { - wantedBy = [ "sysinit.target" ]; - restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ]; - }; - - environment.etc."systemd/timesyncd.conf".text = '' - [Time] - NTP=${concatStringsSep " " config.services.ntp.servers} - ''; + }; - systemd.services.ntpd.enable = false; - }) - ]; } diff --git a/nixos/modules/system/boot/timesyncd.nix b/nixos/modules/system/boot/timesyncd.nix new file mode 100644 index 000000000000..fd4be47ad721 --- /dev/null +++ b/nixos/modules/system/boot/timesyncd.nix @@ -0,0 +1,38 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + + options = { + + services.timesyncd.enable = mkOption { + default = false; + type = types.bool; + description = '' + Enables the systemd NTP client daemon. + ''; + }; + + }; + + config = mkIf config.services.timesyncd.enable { + + systemd.services.systemd-timesyncd = { + wantedBy = [ "sysinit.target" ]; + restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ]; + }; + + environment.etc."systemd/timesyncd.conf".text = '' + [Time] + NTP=${concatStringsSep " " config.services.ntp.servers} + ''; + + systemd.services.ntpd.enable = false; + + users.extraUsers.systemd-timesync.uid = config.ids.uids.systemd-timesync; + users.extraGroups.systemd-timesync.gid = config.ids.gids.systemd-timesync; + + }; + +} -- cgit 1.4.1