Merge pull request #292472 from Janik-Haag/networkmanager-tests
nixosTests.networking: refactor and add NetworkManager support
This commit is contained in:
commit
59742f6f72
6 changed files with 224 additions and 41 deletions
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
|
@ -232,10 +232,12 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
||||||
/nixos/modules/services/networking/babeld.nix @mweinelt
|
/nixos/modules/services/networking/babeld.nix @mweinelt
|
||||||
/nixos/modules/services/networking/kea.nix @mweinelt
|
/nixos/modules/services/networking/kea.nix @mweinelt
|
||||||
/nixos/modules/services/networking/knot.nix @mweinelt
|
/nixos/modules/services/networking/knot.nix @mweinelt
|
||||||
|
nixos/modules/services/networking/networkmanager.nix @Janik-Haag
|
||||||
/nixos/modules/services/monitoring/prometheus/exporters/kea.nix @mweinelt
|
/nixos/modules/services/monitoring/prometheus/exporters/kea.nix @mweinelt
|
||||||
/nixos/tests/babeld.nix @mweinelt
|
/nixos/tests/babeld.nix @mweinelt
|
||||||
/nixos/tests/kea.nix @mweinelt
|
/nixos/tests/kea.nix @mweinelt
|
||||||
/nixos/tests/knot.nix @mweinelt
|
/nixos/tests/knot.nix @mweinelt
|
||||||
|
/nixos/tests/networking/* @Janik-Haag
|
||||||
|
|
||||||
# Web servers
|
# Web servers
|
||||||
/doc/packages/nginx.section.md @raitobezarius
|
/doc/packages/nginx.section.md @raitobezarius
|
||||||
|
|
|
@ -587,6 +587,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
|
||||||
|
|
||||||
- The `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399).
|
- The `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399).
|
||||||
|
|
||||||
|
- The `services.networkmanager.extraConfig` was renamed to `services.networkmanager.settings` and was changed to use the ini type instead of using a multiline string.
|
||||||
|
|
||||||
- The module `services.github-runner` has been removed. To configure a single GitHub Actions Runner refer to `services.github-runners.*`. Note that this will trigger a new runner registration.
|
- The module `services.github-runner` has been removed. To configure a single GitHub Actions Runner refer to `services.github-runners.*`. Note that this will trigger a new runner registration.
|
||||||
|
|
||||||
- The `services.slskd` has been refactored to include more configuation options in
|
- The `services.slskd` has been refactored to include more configuation options in
|
||||||
|
|
|
@ -10,49 +10,31 @@ let
|
||||||
|
|
||||||
enableIwd = cfg.wifi.backend == "iwd";
|
enableIwd = cfg.wifi.backend == "iwd";
|
||||||
|
|
||||||
mkValue = v:
|
configAttrs = lib.recursiveUpdate {
|
||||||
if v == true then "yes"
|
main = {
|
||||||
else if v == false then "no"
|
|
||||||
else if lib.isInt v then toString v
|
|
||||||
else v;
|
|
||||||
|
|
||||||
mkSection = name: attrs: ''
|
|
||||||
[${name}]
|
|
||||||
${
|
|
||||||
lib.concatStringsSep "\n"
|
|
||||||
(lib.mapAttrsToList
|
|
||||||
(k: v: "${k}=${mkValue v}")
|
|
||||||
(lib.filterAttrs
|
|
||||||
(k: v: v != null)
|
|
||||||
attrs))
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
configFile = pkgs.writeText "NetworkManager.conf" (lib.concatStringsSep "\n" [
|
|
||||||
(mkSection "main" {
|
|
||||||
plugins = "keyfile";
|
plugins = "keyfile";
|
||||||
inherit (cfg) dhcp dns;
|
inherit (cfg) dhcp dns;
|
||||||
# If resolvconf is disabled that means that resolv.conf is managed by some other module.
|
# If resolvconf is disabled that means that resolv.conf is managed by some other module.
|
||||||
rc-manager =
|
rc-manager =
|
||||||
if config.networking.resolvconf.enable then "resolvconf"
|
if config.networking.resolvconf.enable then "resolvconf"
|
||||||
else "unmanaged";
|
else "unmanaged";
|
||||||
})
|
};
|
||||||
(mkSection "keyfile" {
|
keyfile = {
|
||||||
unmanaged-devices =
|
unmanaged-devices =
|
||||||
if cfg.unmanaged == [ ] then null
|
if cfg.unmanaged == [ ] then null
|
||||||
else lib.concatStringsSep ";" cfg.unmanaged;
|
else lib.concatStringsSep ";" cfg.unmanaged;
|
||||||
})
|
};
|
||||||
(mkSection "logging" {
|
logging = {
|
||||||
audit = config.security.audit.enable;
|
audit = config.security.audit.enable;
|
||||||
level = cfg.logLevel;
|
level = cfg.logLevel;
|
||||||
})
|
};
|
||||||
(mkSection "connection" cfg.connectionConfig)
|
connection = cfg.connectionConfig;
|
||||||
(mkSection "device" {
|
device = {
|
||||||
"wifi.scan-rand-mac-address" = cfg.wifi.scanRandMacAddress;
|
"wifi.scan-rand-mac-address" = cfg.wifi.scanRandMacAddress;
|
||||||
"wifi.backend" = cfg.wifi.backend;
|
"wifi.backend" = cfg.wifi.backend;
|
||||||
})
|
};
|
||||||
cfg.extraConfig
|
} cfg.settings;
|
||||||
]);
|
configFile = ini.generate "NetworkManager.conf" configAttrs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[network-manager]
|
[network-manager]
|
||||||
|
@ -145,7 +127,7 @@ in
|
||||||
{
|
{
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
maintainers = teams.freedesktop.members;
|
maintainers = teams.freedesktop.members ++ [ lib.maintainers.janik ];
|
||||||
};
|
};
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
|
@ -185,11 +167,11 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
extraConfig = mkOption {
|
settings = mkOption {
|
||||||
type = types.lines;
|
type = ini.type;
|
||||||
default = "";
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
Configuration appended to the generated NetworkManager.conf.
|
Configuration added to the generated NetworkManager.conf, note that you can overwrite settings with this.
|
||||||
Refer to
|
Refer to
|
||||||
[
|
[
|
||||||
https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html
|
https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html
|
||||||
|
@ -471,8 +453,28 @@ in
|
||||||
imports = [
|
imports = [
|
||||||
(mkRenamedOptionModule
|
(mkRenamedOptionModule
|
||||||
[ "networking" "networkmanager" "packages" ]
|
[ "networking" "networkmanager" "packages" ]
|
||||||
[ "networking" "networkmanager" "plugins" ])
|
[ "networking" "networkmanager" "plugins" ]
|
||||||
(mkRenamedOptionModule [ "networking" "networkmanager" "useDnsmasq" ] [ "networking" "networkmanager" "dns" ])
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "networking" "networkmanager" "useDnsmasq" ]
|
||||||
|
[ "networking" "networkmanager" "dns" ]
|
||||||
|
)
|
||||||
|
(mkRemovedOptionModule [ "networking" "networkmanager" "extraConfig" ] ''
|
||||||
|
This option was removed in favour of `networking.networkmanager.settings`,
|
||||||
|
which accepts structured nix-code equivalent to the ini
|
||||||
|
and allows for overriding settings.
|
||||||
|
Example patch:
|
||||||
|
```patch
|
||||||
|
networking.networkmanager = {
|
||||||
|
- extraConfig = '''
|
||||||
|
- [main]
|
||||||
|
- no-auto-default=*
|
||||||
|
- '''
|
||||||
|
+ extraConfig.main.no-auto-default = "*";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
''
|
||||||
|
)
|
||||||
(mkRemovedOptionModule [ "networking" "networkmanager" "enableFccUnlock" ] ''
|
(mkRemovedOptionModule [ "networking" "networkmanager" "enableFccUnlock" ] ''
|
||||||
This option was removed, because using bundled FCC unlock scripts is risky,
|
This option was removed, because using bundled FCC unlock scripts is risky,
|
||||||
might conflict with vendor-provided unlock scripts, and should
|
might conflict with vendor-provided unlock scripts, and should
|
||||||
|
|
|
@ -599,6 +599,7 @@ in {
|
||||||
netdata = handleTest ./netdata.nix {};
|
netdata = handleTest ./netdata.nix {};
|
||||||
networking.scripted = handleTest ./networking/networkd-and-scripted.nix { networkd = false; };
|
networking.scripted = handleTest ./networking/networkd-and-scripted.nix { networkd = false; };
|
||||||
networking.networkd = handleTest ./networking/networkd-and-scripted.nix { networkd = true; };
|
networking.networkd = handleTest ./networking/networkd-and-scripted.nix { networkd = true; };
|
||||||
|
networking.networkmanager = handleTest ./networking/networkmanager.nix {};
|
||||||
netbox_3_6 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_6; };
|
netbox_3_6 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_6; };
|
||||||
netbox_3_7 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_7; };
|
netbox_3_7 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_7; };
|
||||||
netbox-upgrade = handleTest ./web-apps/netbox-upgrade.nix {};
|
netbox-upgrade = handleTest ./web-apps/netbox-upgrade.nix {};
|
||||||
|
|
172
nixos/tests/networking/networkmanager.nix
Normal file
172
nixos/tests/networking/networkmanager.nix
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
{ system ? builtins.currentSystem
|
||||||
|
, config ? {}
|
||||||
|
, pkgs ? import ../.. { inherit system config; }
|
||||||
|
}:
|
||||||
|
|
||||||
|
with import ../../lib/testing-python.nix { inherit system pkgs; };
|
||||||
|
|
||||||
|
let
|
||||||
|
lib = pkgs.lib;
|
||||||
|
# this is intended as a client test since you shouldn't use NetworkManager for a router or server
|
||||||
|
# so using systemd-networkd for the router vm is fine in these tests.
|
||||||
|
router = import ./router.nix { networkd = true; };
|
||||||
|
qemu-common = import ../../lib/qemu-common.nix { inherit (pkgs) lib pkgs; };
|
||||||
|
clientConfig = extraConfig: lib.recursiveUpdate {
|
||||||
|
networking.useDHCP = false;
|
||||||
|
|
||||||
|
# Make sure that only NetworkManager configures the interface
|
||||||
|
networking.interfaces = lib.mkForce {
|
||||||
|
eth1 = {};
|
||||||
|
};
|
||||||
|
networking.networkmanager = {
|
||||||
|
enable = true;
|
||||||
|
# this is needed so NM doesn't generate 'Wired Connection' profiles and instead uses the default one
|
||||||
|
settings.main.no-auto-default = "*";
|
||||||
|
ensureProfiles.profiles.default = {
|
||||||
|
connection = {
|
||||||
|
id = "default";
|
||||||
|
type = "ethernet";
|
||||||
|
interface-name = "eth1";
|
||||||
|
autoconnect = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} extraConfig;
|
||||||
|
testCases = {
|
||||||
|
static = {
|
||||||
|
name = "static";
|
||||||
|
nodes = {
|
||||||
|
inherit router;
|
||||||
|
client = clientConfig {
|
||||||
|
networking.networkmanager.ensureProfiles.profiles.default = {
|
||||||
|
ipv4.method = "manual";
|
||||||
|
ipv4.addresses = "192.168.1.42/24";
|
||||||
|
ipv4.gateway = "192.168.1.1";
|
||||||
|
ipv6.method = "manual";
|
||||||
|
ipv6.addresses = "fd00:1234:5678:1::42/64";
|
||||||
|
ipv6.gateway = "fd00:1234:5678:1::1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
router.systemctl("start network-online.target")
|
||||||
|
router.wait_for_unit("network-online.target")
|
||||||
|
client.wait_for_unit("NetworkManager.service")
|
||||||
|
|
||||||
|
with subtest("Wait until we have an ip address on each interface"):
|
||||||
|
client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'")
|
||||||
|
client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'")
|
||||||
|
|
||||||
|
with subtest("Test if icmp echo works"):
|
||||||
|
client.wait_until_succeeds("ping -c 1 192.168.3.1")
|
||||||
|
client.wait_until_succeeds("ping -c 1 fd00:1234:5678:3::1")
|
||||||
|
router.wait_until_succeeds("ping -c 1 192.168.1.42")
|
||||||
|
router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::42")
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
auto = {
|
||||||
|
name = "auto";
|
||||||
|
nodes = {
|
||||||
|
inherit router;
|
||||||
|
client = clientConfig {
|
||||||
|
networking.networkmanager.ensureProfiles.profiles.default = {
|
||||||
|
ipv4.method = "auto";
|
||||||
|
ipv6.method = "auto";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
router.systemctl("start network-online.target")
|
||||||
|
router.wait_for_unit("network-online.target")
|
||||||
|
client.wait_for_unit("NetworkManager.service")
|
||||||
|
|
||||||
|
with subtest("Wait until we have an ip address on each interface"):
|
||||||
|
client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'")
|
||||||
|
client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'")
|
||||||
|
|
||||||
|
with subtest("Test if icmp echo works"):
|
||||||
|
client.wait_until_succeeds("ping -c 1 192.168.1.1")
|
||||||
|
client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1")
|
||||||
|
router.wait_until_succeeds("ping -c 1 192.168.1.2")
|
||||||
|
router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::2")
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
dns = {
|
||||||
|
name = "dns";
|
||||||
|
nodes = {
|
||||||
|
inherit router;
|
||||||
|
dynamic = clientConfig {
|
||||||
|
networking.networkmanager.ensureProfiles.profiles.default = {
|
||||||
|
ipv4.method = "auto";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static = clientConfig {
|
||||||
|
networking.networkmanager.ensureProfiles.profiles.default = {
|
||||||
|
ipv4 = {
|
||||||
|
method = "auto";
|
||||||
|
ignore-auto-dns = "true";
|
||||||
|
dns = "10.10.10.10";
|
||||||
|
dns-search = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
router.systemctl("start network-online.target")
|
||||||
|
router.wait_for_unit("network-online.target")
|
||||||
|
dynamic.wait_for_unit("NetworkManager.service")
|
||||||
|
static.wait_for_unit("NetworkManager.service")
|
||||||
|
|
||||||
|
dynamic.wait_until_succeeds("cat /etc/resolv.conf | grep -q '192.168.1.1'")
|
||||||
|
static.wait_until_succeeds("cat /etc/resolv.conf | grep -q '10.10.10.10'")
|
||||||
|
static.wait_until_fails("cat /etc/resolv.conf | grep -q '192.168.1.1'")
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
dispatcherScripts = {
|
||||||
|
name = "dispatcherScripts";
|
||||||
|
nodes.client = clientConfig {
|
||||||
|
networking.networkmanager.dispatcherScripts = [{
|
||||||
|
type = "pre-up";
|
||||||
|
source = pkgs.writeText "testHook" ''
|
||||||
|
touch /tmp/dispatcher-scripts-are-working
|
||||||
|
'';
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
client.wait_for_unit("NetworkManager.service")
|
||||||
|
client.wait_until_succeeds("stat /tmp/dispatcher-scripts-are-working")
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
envsubst = {
|
||||||
|
name = "envsubst";
|
||||||
|
nodes.client = let
|
||||||
|
# you should never write secrets in to your nixos configuration, please use tools like sops-nix or agenix
|
||||||
|
secretFile = pkgs.writeText "my-secret.env" ''
|
||||||
|
MY_SECRET_IP=fd00:1234:5678:1::23/64
|
||||||
|
'';
|
||||||
|
in clientConfig {
|
||||||
|
networking.networkmanager.ensureProfiles.environmentFiles = [ secretFile ];
|
||||||
|
networking.networkmanager.ensureProfiles.profiles.default = {
|
||||||
|
ipv6.method = "manual";
|
||||||
|
ipv6.addresses = "$MY_SECRET_IP";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
client.wait_for_unit("NetworkManager.service")
|
||||||
|
client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'")
|
||||||
|
client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::23")
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in lib.mapAttrs (lib.const (attrs: makeTest (attrs // {
|
||||||
|
name = "${attrs.name}-Networking-NetworkManager";
|
||||||
|
meta = {
|
||||||
|
maintainers = with lib.maintainers; [ janik ];
|
||||||
|
};
|
||||||
|
|
||||||
|
}))) testCases
|
|
@ -50,6 +50,7 @@
|
||||||
, mobile-broadband-provider-info
|
, mobile-broadband-provider-info
|
||||||
, runtimeShell
|
, runtimeShell
|
||||||
, buildPackages
|
, buildPackages
|
||||||
|
, nixosTests
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -203,6 +204,9 @@ stdenv.mkDerivation rec {
|
||||||
attrPath = "networkmanager";
|
attrPath = "networkmanager";
|
||||||
versionPolicy = "odd-unstable";
|
versionPolicy = "odd-unstable";
|
||||||
};
|
};
|
||||||
|
tests = {
|
||||||
|
inherit (nixosTests.networking) networkmanager;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
|
|
Loading…
Reference in a new issue