From 65ff0d5f9de3e8f0ca5ec3a70549e30afd84a6d5 Mon Sep 17 00:00:00 2001 From: danbst Date: Tue, 22 Aug 2017 15:04:18 +0300 Subject: [PATCH 1/2] switch-to-configuration: fix detection of changes between rebuilds for template instances This makes declarative containers truly reloadable. Current code already declares it: https://github.com/NixOS/nixpkgs/blob/56904d7c423f2b13b37fbd29f39bbb4b52bc7824/nixos/modules/virtualisation/containers.nix#L488 ``` restartIfChanged = false; ``` https://github.com/NixOS/nixpkgs/blob/56904d7c423f2b13b37fbd29f39bbb4b52bc7824/nixos/modules/virtualisation/containers.nix#L540 ``` reloadIfChanged = true; ``` Original author: @chrisfarms in https://github.com/NixOS/nixpkgs/pull/3021/commits/6e36619b277f78ece1bb81b79b5651897e46a2bf Most of stuff from that commit has already been ported. --- .../modules/system/activation/switch-to-configuration.pl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index 88e7847cf8c8..29cc60b00324 100644 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -147,11 +147,16 @@ my $activePrev = getActiveUnits; while (my ($unit, $state) = each %{$activePrev}) { my $baseUnit = $unit; - # Recognise template instances. - $baseUnit = "$1\@.$2" if $unit =~ /^(.*)@[^\.]*\.(.*)$/; my $prevUnitFile = "/etc/systemd/system/$baseUnit"; my $newUnitFile = "$out/etc/systemd/system/$baseUnit"; + # Detect template instances. + if (!-e $prevUnitFile && !-e $newUnitFile && $unit =~ /^(.*)@[^\.]*\.(.*)$/) { + $baseUnit = "$1\@.$2"; + $prevUnitFile = "/etc/systemd/system/$baseUnit"; + $newUnitFile = "$out/etc/systemd/system/$baseUnit"; + } + my $baseName = $baseUnit; $baseName =~ s/\.[a-z]*$//; From 63f8122cd93b8d100865515d80b5e1325e69f2cd Mon Sep 17 00:00:00 2001 From: danbst Date: Wed, 23 Aug 2017 12:43:07 +0300 Subject: [PATCH 2/2] nixos tests: add test for declarative containers, that container config changes are applied on `nixos-rebuild switch` invocations. --- nixos/tests/containers-reloadable.nix | 66 +++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 nixos/tests/containers-reloadable.nix diff --git a/nixos/tests/containers-reloadable.nix b/nixos/tests/containers-reloadable.nix new file mode 100644 index 000000000000..b5867c6f6ab1 --- /dev/null +++ b/nixos/tests/containers-reloadable.nix @@ -0,0 +1,66 @@ +import ./make-test.nix ({ pkgs, lib, ...} : +let + client_base = rec { + + containers.test1 = { + autoStart = true; + config = { + environment.etc."check".text = "client_base"; + }; + }; + + # prevent make-test.nix to change IP + networking.interfaces = { + eth1.ip4 = lib.mkOverride 0 [ ]; + }; + }; +in { + name = "cotnainers-reloadable"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ danbst ]; + }; + + nodes = { + client = { lib, pkgs, ... }: { + imports = [ client_base ]; + }; + + client_c1 = { lib, pkgs, ... }: { + 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, pkgs, ... }: { + imports = [ client_base ]; + + containers.test1.config = { + environment.etc."check".text = lib.mkForce "client_c2"; + services.nginx.enable = true; + }; + }; + }; + + testScript = {nodes, ...}: let + originalSystem = nodes.client.config.system.build.toplevel; + c1System = nodes.client_c1.config.system.build.toplevel; + c2System = nodes.client_c2.config.system.build.toplevel; + in '' + $client->start(); + $client->waitForUnit("default.target"); + $client->succeed("[[ \$(nixos-container run test1 cat /etc/check) == client_base ]] >&2"); + + $client->succeed("${c1System}/bin/switch-to-configuration test >&2"); + $client->succeed("[[ \$(nixos-container run test1 cat /etc/check) == client_c1 ]] >&2"); + $client->succeed("systemctl status httpd -M test1 >&2"); + + $client->succeed("${c2System}/bin/switch-to-configuration test >&2"); + $client->succeed("[[ \$(nixos-container run test1 cat /etc/check) == client_c2 ]] >&2"); + $client->fail("systemctl status httpd -M test1 >&2"); + $client->succeed("systemctl status nginx -M test1 >&2"); + ''; + +})