From 93943acbc5d795a34a0f933d3b31094fc2c7b78f Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Mon, 10 Feb 2020 02:21:24 +0100 Subject: [PATCH 1/2] nixos/nixos-container: ensure that the state-dir is cleaned up if a build fails --- nixos/tests/containers-imperative.nix | 15 +++++++++++ .../nixos-container/nixos-container.pl | 26 ++++++++++++++----- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/nixos/tests/containers-imperative.nix b/nixos/tests/containers-imperative.nix index 61df74042cb..c4f2002918f 100644 --- a/nixos/tests/containers-imperative.nix +++ b/nixos/tests/containers-imperative.nix @@ -46,6 +46,15 @@ import ./make-test-python.nix ({ pkgs, ...} : { }; } ''; + brokenCfg = pkgs.writeText "broken.nix" '' + { + assertions = [ + { assertion = false; + message = "I never evaluate"; + } + ]; + } + ''; in '' with subtest("Make sure we have a NixOS tree (required by ‘nixos-container create’)"): machine.succeed("PAGER=cat nix-env -qa -A nixos.hello >&2") @@ -130,5 +139,11 @@ import ./make-test-python.nix ({ pkgs, ...} : { with subtest("Ensure that the container path is gone"): print(machine.succeed("ls -lsa /var/lib/containers")) machine.succeed(f"test ! -e /var/lib/containers/{id1}") + + with subtest("Ensure that a failed container creation doesn'leave any state"): + machine.fail( + "nixos-container create b0rk --config-file ${brokenCfg}" + ) + machine.succeed(f"test ! -e /var/lib/containers/b0rk") ''; }) diff --git a/pkgs/tools/virtualization/nixos-container/nixos-container.pl b/pkgs/tools/virtualization/nixos-container/nixos-container.pl index 727c0333b27..a14926a9767 100755 --- a/pkgs/tools/virtualization/nixos-container/nixos-container.pl +++ b/pkgs/tools/virtualization/nixos-container/nixos-container.pl @@ -149,6 +149,16 @@ sub buildFlake { unlink("$systemPath.tmp"); } +sub clearContainerState { + my ($profileDir, $gcRootsDir, $root, $configFile) = @_; + + safeRemoveTree($profileDir) if -e $profileDir; + safeRemoveTree($gcRootsDir) if -e $gcRootsDir; + system("chattr", "-i", "$root/var/empty") if -e "$root/var/empty"; + safeRemoveTree($root) if -e $root; + unlink($configFile) or die; +} + if ($action eq "create") { # Acquire an exclusive lock to prevent races with other # invocations of ‘nixos-container create’. @@ -226,7 +236,10 @@ if ($action eq "create") { if (defined $systemPath) { system("nix-env", "-p", "$profileDir/system", "--set", $systemPath) == 0 - or die "$0: failed to set initial container configuration\n"; + or do { + clearContainerState($profileDir, "$profileDir/$containerName", $root, $confFile); + die "$0: failed to set initial container configuration\n"; + }; } else { mkpath("$root/etc/nixos", 0, 0755); @@ -237,7 +250,10 @@ if ($action eq "create") { system("nix-env", "-p", "$profileDir/system", "-I", "nixos-config=$nixosConfigFile", "-f", "$nixenvF", "--set", "-A", "system") == 0 - or die "$0: failed to build initial container configuration\n"; + or do { + clearContainerState($profileDir, "$profileDir/$containerName", $root, $confFile); + die "$0: failed to build initial container configuration\n" + }; } print "$containerName\n" if $ensureUniqueName; @@ -331,11 +347,7 @@ if ($action eq "destroy") { terminateContainer if (isContainerRunning); - safeRemoveTree($profileDir) if -e $profileDir; - safeRemoveTree($gcRootsDir) if -e $gcRootsDir; - system("chattr", "-i", "$root/var/empty") if -e "$root/var/empty"; - safeRemoveTree($root) if -e $root; - unlink($confFile) or die; + clearContainerState($profileDir, $gcRootsDir, $root, $confFile); } elsif ($action eq "restart") { From 31bbcc21d38366489120341bb74438cd38f4bf40 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Mon, 10 Feb 2020 15:12:00 +0100 Subject: [PATCH 2/2] nixos/nixos-container: use custom path if specified by `--nixos-path` --- pkgs/tools/virtualization/nixos-container/nixos-container.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/tools/virtualization/nixos-container/nixos-container.pl b/pkgs/tools/virtualization/nixos-container/nixos-container.pl index a14926a9767..df4c8fee21b 100755 --- a/pkgs/tools/virtualization/nixos-container/nixos-container.pl +++ b/pkgs/tools/virtualization/nixos-container/nixos-container.pl @@ -43,6 +43,7 @@ Usage: nixos-container list [--config ] [--config-file ] [--flake ] + [--nixos-path ] nixos-container login nixos-container root-login nixos-container run -- args... @@ -386,6 +387,7 @@ elsif ($action eq "update") { system("nix-env", "-p", "$profileDir/system", "--set", $systemPath) == 0 or die "$0: failed to set container configuration\n"; } else { + my $nixosConfigFile = "$root/etc/nixos/configuration.nix"; # FIXME: may want to be more careful about clobbering the existing @@ -395,8 +397,9 @@ elsif ($action eq "update") { writeNixOSConfig $nixosConfigFile; } + my $nixenvF = $nixosPath // ""; system("nix-env", "-p", "$profileDir/system", - "-I", "nixos-config=$nixosConfigFile", "-f", "", + "-I", "nixos-config=$nixosConfigFile", "-f", $nixenvF, "--set", "-A", "system") == 0 or die "$0: failed to build container configuration\n"; }