From 00022fbeda385d7b6ae2eee44f07eecfc6d92015 Mon Sep 17 00:00:00 2001 From: Bas van Dijk Date: Mon, 20 Apr 2020 12:00:23 +0200 Subject: [PATCH 1/4] lib: add the toHex and toBase utility functions `toHex` converts the given positive integer to a string of the hexadecimal representation of that integer. For example: ``` toHex 0 => "0" toHex 16 => "10" toHex 250 => "FA" ``` `toBase base i` converts the positive integer `i` to a list of it digits in the given `base`. For example: ``` toBase 10 123 => [ 1 2 3 ] toBase 2 6 => [ 1 1 0 ] toBase 16 250 => [ 15 10 ] ``` --- lib/default.nix | 2 +- lib/tests/misc.nix | 10 +++++++++ lib/trivial.nix | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/default.nix b/lib/default.nix index 7387e9d9f1f..a5c768ff407 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -67,7 +67,7 @@ let inherit (trivial) id const pipe concat or and bitAnd bitOr bitXor bitNot boolToString mergeAttrs flip mapNullable inNixShell min max importJSON warn info showWarnings nixpkgsVersion version mod compare - splitByAndCompare functionArgs setFunctionArgs isFunction; + splitByAndCompare functionArgs setFunctionArgs isFunction toHex toBase; inherit (fixedPoints) fix fix' converge extends composeExtensions makeExtensible makeExtensibleWithCustomName; inherit (attrsets) attrByPath hasAttrByPath setAttrByPath diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 36ddd186d7b..7d38b56bc21 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -102,6 +102,16 @@ runTests { expected = 9; }; + testToHex = { + expr = toHex 250; + expected = "FA"; + }; + + testToBase = { + expr = toBase 2 6; + expected = [ 1 1 0 ]; + }; + # STRINGS testConcatMapStrings = { diff --git a/lib/trivial.nix b/lib/trivial.nix index 5788dd435e5..1114e94b523 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -332,4 +332,55 @@ rec { */ isFunction = f: builtins.isFunction f || (f ? __functor && isFunction (f.__functor f)); + + /* Convert the given positive integer to a string of its hexadecimal + representation. For example: + + toHex 0 => "0" + + toHex 16 => "10" + + toHex 250 => "FA" + */ + toHex = i: + let + toHexDigit = d: + if d < 10 + then toString d + else + { + "10" = "A"; + "11" = "B"; + "12" = "C"; + "13" = "D"; + "14" = "E"; + "15" = "F"; + }.${toString d}; + in + lib.concatMapStrings toHexDigit (toBase 16 i); + + /* `toBase base i` converts the positive integer i to a list of its + digits in the given base. For example: + + toBase 10 123 => [ 1 2 3 ] + + toBase 2 6 => [ 1 1 0 ] + + toBase 16 250 => [ 15 10 ] + */ + toBase = base: i: + let + go = i: + if i < base + then [i] + else + let + r = i - ((i / base) * base); + q = (i - r) / base; + in + [r] ++ go q; + in + assert (base >= 2); + assert (i >= 0); + lib.reverseList (go i); } From 0410f5dff9ff952bfe129e522933c4c4ef6b3815 Mon Sep 17 00:00:00 2001 From: Bas van Dijk Date: Mon, 20 Apr 2020 12:01:24 +0200 Subject: [PATCH 2/4] nixos/tests: support up to 255 nodes in NixOS tests --- nixos/lib/qemu-flags.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nixos/lib/qemu-flags.nix b/nixos/lib/qemu-flags.nix index 859d9e975fe..b310914d36c 100644 --- a/nixos/lib/qemu-flags.nix +++ b/nixos/lib/qemu-flags.nix @@ -2,7 +2,11 @@ { pkgs }: let - zeroPad = n: if n < 10 then "0${toString n}" else toString n; + zeroPad = n: + pkgs.lib.optionalString (n < 16) "0" + + (if n > 255 + then throw "Can't have more than 255 nets or nodes!" + else pkgs.lib.toHex n); in { From e15815e885db42e642ed67527df76bbcc35f3e91 Mon Sep 17 00:00:00 2001 From: Bas van Dijk Date: Mon, 20 Apr 2020 22:06:02 +0200 Subject: [PATCH 3/4] nixos/tests/networking.nix: test the services.dhcpd4.machines option This modifies the `router` to not give out a range of IP addresses but only give out a fixed address based on the MAC address using the `services.dhcpd4.machines` option. To get access to the MAC address the `qemuNicMac` function is defined and exported from `qemu-flags.nix`. --- nixos/lib/qemu-flags.nix | 5 +++-- nixos/tests/networking.nix | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/nixos/lib/qemu-flags.nix b/nixos/lib/qemu-flags.nix index b310914d36c..4774fd23168 100644 --- a/nixos/lib/qemu-flags.nix +++ b/nixos/lib/qemu-flags.nix @@ -9,10 +9,11 @@ let else pkgs.lib.toHex n); in -{ +rec { + qemuNicMac = net: machine: "52:54:00:12:${zeroPad net}:${zeroPad machine}"; qemuNICFlags = nic: net: machine: - [ "-device virtio-net-pci,netdev=vlan${toString nic},mac=52:54:00:12:${zeroPad net}:${zeroPad machine}" + [ "-device virtio-net-pci,netdev=vlan${toString nic},mac=${qemuNicMac net machine}" "-netdev vde,id=vlan${toString nic},sock=$QEMU_VDE_SOCKET_${toString net}" ]; diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix index 3d8ab761a44..ebebbf90eb1 100644 --- a/nixos/tests/networking.nix +++ b/nixos/tests/networking.nix @@ -8,7 +8,9 @@ with import ../lib/testing-python.nix { inherit system pkgs; }; with pkgs.lib; let - router = { config, pkgs, ... }: + qemu-flags = import ../lib/qemu-flags.nix { inherit pkgs; }; + + router = { config, pkgs, lib, ... }: with pkgs.lib; let vlanIfs = range 1 (length config.virtualisation.vlans); @@ -31,16 +33,19 @@ let enable = true; interfaces = map (n: "eth${toString n}") vlanIfs; extraConfig = '' - authoritative; '' + flip concatMapStrings vlanIfs (n: '' subnet 192.168.${toString n}.0 netmask 255.255.255.0 { option routers 192.168.${toString n}.1; - # XXX: technically it's _not guaranteed_ that IP addresses will be - # issued from the first item in range onwards! We assume that in - # our tests however. - range 192.168.${toString n}.2 192.168.${toString n}.254; } - ''); + '') + ; + machines = lib.flip map vlanIfs (vlan: + { + hostName = "client${toString vlan}"; + ethernetAddress = qemu-flags.qemuNicMac vlan 1; + ipAddress = "192.168.${toString vlan}.2"; + } + ); }; services.radvd = { enable = true; From 6e7822b8f3e495e3c2c12b121ca81d8565298589 Mon Sep 17 00:00:00 2001 From: Bas van Dijk Date: Mon, 20 Jul 2020 13:14:19 +0200 Subject: [PATCH 4/4] lib: toHex -> toHexString & toBase -> toBaseDigits This makes the type of these functions more apparent from the name. --- lib/default.nix | 2 +- lib/tests/misc.nix | 8 ++++---- lib/trivial.nix | 20 ++++++++++---------- nixos/lib/qemu-flags.nix | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/default.nix b/lib/default.nix index a5c768ff407..43b9ab5930c 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -67,7 +67,7 @@ let inherit (trivial) id const pipe concat or and bitAnd bitOr bitXor bitNot boolToString mergeAttrs flip mapNullable inNixShell min max importJSON warn info showWarnings nixpkgsVersion version mod compare - splitByAndCompare functionArgs setFunctionArgs isFunction toHex toBase; + splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits; inherit (fixedPoints) fix fix' converge extends composeExtensions makeExtensible makeExtensibleWithCustomName; inherit (attrsets) attrByPath hasAttrByPath setAttrByPath diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 7d38b56bc21..b066f577f32 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -102,13 +102,13 @@ runTests { expected = 9; }; - testToHex = { - expr = toHex 250; + testToHexString = { + expr = toHexString 250; expected = "FA"; }; - testToBase = { - expr = toBase 2 6; + testToBaseDigits = { + expr = toBaseDigits 2 6; expected = [ 1 1 0 ]; }; diff --git a/lib/trivial.nix b/lib/trivial.nix index 1114e94b523..6eb1fb3a5b1 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -336,13 +336,13 @@ rec { /* Convert the given positive integer to a string of its hexadecimal representation. For example: - toHex 0 => "0" + toHexString 0 => "0" - toHex 16 => "10" + toHexString 16 => "10" - toHex 250 => "FA" + toHexString 250 => "FA" */ - toHex = i: + toHexString = i: let toHexDigit = d: if d < 10 @@ -357,18 +357,18 @@ rec { "15" = "F"; }.${toString d}; in - lib.concatMapStrings toHexDigit (toBase 16 i); + lib.concatMapStrings toHexDigit (toBaseDigits 16 i); - /* `toBase base i` converts the positive integer i to a list of its + /* `toBaseDigits base i` converts the positive integer i to a list of its digits in the given base. For example: - toBase 10 123 => [ 1 2 3 ] + toBaseDigits 10 123 => [ 1 2 3 ] - toBase 2 6 => [ 1 1 0 ] + toBaseDigits 2 6 => [ 1 1 0 ] - toBase 16 250 => [ 15 10 ] + toBaseDigits 16 250 => [ 15 10 ] */ - toBase = base: i: + toBaseDigits = base: i: let go = i: if i < base diff --git a/nixos/lib/qemu-flags.nix b/nixos/lib/qemu-flags.nix index 4774fd23168..0cf6977af4b 100644 --- a/nixos/lib/qemu-flags.nix +++ b/nixos/lib/qemu-flags.nix @@ -6,7 +6,7 @@ let pkgs.lib.optionalString (n < 16) "0" + (if n > 255 then throw "Can't have more than 255 nets or nodes!" - else pkgs.lib.toHex n); + else pkgs.lib.toHexString n); in rec {