diff options
author | Maximilian Bosch <maximilian@mbosch.me> | 2020-02-10 02:21:24 +0100 |
---|---|---|
committer | Maximilian Bosch <maximilian@mbosch.me> | 2020-02-11 14:42:30 +0100 |
commit | 93943acbc5d795a34a0f933d3b31094fc2c7b78f (patch) | |
tree | 8a4ab4853e3f38682431b78ad0b17b53620d147c | |
parent | c6fa3c201c1ef175ea58f5c0919b39a48a83bb3c (diff) | |
download | nixpkgs-93943acbc5d795a34a0f933d3b31094fc2c7b78f.tar nixpkgs-93943acbc5d795a34a0f933d3b31094fc2c7b78f.tar.gz nixpkgs-93943acbc5d795a34a0f933d3b31094fc2c7b78f.tar.bz2 nixpkgs-93943acbc5d795a34a0f933d3b31094fc2c7b78f.tar.lz nixpkgs-93943acbc5d795a34a0f933d3b31094fc2c7b78f.tar.xz nixpkgs-93943acbc5d795a34a0f933d3b31094fc2c7b78f.tar.zst nixpkgs-93943acbc5d795a34a0f933d3b31094fc2c7b78f.zip |
nixos/nixos-container: ensure that the state-dir is cleaned up if a build fails
-rw-r--r-- | nixos/tests/containers-imperative.nix | 15 | ||||
-rwxr-xr-x | pkgs/tools/virtualization/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") { |