summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2020-02-10 02:21:24 +0100
committerMaximilian Bosch <maximilian@mbosch.me>2020-02-11 14:42:30 +0100
commit93943acbc5d795a34a0f933d3b31094fc2c7b78f (patch)
tree8a4ab4853e3f38682431b78ad0b17b53620d147c
parentc6fa3c201c1ef175ea58f5c0919b39a48a83bb3c (diff)
downloadnixpkgs-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.nix15
-rwxr-xr-xpkgs/tools/virtualization/nixos-container/nixos-container.pl26
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") {