mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-14 06:00:33 +03:00
nixos/tests: don't include switch-to-configuration in DUT by default (#340445)
This commit is contained in:
commit
a9c0a2e2a1
14 changed files with 149 additions and 172 deletions
|
@ -3,7 +3,7 @@
|
||||||
# even in `inheritParentConfig = false` specialisations.
|
# even in `inheritParentConfig = false` specialisations.
|
||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
let
|
let
|
||||||
inherit (lib) mkForce;
|
inherit (lib) mkDefault mkForce;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -22,6 +22,11 @@ in
|
||||||
label = mkForce "test";
|
label = mkForce "test";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
({ config, ... }: {
|
||||||
|
# Don't pull in switch-to-configuration by default, except when specialisations are involved.
|
||||||
|
# This is mostly a Hydra optimization, so we don't rebuild all the tests every time switch-to-configuration-ng changes.
|
||||||
|
key = "no-switch-to-configuration";
|
||||||
|
system.switch.enable = mkDefault (config.isSpecialisation || config.specialisation != {});
|
||||||
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,5 @@ with lib;
|
||||||
{
|
{
|
||||||
boot.loader.grub.device = mkOverride 0 "nodev";
|
boot.loader.grub.device = mkOverride 0 "nodev";
|
||||||
specialisation = mkOverride 0 {};
|
specialisation = mkOverride 0 {};
|
||||||
|
isSpecialisation = mkOverride 0 true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,12 @@ let
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
isSpecialisation = mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
internal = true;
|
||||||
|
default = false;
|
||||||
|
description = "Whether this system is a specialisation of another.";
|
||||||
|
};
|
||||||
|
|
||||||
specialisation = mkOption {
|
specialisation = mkOption {
|
||||||
default = { };
|
default = { };
|
||||||
|
|
|
@ -7,25 +7,24 @@ import ./make-test-python.nix ({ lib, ... }:
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
default = {
|
machine = {
|
||||||
services.chrony.enable = true;
|
services.chrony.enable = true;
|
||||||
};
|
|
||||||
graphene-hardened = {
|
specialisation.hardened.configuration = {
|
||||||
services.chrony.enable = true;
|
services.chrony.enableMemoryLocking = true;
|
||||||
services.chrony.enableMemoryLocking = true;
|
environment.memoryAllocator.provider = "graphene-hardened";
|
||||||
environment.memoryAllocator.provider = "graphene-hardened";
|
# dhcpcd privsep is incompatible with graphene-hardened
|
||||||
# dhcpcd privsep is incompatible with graphene-hardened
|
networking.useNetworkd = true;
|
||||||
networking.useNetworkd = true;
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = {nodes, ...} : let
|
testScript = ''
|
||||||
graphene-hardened = nodes.graphene-hardened.system.build.toplevel;
|
machine.start()
|
||||||
in ''
|
machine.wait_for_unit('multi-user.target')
|
||||||
default.start()
|
machine.succeed('systemctl is-active chronyd.service')
|
||||||
default.wait_for_unit('multi-user.target')
|
machine.succeed('/run/booted-system/specialisation/hardened/bin/switch-to-configuration test')
|
||||||
default.succeed('systemctl is-active chronyd.service')
|
machine.succeed('systemctl restart chronyd.service')
|
||||||
default.succeed('${graphene-hardened}/bin/switch-to-configuration test')
|
machine.wait_for_unit('chronyd.service')
|
||||||
default.succeed('systemctl is-active chronyd.service')
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,71 +1,57 @@
|
||||||
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
let
|
{
|
||||||
client_base = {
|
|
||||||
containers.test1 = {
|
|
||||||
autoStart = true;
|
|
||||||
config = {
|
|
||||||
environment.etc.check.text = "client_base";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# prevent make-test-python.nix to change IP
|
|
||||||
networking.interfaces = {
|
|
||||||
eth1.ipv4.addresses = lib.mkOverride 0 [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
name = "containers-reloadable";
|
name = "containers-reloadable";
|
||||||
meta = {
|
meta = {
|
||||||
maintainers = with lib.maintainers; [ danbst ];
|
maintainers = with lib.maintainers; [ danbst ];
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
client = { ... }: {
|
machine = { lib, ... }: {
|
||||||
imports = [ client_base ];
|
containers.test1 = {
|
||||||
};
|
autoStart = true;
|
||||||
|
config.environment.etc.check.text = "client_base";
|
||||||
client_c1 = { lib, ... }: {
|
|
||||||
imports = [ client_base ];
|
|
||||||
|
|
||||||
containers.test1.config = {
|
|
||||||
environment.etc.check.text = lib.mkForce "client_c1";
|
|
||||||
services.httpd.enable = true;
|
|
||||||
services.httpd.adminAddr = "nixos@example.com";
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
client_c2 = { lib, ... }: {
|
|
||||||
imports = [ client_base ];
|
|
||||||
|
|
||||||
containers.test1.config = {
|
# prevent make-test-python.nix to change IP
|
||||||
environment.etc.check.text = lib.mkForce "client_c2";
|
networking.interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [ ];
|
||||||
services.nginx.enable = true;
|
|
||||||
|
specialisation.c1.configuration = {
|
||||||
|
containers.test1.config = {
|
||||||
|
environment.etc.check.text = lib.mkForce "client_c1";
|
||||||
|
services.httpd.enable = true;
|
||||||
|
services.httpd.adminAddr = "nixos@example.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
specialisation.c2.configuration = {
|
||||||
|
containers.test1.config = {
|
||||||
|
environment.etc.check.text = lib.mkForce "client_c2";
|
||||||
|
services.nginx.enable = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = {nodes, ...}: let
|
testScript = ''
|
||||||
c1System = nodes.client_c1.config.system.build.toplevel;
|
machine.start()
|
||||||
c2System = nodes.client_c2.config.system.build.toplevel;
|
machine.wait_for_unit("default.target")
|
||||||
in ''
|
|
||||||
client.start()
|
|
||||||
client.wait_for_unit("default.target")
|
|
||||||
|
|
||||||
assert "client_base" in client.succeed("nixos-container run test1 cat /etc/check")
|
assert "client_base" in machine.succeed("nixos-container run test1 cat /etc/check")
|
||||||
|
|
||||||
with subtest("httpd is available after activating config1"):
|
with subtest("httpd is available after activating config1"):
|
||||||
client.succeed(
|
machine.succeed(
|
||||||
"${c1System}/bin/switch-to-configuration test >&2",
|
"/run/booted-system/specialisation/c1/bin/switch-to-configuration test >&2",
|
||||||
"[[ $(nixos-container run test1 cat /etc/check) == client_c1 ]] >&2",
|
"[[ $(nixos-container run test1 cat /etc/check) == client_c1 ]] >&2",
|
||||||
"systemctl status httpd -M test1 >&2",
|
"systemctl status httpd -M test1 >&2",
|
||||||
)
|
)
|
||||||
|
|
||||||
with subtest("httpd is not available any longer after switching to config2"):
|
with subtest("httpd is not available any longer after switching to config2"):
|
||||||
client.succeed(
|
machine.succeed(
|
||||||
"${c2System}/bin/switch-to-configuration test >&2",
|
"/run/booted-system/specialisation/c2/bin/switch-to-configuration test >&2",
|
||||||
"[[ $(nixos-container run test1 cat /etc/check) == client_c2 ]] >&2",
|
"[[ $(nixos-container run test1 cat /etc/check) == client_c2 ]] >&2",
|
||||||
"systemctl status nginx -M test1 >&2",
|
"systemctl status nginx -M test1 >&2",
|
||||||
)
|
)
|
||||||
client.fail("systemctl status httpd -M test1 >&2")
|
machine.fail("systemctl status httpd -M test1 >&2")
|
||||||
'';
|
'';
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,20 +1,4 @@
|
||||||
let
|
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
client_base = {
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
|
|
||||||
containers.webserver = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostBridge = "br0";
|
|
||||||
config = {
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.interfaces.eth0.ipv4.addresses = [
|
|
||||||
{ address = "192.168.1.122"; prefixLength = 24; }
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in import ./make-test-python.nix ({ pkgs, lib, ... }:
|
|
||||||
{
|
{
|
||||||
name = "containers-restart_networking";
|
name = "containers-restart_networking";
|
||||||
meta = {
|
meta = {
|
||||||
|
@ -22,46 +6,55 @@ in import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
client = { lib, ... }: client_base // {
|
client = {
|
||||||
virtualisation.vlans = [ 1 ];
|
virtualisation.vlans = [ 1 ];
|
||||||
|
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
|
||||||
|
containers.webserver = {
|
||||||
|
autoStart = true;
|
||||||
|
privateNetwork = true;
|
||||||
|
hostBridge = "br0";
|
||||||
|
config = {
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
networking.interfaces.eth0.ipv4.addresses = [
|
||||||
|
{ address = "192.168.1.122"; prefixLength = 24; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
networking.bridges.br0 = {
|
networking.bridges.br0 = {
|
||||||
interfaces = [];
|
interfaces = [];
|
||||||
rstp = false;
|
rstp = false;
|
||||||
};
|
};
|
||||||
networking.interfaces = {
|
|
||||||
eth1.ipv4.addresses = lib.mkOverride 0 [ ];
|
networking.interfaces.br0.ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
|
||||||
br0.ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
|
|
||||||
|
specialisation.eth1.configuration = {
|
||||||
|
networking.bridges.br0.interfaces = [ "eth1" ];
|
||||||
|
networking.interfaces = {
|
||||||
|
eth1.ipv4.addresses = lib.mkForce [ ];
|
||||||
|
eth1.ipv6.addresses = lib.mkForce [ ];
|
||||||
|
br0.ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
specialisation.eth1-rstp.configuration = {
|
||||||
client_eth1 = { lib, ... }: client_base // {
|
networking.bridges.br0 = {
|
||||||
networking.bridges.br0 = {
|
interfaces = [ "eth1" ];
|
||||||
interfaces = [ "eth1" ];
|
rstp = lib.mkForce true;
|
||||||
rstp = false;
|
};
|
||||||
};
|
|
||||||
networking.interfaces = {
|
networking.interfaces = {
|
||||||
eth1.ipv4.addresses = lib.mkOverride 0 [ ];
|
eth1.ipv4.addresses = lib.mkForce [ ];
|
||||||
br0.ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
|
eth1.ipv6.addresses = lib.mkForce [ ];
|
||||||
};
|
br0.ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
|
||||||
};
|
};
|
||||||
client_eth1_rstp = { lib, ... }: client_base // {
|
|
||||||
networking.bridges.br0 = {
|
|
||||||
interfaces = [ "eth1" ];
|
|
||||||
rstp = true;
|
|
||||||
};
|
|
||||||
networking.interfaces = {
|
|
||||||
eth1.ipv4.addresses = lib.mkOverride 0 [ ];
|
|
||||||
br0.ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = {nodes, ...}: let
|
testScript = ''
|
||||||
originalSystem = nodes.client.config.system.build.toplevel;
|
|
||||||
eth1_bridged = nodes.client_eth1.config.system.build.toplevel;
|
|
||||||
eth1_rstp = nodes.client_eth1_rstp.config.system.build.toplevel;
|
|
||||||
in ''
|
|
||||||
client.start()
|
client.start()
|
||||||
|
|
||||||
client.wait_for_unit("default.target")
|
client.wait_for_unit("default.target")
|
||||||
|
@ -75,7 +68,7 @@ in import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
|
|
||||||
with subtest("Bridged configuration without STP preserves connectivity"):
|
with subtest("Bridged configuration without STP preserves connectivity"):
|
||||||
client.succeed(
|
client.succeed(
|
||||||
"${eth1_bridged}/bin/switch-to-configuration test >&2"
|
"/run/booted-system/specialisation/eth1/bin/switch-to-configuration test >&2"
|
||||||
)
|
)
|
||||||
|
|
||||||
client.succeed(
|
client.succeed(
|
||||||
|
@ -87,7 +80,7 @@ in import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
|
|
||||||
# activating rstp needs another service, therefore the bridge will restart and the container will lose its connectivity
|
# activating rstp needs another service, therefore the bridge will restart and the container will lose its connectivity
|
||||||
# with subtest("Bridged configuration with STP"):
|
# with subtest("Bridged configuration with STP"):
|
||||||
# client.succeed("${eth1_rstp}/bin/switch-to-configuration test >&2")
|
# client.succeed("/run/booted-system/specialisation/eth1-rstp/bin/switch-to-configuration test >&2")
|
||||||
# client.execute("ip -4 a >&2")
|
# client.execute("ip -4 a >&2")
|
||||||
# client.execute("ip l >&2")
|
# client.execute("ip l >&2")
|
||||||
#
|
#
|
||||||
|
@ -100,7 +93,7 @@ in import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
|
|
||||||
with subtest("Reverting to initial configuration preserves connectivity"):
|
with subtest("Reverting to initial configuration preserves connectivity"):
|
||||||
client.succeed(
|
client.succeed(
|
||||||
"${originalSystem}/bin/switch-to-configuration test >&2"
|
"/run/booted-system/bin/switch-to-configuration test >&2"
|
||||||
)
|
)
|
||||||
|
|
||||||
client.succeed("ping 192.168.1.122 -c 1 -n >&2")
|
client.succeed("ping 192.168.1.122 -c 1 -n >&2")
|
||||||
|
|
|
@ -14,17 +14,10 @@ import ./make-test-python.nix ( { pkgs, nftables, ... } : {
|
||||||
networking.nftables.enable = nftables;
|
networking.nftables.enable = nftables;
|
||||||
services.httpd.enable = true;
|
services.httpd.enable = true;
|
||||||
services.httpd.adminAddr = "foo@example.org";
|
services.httpd.adminAddr = "foo@example.org";
|
||||||
};
|
|
||||||
|
|
||||||
# Dummy configuration to check whether firewall.service will be honored
|
specialisation.different-config.configuration = {
|
||||||
# during system activation. This only needs to be different to the
|
networking.firewall.rejectPackets = true;
|
||||||
# original walled configuration so that there is a change in the service
|
};
|
||||||
# file.
|
|
||||||
walled2 =
|
|
||||||
{ ... }:
|
|
||||||
{ networking.firewall.enable = true;
|
|
||||||
networking.firewall.rejectPackets = true;
|
|
||||||
networking.nftables.enable = nftables;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
attacker =
|
attacker =
|
||||||
|
@ -36,7 +29,6 @@ import ./make-test-python.nix ( { pkgs, nftables, ... } : {
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = { nodes, ... }: let
|
testScript = { nodes, ... }: let
|
||||||
newSystem = nodes.walled2.system.build.toplevel;
|
|
||||||
unit = if nftables then "nftables" else "firewall";
|
unit = if nftables then "nftables" else "firewall";
|
||||||
in ''
|
in ''
|
||||||
start_all()
|
start_all()
|
||||||
|
@ -62,7 +54,7 @@ import ./make-test-python.nix ( { pkgs, nftables, ... } : {
|
||||||
|
|
||||||
# Check whether activation of a new configuration reloads the firewall.
|
# Check whether activation of a new configuration reloads the firewall.
|
||||||
walled.succeed(
|
walled.succeed(
|
||||||
"${newSystem}/bin/switch-to-configuration test 2>&1 | grep -qF ${unit}.service"
|
"/run/booted-system/specialisation/different-config/bin/switch-to-configuration test 2>&1 | grep -qF ${unit}.service"
|
||||||
)
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|
|
@ -635,6 +635,7 @@ let
|
||||||
(python3.withPackages (p: [ p.mistune ]))
|
(python3.withPackages (p: [ p.mistune ]))
|
||||||
shared-mime-info
|
shared-mime-info
|
||||||
sudo
|
sudo
|
||||||
|
switch-to-configuration-ng
|
||||||
texinfo
|
texinfo
|
||||||
unionfs-fuse
|
unionfs-fuse
|
||||||
xorg.lndir
|
xorg.lndir
|
||||||
|
@ -648,6 +649,10 @@ let
|
||||||
in [
|
in [
|
||||||
(pkgs.grub2.override { inherit zfsSupport; })
|
(pkgs.grub2.override { inherit zfsSupport; })
|
||||||
(pkgs.grub2_efi.override { inherit zfsSupport; })
|
(pkgs.grub2_efi.override { inherit zfsSupport; })
|
||||||
|
pkgs.nixos-artwork.wallpapers.simple-dark-gray-bootloader
|
||||||
|
pkgs.perlPackages.FileCopyRecursive
|
||||||
|
pkgs.perlPackages.XMLSAX
|
||||||
|
pkgs.perlPackages.XMLSAXBase
|
||||||
])
|
])
|
||||||
++ optionals (bootLoader == "systemd-boot") [
|
++ optionals (bootLoader == "systemd-boot") [
|
||||||
pkgs.zstd.bin
|
pkgs.zstd.bin
|
||||||
|
|
|
@ -7,19 +7,19 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
machine = { ... }: {
|
machine = {
|
||||||
users.mutableUsers = false;
|
specialisation.immutable.configuration = {
|
||||||
};
|
users.mutableUsers = false;
|
||||||
mutable = { ... }: {
|
};
|
||||||
users.mutableUsers = true;
|
|
||||||
users.users.dry-test.isNormalUser = true;
|
specialisation.mutable.configuration = {
|
||||||
|
users.mutableUsers = true;
|
||||||
|
users.users.dry-test.isNormalUser = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = {nodes, ...}: let
|
testScript = ''
|
||||||
immutableSystem = nodes.machine.config.system.build.toplevel;
|
|
||||||
mutableSystem = nodes.mutable.config.system.build.toplevel;
|
|
||||||
in ''
|
|
||||||
machine.start()
|
machine.start()
|
||||||
machine.wait_for_unit("default.target")
|
machine.wait_for_unit("default.target")
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
machine.succeed("sudo useradd foobar")
|
machine.succeed("sudo useradd foobar")
|
||||||
assert "foobar" in machine.succeed("cat /etc/passwd")
|
assert "foobar" in machine.succeed("cat /etc/passwd")
|
||||||
machine.succeed(
|
machine.succeed(
|
||||||
"${immutableSystem}/bin/switch-to-configuration test"
|
"/run/booted-system/specialisation/immutable/bin/switch-to-configuration test"
|
||||||
)
|
)
|
||||||
assert "foobar" not in machine.succeed("cat /etc/passwd")
|
assert "foobar" not in machine.succeed("cat /etc/passwd")
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
with subtest("Password is wrapped in mutable mode"):
|
with subtest("Password is wrapped in mutable mode"):
|
||||||
assert "/run/current-system/" in machine.succeed("which passwd")
|
assert "/run/current-system/" in machine.succeed("which passwd")
|
||||||
machine.succeed(
|
machine.succeed(
|
||||||
"${mutableSystem}/bin/switch-to-configuration test"
|
"/run/booted-system/specialisation/mutable/bin/switch-to-configuration test"
|
||||||
)
|
)
|
||||||
assert "/run/wrappers/" in machine.succeed("which passwd")
|
assert "/run/wrappers/" in machine.succeed("which passwd")
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
expected_hashes[file] = machine.succeed(f"sha256sum {file}")
|
expected_hashes[file] = machine.succeed(f"sha256sum {file}")
|
||||||
expected_stats[file] = machine.succeed(f"stat {file}")
|
expected_stats[file] = machine.succeed(f"stat {file}")
|
||||||
|
|
||||||
machine.succeed("/run/current-system/bin/switch-to-configuration dry-activate")
|
machine.succeed("/run/booted-system/specialisation/mutable/bin/switch-to-configuration dry-activate")
|
||||||
|
|
||||||
machine.fail('test -e /home/dry-test') # home was not recreated
|
machine.fail('test -e /home/dry-test') # home was not recreated
|
||||||
for file in files_to_check:
|
for file in files_to_check:
|
||||||
|
|
|
@ -6,17 +6,6 @@
|
||||||
import ./make-test-python.nix ({ pkgs, lib, withFirewall, nftables ? false, ... }:
|
import ./make-test-python.nix ({ pkgs, lib, withFirewall, nftables ? false, ... }:
|
||||||
let
|
let
|
||||||
unit = if nftables then "nftables" else (if withFirewall then "firewall" else "nat");
|
unit = if nftables then "nftables" else (if withFirewall then "firewall" else "nat");
|
||||||
|
|
||||||
routerBase =
|
|
||||||
lib.mkMerge [
|
|
||||||
{ virtualisation.vlans = [ 2 1 ];
|
|
||||||
networking.firewall.enable = withFirewall;
|
|
||||||
networking.firewall.filterForward = nftables;
|
|
||||||
networking.nftables.enable = nftables;
|
|
||||||
networking.nat.internalIPs = [ "192.168.1.0/24" ];
|
|
||||||
networking.nat.externalInterface = "eth1";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
name = "nat" + (lib.optionalString nftables "Nftables")
|
name = "nat" + (lib.optionalString nftables "Nftables")
|
||||||
|
@ -26,27 +15,27 @@ import ./make-test-python.nix ({ pkgs, lib, withFirewall, nftables ? false, ...
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes =
|
nodes =
|
||||||
{ client =
|
{
|
||||||
{ pkgs, nodes, ... }:
|
client = { lib, nodes, ... }: {
|
||||||
lib.mkMerge [
|
virtualisation.vlans = [ 1 ];
|
||||||
{ virtualisation.vlans = [ 1 ];
|
networking.defaultGateway =
|
||||||
networking.defaultGateway =
|
(lib.head nodes.router.networking.interfaces.eth2.ipv4.addresses).address;
|
||||||
(pkgs.lib.head nodes.router.networking.interfaces.eth2.ipv4.addresses).address;
|
networking.nftables.enable = nftables;
|
||||||
networking.nftables.enable = nftables;
|
};
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
router =
|
router = { lib, ... }: {
|
||||||
{ ... }: lib.mkMerge [
|
virtualisation.vlans = [ 2 1 ];
|
||||||
routerBase
|
networking.firewall.enable = withFirewall;
|
||||||
{ networking.nat.enable = true; }
|
networking.firewall.filterForward = nftables;
|
||||||
];
|
networking.nftables.enable = nftables;
|
||||||
|
networking.nat.enable = true;
|
||||||
|
networking.nat.internalIPs = [ "192.168.1.0/24" ];
|
||||||
|
networking.nat.externalInterface = "eth1";
|
||||||
|
|
||||||
routerDummyNoNat =
|
specialisation.no-nat.configuration = {
|
||||||
{ ... }: lib.mkMerge [
|
networking.nat.enable = lib.mkForce false;
|
||||||
routerBase
|
};
|
||||||
{ networking.nat.enable = false; }
|
};
|
||||||
];
|
|
||||||
|
|
||||||
server =
|
server =
|
||||||
{ ... }:
|
{ ... }:
|
||||||
|
@ -59,11 +48,7 @@ import ./make-test-python.nix ({ pkgs, lib, withFirewall, nftables ? false, ...
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript =
|
testScript = ''
|
||||||
{ nodes, ... }: let
|
|
||||||
routerDummyNoNatClosure = nodes.routerDummyNoNat.system.build.toplevel;
|
|
||||||
routerClosure = nodes.router.system.build.toplevel;
|
|
||||||
in ''
|
|
||||||
client.start()
|
client.start()
|
||||||
router.start()
|
router.start()
|
||||||
server.start()
|
server.start()
|
||||||
|
@ -94,14 +79,14 @@ import ./make-test-python.nix ({ pkgs, lib, withFirewall, nftables ? false, ...
|
||||||
|
|
||||||
# If we turn off NAT, the client shouldn't be able to reach the server.
|
# If we turn off NAT, the client shouldn't be able to reach the server.
|
||||||
router.succeed(
|
router.succeed(
|
||||||
"${routerDummyNoNatClosure}/bin/switch-to-configuration test 2>&1"
|
"/run/booted-system/specialisation/no-nat/bin/switch-to-configuration test 2>&1"
|
||||||
)
|
)
|
||||||
client.fail("curl -4 --fail --connect-timeout 5 http://server/ >&2")
|
client.fail("curl -4 --fail --connect-timeout 5 http://server/ >&2")
|
||||||
client.fail("ping -4 -c 1 server >&2")
|
client.fail("ping -4 -c 1 server >&2")
|
||||||
|
|
||||||
# And make sure that reloading the NAT job works.
|
# And make sure that reloading the NAT job works.
|
||||||
router.succeed(
|
router.succeed(
|
||||||
"${routerClosure}/bin/switch-to-configuration test 2>&1"
|
"/run/booted-system/bin/switch-to-configuration test 2>&1"
|
||||||
)
|
)
|
||||||
# FIXME: this should not be necessary, but nat.service is not started because
|
# FIXME: this should not be necessary, but nat.service is not started because
|
||||||
# network.target is not triggered
|
# network.target is not triggered
|
||||||
|
|
|
@ -7,6 +7,8 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
nodes.machine = { pkgs, ... }: {
|
nodes.machine = { pkgs, ... }: {
|
||||||
imports = [ ../modules/profiles/minimal.nix ];
|
imports = [ ../modules/profiles/minimal.nix ];
|
||||||
|
|
||||||
|
system.switch.enable = true;
|
||||||
|
|
||||||
systemd.services.restart-me = {
|
systemd.services.restart-me = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
|
|
@ -591,6 +591,7 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
other = {
|
other = {
|
||||||
|
system.switch.enable = true;
|
||||||
users.mutableUsers = true;
|
users.mutableUsers = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@ let
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
environment.systemPackages = [ pkgs.efibootmgr ];
|
environment.systemPackages = [ pkgs.efibootmgr ];
|
||||||
|
system.switch.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
commonXbootldr = { config, lib, pkgs, ... }:
|
commonXbootldr = { config, lib, pkgs, ... }:
|
||||||
|
|
|
@ -3,6 +3,7 @@ import ./make-test-python.nix ({ lib, ... }: {
|
||||||
meta = with lib.maintainers; { maintainers = [ chkno ]; };
|
meta = with lib.maintainers; { maintainers = [ chkno ]; };
|
||||||
|
|
||||||
nodes.machine = {
|
nodes.machine = {
|
||||||
|
system.switch.enable = true;
|
||||||
system.userActivationScripts.foo = "mktemp ~/user-activation-ran.XXXXXX";
|
system.userActivationScripts.foo = "mktemp ~/user-activation-ran.XXXXXX";
|
||||||
users.users.alice = {
|
users.users.alice = {
|
||||||
initialPassword = "pass1";
|
initialPassword = "pass1";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue