diff --git a/docs/disko-images.md b/docs/disko-images.md index 281a0672..7d1bd5b7 100644 --- a/docs/disko-images.md +++ b/docs/disko-images.md @@ -1,11 +1,9 @@ # Generating Disk Images with Secrets Included using Disko -Using Disko on NixOS allows you to efficiently create `.raw` VM images from a -system configuration. The generated image can be used as a VM or directly -written to a physical drive to create a bootable disk. Follow the steps below to -generate disk images: +Using Disko on NixOS allows you to efficiently create `.raw` disk images from a system configuration. +Follow the steps below to generate disk images: -## Generating the `.raw` VM Image +## Generating the `.raw` Image 1. **Create a NixOS configuration that includes the disko and the disk configuration of your choice** @@ -24,16 +22,29 @@ In the this example we create a flake containing a nixos configuration for disko.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = { self, disko, nixpkgs }: { + outputs = { self, disko, nixpkgs, ... }: { nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ # You can get this file from here: https://github.com/nix-community/disko/blob/master/example/simple-efi.nix ./simple-efi.nix disko.nixosModules.disko - ({ config, ... }: { + ({ config, modulesPath, ... }: { + imports = [ + # include this line to boot to boot the image inside a VM + # "${modulesPath}/profiles/qemu-guest.nix" + # On other hardware, you may need a hardware-configuration.nix as generated by nixos-generate-config or use nixos-facter (https://github.com/numtide/nixos-facter) + # ./hardware-configuration.nix + ]; + + # Optional. Useful for testing + # users.users.root.initialPassword = "root"; + + boot.loader.grub.efiSupport = lib.mkDefault true; + boot.loader.grub.efiInstallAsRemovable = lib.mkDefault true; + # shut up state version warning - system.stateVersion = config.system.nixos.version; + system.stateVersion = config.system.nixos.release; # Adjust this to your liking. # WARNING: if you set a too low value the image might be not big enough to contain the nixos installation disko.devices.disk.main.imageSize = "10G"; @@ -141,3 +152,58 @@ In the this example we create a flake containing a nixos configuration for By following these instructions and understanding the process, you can smoothly generate disk images with Disko for your NixOS system configurations. + +## Test the image inside a VM + +Make sure you uncommented the `"${modulesPath}/profiles/qemu-guest.nix"` import in the example above! + +Write the following script to `qemu.nix`. Note that it expects an UEFI compatible image! + +``` +with import {}; + +writeShellApplication { + name = "test-image"; + runtimeInputs = [ qemu ]; + text = '' + if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 + fi + tmpFile=$(mktemp /tmp/test-image.XXXXXX) + trap 'rm -f $tmpFile' EXIT + cp "$1" "$tmpFile" + qemu-system-x86_64 \ + -enable-kvm \ + -m 2G \ + -cpu max \ + -smp 2 \ + -netdev user,id=net0,hostfwd=tcp::2222-:22 \ + -device virtio-net-pci,netdev=net0 \ + -drive if=pflash,format=raw,readonly=on,file=${OVMF.firmware} \ + -drive if=pflash,format=raw,readonly=on,file=${OVMF.variables} \ + -drive "if=virtio,format=raw,file=$tmpFile" + ''; +} +``` + +This command will run a qemu vm with your image: + +``` +$(nix-build ./qemu.nix)/bin/test-image ./main.raw +``` + +Replace `main.raw` with the image that you build! + +Tip: You can customize memory (`-m` flag) or cpu (`-smp` flag) available to the VM to your liking. + +## Build the image inside the nix sandbox + +Instead of the diskoImagesScript, we can also build the image inside the nix store. +This approach is slower because it requires copying the image after the build and +we also don't have a secure way to embed secrets this way. + +``` +nix build .#nixosConfigurations.myhost.config.system.build.diskoImages +ls -a ./result/main.raw +``` diff --git a/lib/make-disk-image.nix b/lib/make-disk-image.nix index e3c0c3d5..ec0b32eb 100644 --- a/lib/make-disk-image.nix +++ b/lib/make-disk-image.nix @@ -136,6 +136,7 @@ let installer = lib.optionalString cfg.copyNixStore '' ${binfmtSetup} + unset NIX_REMOTE # populate nix db, so nixos-install doesn't complain export NIX_STATE_DIR=${systemToInstall.config.disko.rootMountPoint}/nix/var/nix nix-store --load-db < "${closureInfo}/registration"