From 22adcaa4491dde18442a234252e1d7ed8c098672 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Tue, 20 Dec 2022 21:04:17 +0100 Subject: nixos/lib/make-disk-image: docs, UEFI vars recording, more determinism - Extensive documentation in NixOS manual - Deterministic mode that fixes various identifiers relative to disk partitions and filesystems in ext4 case - UEFI variable recording --- doc/builders/images.xml | 1 + doc/builders/images/makediskimage.section.md | 107 +++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 doc/builders/images/makediskimage.section.md (limited to 'doc') diff --git a/doc/builders/images.xml b/doc/builders/images.xml index f86ebd86bee4..7d06130e3eca 100644 --- a/doc/builders/images.xml +++ b/doc/builders/images.xml @@ -10,4 +10,5 @@ + diff --git a/doc/builders/images/makediskimage.section.md b/doc/builders/images/makediskimage.section.md new file mode 100644 index 000000000000..9798a0be4d46 --- /dev/null +++ b/doc/builders/images/makediskimage.section.md @@ -0,0 +1,107 @@ +# `` {#sec-make-disk-image} + +`` is a function to create _disk images_ in multiple formats: raw, QCOW2 (QEMU), QCOW2-Compressed (compressed version), VDI (VirtualBox), VPC (VirtualPC). + +This function can create images in two ways: + +- using `cptofs` without any virtual machine to create a Nix store disk image, +- using a virtual machine to create a full NixOS installation. + +When testing early-boot or lifecycle parts of NixOS such as a bootloader or multiple generations, it is necessary to opt for a full NixOS system installation. +Whereas for many web servers, applications, it is possible to work with a Nix store only disk image and is faster to build. + +NixOS tests also use this function when preparing the VM. The `cptofs` method is used when `virtualisation.useBootLoader` is false (the default). Otherwise the second method is used. + +## Features + +For reference, read the function signature source code for documentation on arguments: . +Features are separated in various sections depending on if you opt for a Nix-store only image or a full NixOS image. + +### Common + +- arbitrary NixOS configuration +- automatic or bound disk size: `diskSize` parameter, `additionalSpace` can be set when `diskSize` is `auto` to add a constant of disk space +- multiple partition table layouts: EFI, legacy, legacy + GPT, hybrid, none through `partitionTableType` parameter +- OVMF or EFI firmwares and variables templates can be customized +- root filesystem `fsType` can be customized to whatever `mkfs.${fsType}` exist during operations +- root filesystem label can be customized, defaults to `nix-store` if it's a Nix store image, otherwise `nixpkgs/nixos` +- arbitrary code can be executed after disk image was produced with `postVM` +- the current nixpkgs can be realized as a channel in the disk image, which will change the hash of the image when the sources are updated +- additional store paths can be provided through `additionalPaths` + +### Full NixOS image + +- arbitrary contents with permissions can be placed in the target filesystem using `contents` +- a `/etc/nixpkgs/nixos/configuration.nix` can be provided through `configFile` +- bootloaders are supported +- EFI variables can be mutated during image production and the result is exposed in `$out` +- boot partition size when partition table is `efi` or `hybrid` + +### On bit-to-bit reproducibility + +Images are **NOT** deterministic, please do not hesitate to try to fix this, source of determinisms are (not exhaustive) : + +- bootloader installation have timestamps +- SQLite Nix store database contain registration times +- `/etc/shadow` is in a non-deterministic order + +A `deterministic` flag is available for best efforts determinism. + +## Usage + +To produce a Nix-store only image: +```nix +let + pkgs = import {}; + lib = pkgs.lib; + make-disk-image = import ; +in + make-disk-image { + inherit pkgs lib; + config = {}; + additionalPaths = [ ]; + format = "qcow2"; + onlyNixStore = true; + partitionTableType = "none"; + installBootLoader = false; + touchEFIVars = false; + diskSize = "auto"; + additionalSpace = "0M"; # Defaults to 512M. + copyChannel = false; + } +``` + +Some arguments can be left out, they are shown explicitly for the sake of the example. + +Building this derivation will provide a QCOW2 disk image containing only the Nix store and its registration information. + +To produce a NixOS installation image disk with UEFI and bootloader installed: +```nix +let + pkgs = import {}; + lib = pkgs.lib; + make-disk-image = import ; + evalConfig = import ; +in + make-disk-image { + inherit pkgs lib; + config = evalConfig { + modules = [ + { + fileSystems."/" = { device = "/dev/vda"; fsType = "ext4"; autoFormat = true; }; + boot.grub.device = "/dev/vda"; + } + ]; + }; + format = "qcow2"; + onlyNixStore = false; + partitionTableType = "legacy+gpt"; + installBootLoader = true; + touchEFIVars = true; + diskSize = "auto"; + additionalSpace = "0M"; # Defaults to 512M. + copyChannel = false; + } +``` + + -- cgit 1.4.1