about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRaito Bezarius <masterancpp@gmail.com>2023-04-23 23:48:35 +0200
committerRaito Bezarius <masterancpp@gmail.com>2023-04-23 23:48:35 +0200
commitfc39343438c5e72b9893f87dc06b0561a8e5cd2d (patch)
tree6fce7306f41b6388c79285515331117d0bd45d17
parent6d69171610869050b8c1daa07ec2446a5c897c19 (diff)
nixos/lib/make-disk-image: introduce `noNixStore` option make-disk-image/no-nix-store
Sometimes, we want to use the host nix store for everything because it's
more convenient.

To do so, we need to "not install" the nix store in the target disk
image.

We trick nixos-install by mount binding the host nix store into the
$root/nix folder and letting Nix do the idempotency thing.
-rw-r--r--nixos/lib/make-disk-image.nix18
1 files changed, 17 insertions, 1 deletions
diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix
index db53bb98ee4ef..e18c82a65bfe7 100644
--- a/nixos/lib/make-disk-image.nix
+++ b/nixos/lib/make-disk-image.nix
@@ -162,6 +162,12 @@ To solve this, you can run `fdisk -l $image` and generate `dd if=$image of=$imag
   # `installBootLoader` and `configFile`.
   onlyNixStore ? false
 
+, # Ensure that no "new" Nix store is written to the root of the image
+  # by symlinking the host Nix store.
+  # This saves a lot of disk space if you don't need an isolated Nix store.
+  # Incompatible with `additionalPaths`
+  noNixStore ? true
+
 , name ? "nixos-disk-image"
 
 , # Disk image format, one of qcow2, qcow2-compressed, vdi, vpc, raw.
@@ -198,8 +204,9 @@ assert (lib.assertMsg (fsType == "ext4" && deterministic -> rootFSUID != null) "
   # We use -E offset=X below, which is only supported by e2fsprogs
 assert (lib.assertMsg (partitionTableType != "none" -> fsType == "ext4") "to produce a partition table, we need to use -E offset flag which is support only for fsType = ext4");
 assert (lib.assertMsg (touchEFIVars -> partitionTableType == "hybrid" || partitionTableType == "efi" || partitionTableType == "legacy+gpt") "EFI variables can be used only with a partition table of type: hybrid, efi or legacy+gpt.");
-  # If only Nix store image, then: contents must be empty, configFile must be unset, and we should no install bootloader.
+# If only Nix store image, then: contents must be empty, configFile must be unset, and we should no install bootloader.
 assert (lib.assertMsg (onlyNixStore -> contents == [] && configFile == null && !installBootLoader) "In a only Nix store image, the contents must be empty, no configuration must be provided and no bootloader should be installed.");
+assert (lib.assertMsg (noNixStore -> additionalPaths == []) "Without a Nix store in the rootfs, additional paths cannot be copied otherwise you would end up again with a Nix store.");
 # Either both or none of {user,group} need to be set
 assert (lib.assertMsg (lib.all
          (attrs: ((attrs.user  or null) == null)
@@ -422,6 +429,15 @@ let format' = format; in let
     export NIX_STATE_DIR=$TMPDIR/state
     nix-store --load-db < ${closureInfo}/registration
 
+    ${optionalString noNixStore ''
+      # Ensure host Nix store is available so that `nixos-install` performs
+      # no extra operations.
+      mkdir -p $root/nix
+      # TODO: this needs to be made persistent or you need to run the nixos-install inside the namespace.
+      # then, we need to unmount.
+      unshare --mount --map-root-user mount --rbind ${builtins.storeDir} $root/nix
+    ''}
+
     chmod 755 "$TMPDIR"
     echo "running nixos-install..."
     nixos-install --root $root --no-bootloader --no-root-passwd \