diff options
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2405.section.md | 4 | ||||
-rw-r--r-- | nixos/lib/systemd-lib.nix | 4 | ||||
-rw-r--r-- | nixos/lib/systemd-network-units.nix | 3 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/programs/bash/bash.nix | 2 | ||||
-rw-r--r-- | nixos/modules/programs/nh.nix | 96 | ||||
-rw-r--r-- | nixos/modules/programs/slock.nix | 5 | ||||
-rw-r--r-- | nixos/modules/services/monitoring/grafana.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/networking/nsd.nix | 18 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/coder.nix | 20 | ||||
-rw-r--r-- | nixos/modules/system/boot/networkd.nix | 42 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/systemd-networkd-bridge.nix | 103 |
13 files changed, 283 insertions, 18 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 9fcfd6defc572..988632fc44349 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -153,6 +153,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - binfmt option for AppImage-run to support running [AppImage](https://appimage.org/)'s seamlessly on NixOS.. Available as [programs.appimage.binfmt](#opt-programs.appimage.binfmt). +- [nh](https://github.com/viperML/nh), yet another Nix CLI helper. Available as [programs.nh](#opt-programs.nh.enable). + - [ALVR](https://github.com/alvr-org/alvr), a VR desktop streamer. Available as [programs.alvr](#opt-programs.alvr.enable) - [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. @@ -596,3 +598,5 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `documentation.man.mandoc` now by default uses `MANPATH` to set the directories where mandoc will search for manual pages. This enables mandoc to find manual pages in Nix profiles. To set the manual search paths via the `mandoc.conf` configuration file like before, use `documentation.man.mandoc.settings.manpath` instead. + +- The `grafana-loki` package was updated to 3.0.0 which includes [breaking changes](https://github.com/grafana/loki/releases/tag/v3.0.0) diff --git a/nixos/lib/systemd-lib.nix b/nixos/lib/systemd-lib.nix index b67495609ff5a..198a710f052dd 100644 --- a/nixos/lib/systemd-lib.nix +++ b/nixos/lib/systemd-lib.nix @@ -148,6 +148,10 @@ in rec { optional (attr ? ${name} && !(min <= attr.${name} && max >= attr.${name})) "Systemd ${group} field `${name}' is outside the range [${toString min},${toString max}]"; + assertRangeOrOneOf = name: min: max: values: group: attr: + optional (attr ? ${name} && !((min <= attr.${name} && max >= attr.${name}) || elem attr.${name} values)) + "Systemd ${group} field `${name}' is not a value in range [${toString min},${toString max}], or one of ${toString values}"; + assertMinimum = name: min: group: attr: optional (attr ? ${name} && attr.${name} < min) "Systemd ${group} field `${name}' must be greater than or equal to ${toString min}"; diff --git a/nixos/lib/systemd-network-units.nix b/nixos/lib/systemd-network-units.nix index 986586a61a705..ae581495772a8 100644 --- a/nixos/lib/systemd-network-units.nix +++ b/nixos/lib/systemd-network-units.nix @@ -25,6 +25,9 @@ in { commonMatchText def + '' [NetDev] ${attrsToSection def.netdevConfig} + '' + optionalString (def.bridgeConfig != { }) '' + [Bridge] + ${attrsToSection def.bridgeConfig} '' + optionalString (def.vlanConfig != { }) '' [VLAN] ${attrsToSection def.vlanConfig} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 6c43cd06180ab..a45507d5ee3cd 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -233,6 +233,7 @@ ./programs/neovim.nix ./programs/nethoscope.nix ./programs/nexttrace.nix + ./programs/nh.nix ./programs/nix-index.nix ./programs/nix-ld.nix ./programs/nm-applet.nix diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix index 87fb29ed5bbe6..21ef8338d8dd8 100644 --- a/nixos/modules/programs/bash/bash.nix +++ b/nixos/modules/programs/bash/bash.nix @@ -30,7 +30,7 @@ in /* enable = mkOption { default = true; - description = lib.mdDoc '' + description = '' Whenever to configure Bash as an interactive shell. Note that this tries to make Bash the default {option}`users.defaultUserShell`, diff --git a/nixos/modules/programs/nh.nix b/nixos/modules/programs/nh.nix new file mode 100644 index 0000000000000..c42fb2fc724a7 --- /dev/null +++ b/nixos/modules/programs/nh.nix @@ -0,0 +1,96 @@ +{ config +, lib +, pkgs +, ... +}: +let + cfg = config.programs.nh; +in +{ + meta.maintainers = [ lib.maintainers.viperML ]; + + options.programs.nh = { + enable = lib.mkEnableOption "nh, yet another Nix CLI helper"; + + package = lib.mkPackageOption pkgs "nh" { }; + + flake = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = '' + The path that will be used for the `FLAKE` environment variable. + + `FLAKE` is used by nh as the default flake for performing actions, like `nh os switch`. + ''; + }; + + clean = { + enable = lib.mkEnableOption "periodic garbage collection with nh clean all"; + + dates = lib.mkOption { + type = lib.types.singleLineStr; + default = "weekly"; + description = '' + How often cleanup is performed. Passed to systemd.time + + The format is described in + {manpage}`systemd.time(7)`. + ''; + }; + + extraArgs = lib.mkOption { + type = lib.types.singleLineStr; + default = ""; + example = "--keep 5 --keep-since 3d"; + description = '' + Options given to nh clean when the service is run automatically. + + See `nh clean all --help` for more information. + ''; + }; + }; + }; + + config = { + warnings = + if (!(cfg.clean.enable -> !config.nix.gc.automatic)) then [ + "programs.nh.clean.enable and nix.gc.automatic are both enabled. Please use one or the other to avoid conflict." + ] else [ ]; + + assertions = [ + # Not strictly required but probably a good assertion to have + { + assertion = cfg.clean.enable -> cfg.enable; + message = "programs.nh.clean.enable requires programs.nh.enable"; + } + + { + assertion = (cfg.flake != null) -> !(lib.hasSuffix ".nix" cfg.flake); + message = "nh.flake must be a directory, not a nix file"; + } + ]; + + environment = lib.mkIf cfg.enable { + systemPackages = [ cfg.package ]; + variables = lib.mkIf (cfg.flake != null) { + FLAKE = cfg.flake; + }; + }; + + systemd = lib.mkIf cfg.clean.enable { + services.nh-clean = { + description = "Nh clean"; + script = "exec ${lib.getExe cfg.package} clean all ${cfg.clean.extraArgs}"; + startAt = cfg.clean.dates; + path = [ config.nix.package ]; + serviceConfig.Type = "oneshot"; + }; + + timers.nh-clean = { + timerConfig = { + Persistent = true; + }; + }; + }; + }; +} diff --git a/nixos/modules/programs/slock.nix b/nixos/modules/programs/slock.nix index ce80fcc5d4a8a..f39b4d5e9280e 100644 --- a/nixos/modules/programs/slock.nix +++ b/nixos/modules/programs/slock.nix @@ -16,16 +16,17 @@ in Whether to install slock screen locker with setuid wrapper. ''; }; + package = mkPackageOption pkgs "slock" {}; }; }; config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.slock ]; + environment.systemPackages = [ cfg.package ]; security.wrappers.slock = { setuid = true; owner = "root"; group = "root"; - source = "${pkgs.slock.out}/bin/slock"; + source = lib.getExe cfg.package; }; }; } diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix index e691cd64497f0..9d453c5394824 100644 --- a/nixos/modules/services/monitoring/grafana.nix +++ b/nixos/modules/services/monitoring/grafana.nix @@ -682,7 +682,7 @@ in # TODO Add "instrument_queries" option when upgrading to grafana 10.0 # instrument_queries = mkOption { - # description = lib.mdDoc "Set to `true` to add metrics and tracing for database queries."; + # description = "Set to `true` to add metrics and tracing for database queries."; # default = false; # type = types.bool; # }; diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix index 23bb92f09ab9a..b17416c1e3d34 100644 --- a/nixos/modules/services/networking/nsd.nix +++ b/nixos/modules/services/networking/nsd.nix @@ -152,9 +152,7 @@ let copyKeys = concatStrings (mapAttrsToList (keyName: keyOptions: '' secret=$(cat "${keyOptions.keyFile}") dest="${stateDir}/private/${keyName}" - echo " secret: \"$secret\"" > "$dest" - chown ${username}:${username} "$dest" - chmod 0400 "$dest" + install -m 0400 -o "${username}" -g "${username}" <(echo " secret: \"$secret\"") "$dest" '') cfg.keys); @@ -457,9 +455,7 @@ let dnssecTools = pkgs.bind.override { enablePython = true; }; signZones = optionalString dnssec '' - mkdir -p ${stateDir}/dnssec - chown ${username}:${username} ${stateDir}/dnssec - chmod 0600 ${stateDir}/dnssec + install -m 0600 -o "${username}" -g "${username}" -d "${stateDir}/dnssec" ${concatStrings (mapAttrsToList signZone dnssecZones)} ''; @@ -961,9 +957,9 @@ in rm -Rf "${stateDir}/private/" rm -Rf "${stateDir}/tmp/" - mkdir -m 0700 -p "${stateDir}/private" - mkdir -m 0700 -p "${stateDir}/tmp" - mkdir -m 0700 -p "${stateDir}/var" + install -dm 0700 -o "${username}" -g "${username}" "${stateDir}/private" + install -dm 0700 -o "${username}" -g "${username}" "${stateDir}/tmp" + install -dm 0700 -o "${username}" -g "${username}" "${stateDir}/var" cat > "${stateDir}/don't touch anything in here" << EOF Everything in this directory except NSD's state in var and dnssec @@ -971,10 +967,6 @@ in the nsd.service pre-start script. EOF - chown ${username}:${username} -R "${stateDir}/private" - chown ${username}:${username} -R "${stateDir}/tmp" - chown ${username}:${username} -R "${stateDir}/var" - rm -rf "${stateDir}/zones" cp -rL "${nsdEnv}/zones" "${stateDir}/zones" diff --git a/nixos/modules/services/web-apps/coder.nix b/nixos/modules/services/web-apps/coder.nix index 64805fd75248b..318a7c8fc1357 100644 --- a/nixos/modules/services/web-apps/coder.nix +++ b/nixos/modules/services/web-apps/coder.nix @@ -72,6 +72,23 @@ in { example = "*.coder.example.com"; }; + environment = { + extra = mkOption { + type = types.attrs; + description = "Extra environment variables to pass run Coder's server with. See Coder documentation."; + default = {}; + example = { + CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS = true; + CODER_OAUTH2_GITHUB_ALLOWED_ORGS = "your-org"; + }; + }; + file = mkOption { + type = types.nullOr types.path; + description = "Systemd environment file to add to Coder."; + default = null; + }; + }; + database = { createLocally = mkOption { type = types.bool; @@ -152,7 +169,7 @@ in { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - environment = { + environment = config.environment.extra // { CODER_ACCESS_URL = cfg.accessUrl; CODER_WILDCARD_ACCESS_URL = cfg.wildcardAccessUrl; CODER_PG_CONNECTION_URL = "user=${cfg.database.username} ${optionalString (cfg.database.password != null) "password=${cfg.database.password}"} database=${cfg.database.database} host=${cfg.database.host} ${optionalString (cfg.database.sslmode != null) "sslmode=${cfg.database.sslmode}"}"; @@ -177,6 +194,7 @@ in { ExecStart = "${cfg.package}/bin/coder server"; User = cfg.user; Group = cfg.group; + EnvironmentFile = lib.mkIf (cfg.environment.file != null) cfg.environment.file; }; }; diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index 0ddb7dcb651de..bb899c8d89994 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -186,6 +186,37 @@ let (assertNetdevMacAddress "MACAddress") ]; + sectionBridge = checkUnitConfig "Bridge" [ + (assertOnlyFields [ + "HelloTimeSec" + "MaxAgeSec" + "ForwardDelaySec" + "AgeingTimeSec" + "Priority" + "GroupForwardMask" + "DefaultPVID" + "MulticastQuerier" + "MulticastSnooping" + "VLANFiltering" + "VLANProtocol" + "STP" + "MulticastIGMPVersion" + ]) + (assertInt "HelloTimeSec") + (assertInt "MaxAgeSec") + (assertInt "ForwardDelaySec") + (assertInt "AgeingTimeSec") + (assertRange "Priority" 0 65535) + (assertRange "GroupForwardMask" 0 65535) + (assertRangeOrOneOf "DefaultPVID" 0 4094 ["none"]) + (assertValueOneOf "MulticastQuerier" boolValues) + (assertValueOneOf "MulticastSnooping" boolValues) + (assertValueOneOf "VLANFiltering" boolValues) + (assertValueOneOf "VLANProtocol" ["802.1q" "802.ad"]) + (assertValueOneOf "STP" boolValues) + (assertValueOneOf "MulticastIGMPVersion" [2 3]) + ]; + sectionVLAN = checkUnitConfig "VLAN" [ (assertOnlyFields [ "Id" @@ -1635,6 +1666,17 @@ let ''; }; + bridgeConfig = mkOption { + default = {}; + example = { STP = true; }; + type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionBridge; + description = '' + Each attribute in this set specifies an option in the + `[Bridge]` section of the unit. See + {manpage}`systemd.netdev(5)` for details. + ''; + }; + vlanConfig = mkOption { default = {}; example = { Id = 4; }; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index fd5a0186bdecf..fe02a97d6ff1e 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -900,6 +900,7 @@ in { systemd-lock-handler = runTestOn ["aarch64-linux" "x86_64-linux"] ./systemd-lock-handler.nix; systemd-machinectl = handleTest ./systemd-machinectl.nix {}; systemd-networkd = handleTest ./systemd-networkd.nix {}; + systemd-networkd-bridge = handleTest ./systemd-networkd-bridge.nix {}; systemd-networkd-dhcpserver = handleTest ./systemd-networkd-dhcpserver.nix {}; systemd-networkd-dhcpserver-static-leases = handleTest ./systemd-networkd-dhcpserver-static-leases.nix {}; systemd-networkd-ipv6-prefix-delegation = handleTest ./systemd-networkd-ipv6-prefix-delegation.nix {}; diff --git a/nixos/tests/systemd-networkd-bridge.nix b/nixos/tests/systemd-networkd-bridge.nix new file mode 100644 index 0000000000000..f1f8823e84205 --- /dev/null +++ b/nixos/tests/systemd-networkd-bridge.nix @@ -0,0 +1,103 @@ +/* This test ensures that we can configure spanning-tree protocol + across bridges using systemd-networkd. + + Test topology: + + 1 2 3 + node1 --- sw1 --- sw2 --- node2 + \ / + 4 \ / 5 + sw3 + | + 6 | + | + node3 + + where switches 1, 2, and 3 bridge their links and use STP, + and each link is labeled with the VLAN we are assigning it in + virtualisation.vlans. +*/ +with builtins; +let + commonConf = { + systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug"; + networking.useNetworkd = true; + networking.useDHCP = false; + networking.firewall.enable = false; + }; + + generateNodeConf = { octet, vlan }: + { lib, pkgs, config, ... }: { + imports = [ common/user-account.nix commonConf ]; + virtualisation.vlans = [ vlan ]; + systemd.network = { + enable = true; + networks = { + "30-eth" = { + matchConfig.Name = "eth1"; + address = [ "10.0.0.${toString octet}/24" ]; + }; + }; + }; + }; + + generateSwitchConf = vlans: + { lib, pkgs, config, ... }: { + imports = [ common/user-account.nix commonConf ]; + virtualisation.vlans = vlans; + systemd.network = { + enable = true; + netdevs = { + "40-br0" = { + netdevConfig = { + Kind = "bridge"; + Name = "br0"; + }; + bridgeConfig.STP = "yes"; + }; + }; + networks = { + "30-eth" = { + matchConfig.Name = "eth*"; + networkConfig.Bridge = "br0"; + }; + "40-br0" = { matchConfig.Name = "br0"; }; + }; + }; + }; +in import ./make-test-python.nix ({ pkgs, ... }: { + name = "networkd"; + meta = with pkgs.lib.maintainers; { maintainers = [ picnoir ]; }; + nodes = { + node1 = generateNodeConf { + octet = 1; + vlan = 1; + }; + node2 = generateNodeConf { + octet = 2; + vlan = 3; + }; + node3 = generateNodeConf { + octet = 3; + vlan = 6; + }; + sw1 = generateSwitchConf [ 1 2 4 ]; + sw2 = generateSwitchConf [ 2 3 5 ]; + sw3 = generateSwitchConf [ 4 5 6 ]; + }; + testScript = '' + network_nodes = [node1, node2, node3] + network_switches = [sw1, sw2, sw3] + start_all() + + for n in network_nodes + network_switches: + n.wait_for_unit("systemd-networkd-wait-online.service") + + node1.succeed("ping 10.0.0.2 -w 10 -c 1") + node1.succeed("ping 10.0.0.3 -w 10 -c 1") + node2.succeed("ping 10.0.0.1 -w 10 -c 1") + node2.succeed("ping 10.0.0.3 -w 10 -c 1") + node3.succeed("ping 10.0.0.1 -w 10 -c 1") + node3.succeed("ping 10.0.0.2 -w 10 -c 1") + ''; +}) |