Loading nixos/lib/testing/nixos-test-base.nix +7 −2 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ # even in `inheritParentConfig = false` specialisations. { lib, ... }: let inherit (lib) mkForce; inherit (lib) mkDefault mkForce; in { imports = [ Loading @@ -22,6 +22,11 @@ in 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 != {}); }) ]; } nixos/modules/system/activation/no-clone.nix +1 −0 Original line number Diff line number Diff line Loading @@ -5,4 +5,5 @@ with lib; { boot.loader.grub.device = mkOverride 0 "nodev"; specialisation = mkOverride 0 {}; isSpecialisation = mkOverride 0 true; } nixos/modules/system/activation/specialisation.nix +6 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,12 @@ let in { options = { isSpecialisation = mkOption { type = lib.types.bool; internal = true; default = false; description = "Whether this system is a specialisation of another."; }; specialisation = mkOption { default = { }; Loading nixos/tests/chrony.nix +15 −16 Original line number Diff line number Diff line Loading @@ -7,25 +7,24 @@ import ./make-test-python.nix ({ lib, ... }: }; nodes = { default = { services.chrony.enable = true; }; graphene-hardened = { machine = { services.chrony.enable = true; specialisation.hardened.configuration = { services.chrony.enableMemoryLocking = true; environment.memoryAllocator.provider = "graphene-hardened"; # dhcpcd privsep is incompatible with graphene-hardened networking.useNetworkd = true; }; }; }; testScript = {nodes, ...} : let graphene-hardened = nodes.graphene-hardened.system.build.toplevel; in '' default.start() default.wait_for_unit('multi-user.target') default.succeed('systemctl is-active chronyd.service') default.succeed('${graphene-hardened}/bin/switch-to-configuration test') default.succeed('systemctl is-active chronyd.service') testScript = '' machine.start() machine.wait_for_unit('multi-user.target') machine.succeed('systemctl is-active chronyd.service') machine.succeed('/run/booted-system/specialisation/hardened/bin/switch-to-configuration test') machine.succeed('systemctl restart chronyd.service') machine.wait_for_unit('chronyd.service') ''; }) nixos/tests/containers-reloadable.nix +28 −42 Original line number Diff line number Diff line 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"; meta = { maintainers = with lib.maintainers; [ danbst ]; }; nodes = { client = { ... }: { imports = [ client_base ]; machine = { lib, ... }: { containers.test1 = { autoStart = true; config.environment.etc.check.text = "client_base"; }; client_c1 = { lib, ... }: { imports = [ client_base ]; # prevent make-test-python.nix to change IP networking.interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [ ]; specialisation.c1.configuration = { 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 ]; specialisation.c2.configuration = { containers.test1.config = { environment.etc.check.text = lib.mkForce "client_c2"; services.nginx.enable = true; }; }; }; }; testScript = {nodes, ...}: let c1System = nodes.client_c1.config.system.build.toplevel; c2System = nodes.client_c2.config.system.build.toplevel; in '' client.start() client.wait_for_unit("default.target") testScript = '' machine.start() machine.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"): client.succeed( "${c1System}/bin/switch-to-configuration test >&2", machine.succeed( "/run/booted-system/specialisation/c1/bin/switch-to-configuration test >&2", "[[ $(nixos-container run test1 cat /etc/check) == client_c1 ]] >&2", "systemctl status httpd -M test1 >&2", ) with subtest("httpd is not available any longer after switching to config2"): client.succeed( "${c2System}/bin/switch-to-configuration test >&2", machine.succeed( "/run/booted-system/specialisation/c2/bin/switch-to-configuration test >&2", "[[ $(nixos-container run test1 cat /etc/check) == client_c2 ]] >&2", "systemctl status nginx -M test1 >&2", ) client.fail("systemctl status httpd -M test1 >&2") machine.fail("systemctl status httpd -M test1 >&2") ''; }) Loading
nixos/lib/testing/nixos-test-base.nix +7 −2 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ # even in `inheritParentConfig = false` specialisations. { lib, ... }: let inherit (lib) mkForce; inherit (lib) mkDefault mkForce; in { imports = [ Loading @@ -22,6 +22,11 @@ in 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 != {}); }) ]; }
nixos/modules/system/activation/no-clone.nix +1 −0 Original line number Diff line number Diff line Loading @@ -5,4 +5,5 @@ with lib; { boot.loader.grub.device = mkOverride 0 "nodev"; specialisation = mkOverride 0 {}; isSpecialisation = mkOverride 0 true; }
nixos/modules/system/activation/specialisation.nix +6 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,12 @@ let in { options = { isSpecialisation = mkOption { type = lib.types.bool; internal = true; default = false; description = "Whether this system is a specialisation of another."; }; specialisation = mkOption { default = { }; Loading
nixos/tests/chrony.nix +15 −16 Original line number Diff line number Diff line Loading @@ -7,25 +7,24 @@ import ./make-test-python.nix ({ lib, ... }: }; nodes = { default = { services.chrony.enable = true; }; graphene-hardened = { machine = { services.chrony.enable = true; specialisation.hardened.configuration = { services.chrony.enableMemoryLocking = true; environment.memoryAllocator.provider = "graphene-hardened"; # dhcpcd privsep is incompatible with graphene-hardened networking.useNetworkd = true; }; }; }; testScript = {nodes, ...} : let graphene-hardened = nodes.graphene-hardened.system.build.toplevel; in '' default.start() default.wait_for_unit('multi-user.target') default.succeed('systemctl is-active chronyd.service') default.succeed('${graphene-hardened}/bin/switch-to-configuration test') default.succeed('systemctl is-active chronyd.service') testScript = '' machine.start() machine.wait_for_unit('multi-user.target') machine.succeed('systemctl is-active chronyd.service') machine.succeed('/run/booted-system/specialisation/hardened/bin/switch-to-configuration test') machine.succeed('systemctl restart chronyd.service') machine.wait_for_unit('chronyd.service') ''; })
nixos/tests/containers-reloadable.nix +28 −42 Original line number Diff line number Diff line 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"; meta = { maintainers = with lib.maintainers; [ danbst ]; }; nodes = { client = { ... }: { imports = [ client_base ]; machine = { lib, ... }: { containers.test1 = { autoStart = true; config.environment.etc.check.text = "client_base"; }; client_c1 = { lib, ... }: { imports = [ client_base ]; # prevent make-test-python.nix to change IP networking.interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [ ]; specialisation.c1.configuration = { 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 ]; specialisation.c2.configuration = { containers.test1.config = { environment.etc.check.text = lib.mkForce "client_c2"; services.nginx.enable = true; }; }; }; }; testScript = {nodes, ...}: let c1System = nodes.client_c1.config.system.build.toplevel; c2System = nodes.client_c2.config.system.build.toplevel; in '' client.start() client.wait_for_unit("default.target") testScript = '' machine.start() machine.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"): client.succeed( "${c1System}/bin/switch-to-configuration test >&2", machine.succeed( "/run/booted-system/specialisation/c1/bin/switch-to-configuration test >&2", "[[ $(nixos-container run test1 cat /etc/check) == client_c1 ]] >&2", "systemctl status httpd -M test1 >&2", ) with subtest("httpd is not available any longer after switching to config2"): client.succeed( "${c2System}/bin/switch-to-configuration test >&2", machine.succeed( "/run/booted-system/specialisation/c2/bin/switch-to-configuration test >&2", "[[ $(nixos-container run test1 cat /etc/check) == client_c2 ]] >&2", "systemctl status nginx -M test1 >&2", ) client.fail("systemctl status httpd -M test1 >&2") machine.fail("systemctl status httpd -M test1 >&2") ''; })