Open msanft opened 1 week ago
Unifying 3+ interfaces that do the same thing sounds pretty uncontroversial, doubt it needs an rfc :) Thanks for raising this.
Unifying 3+ interfaces that do the same thing sounds pretty uncontroversial, doubt it needs an rfc :) Thanks for raising this.
Yes, I think this part is out of question. The "RFC" part I was referring to rather meant a "discussion with an outcome" about how that new interface should look like
tl;dr
NixOS has many image builders that build an image file from a NixOS configuration, such as
image.repart
,system.build.isoImage
,system.build.sdImage
. Not only do these inconsistent interfaces create a bad UX (options being named differently but doing the same, etc.), they also make it hard to introduce new features for all of those builders due to duplication. With this, I propose to shift towards a unified image builder usingsystemd-repart
. (i.e. the existingimage.repart
builder, with abstractions and default options that enable convenient builds of regularly built image types, such as the existingsystem.build.isoImage
andsystem.build.sdImage
). In addition to this proposition I'd like this issue to be a place for discussion on how such an interface should look like, ideally leading to a decision.The Status Quo
We currently have (at least) 3 different publicly exposed builders that will emit a NixOS image based on a NixOS configuration:
image.repart
: Arguably, this is the state-of-the-art builder, as it's the most configurable one and allows for the easiest attribute-based customizations. It can build almost any sort of image and is especially well-suited for immutable appliance images. It currently lacks support for image pre- and post-processing, for example to insert a ISO9660 (El Torito) boot record for making CD-ROM images. Furthemore, it's the only builder supporting discoverable disk images (DDIs), which are the de-facto standard of systemd nowadays.system.build.isoImage
: The most popular builder for "desktop" installers and users that want an image that "just boots" and resembles closely what they are used to from other distributions. It did earn quite a lot of configurability over the years and has quite many options now. Uses an imperative script to build the actual image and lacks support for declarative partitioning, which is to be done after first boot in this scenario.system.build.sdImage
: Quite similar to the ISO image builder, this one, again, has a new build script. It's the most popular choice for building tiny images, e.g. for embedded devices, as it has support for minimizing the partition sizes at first boot and writes a special/boot/firmware
directory with custom bootloader contents. It lacks configurability for the actual partitions though, as root is always ext4, and/boot/firmware
is always VFAT.Other than that, there also are private builders such as
lib/make-disk-image.nix
, which are used throughout nixpkgs, e.g. to build VM images. Most of them are very use-case specific, but also encode a lot of logic.Why is this an Issue?
Maintaining multiple builders doing similar things is tedious, especially if their work can also be done by other builders. Furthermore, all builders have wildly different configuration interfaces, making it hard for users to find which knobs they need to turn to get what they want, and even finding the correct builder for the use-case in the first place can be a hassle. Furthermore, there are features which would be great to implement for all NixOS image builders, such as build-time execution of activation scripts, making image-based appliances more immutable by not requiring a writable root filesystem.
What is desirable?
Part of this should be discussed within this issue. Personally, I propose a unified interface for building images (e.g.
build.image
) that should cover all current use-cases. The builder should be based on the currentimage.repart
, as it provides the most configurability, and declarative partitioning. It also blends in very well with other systemd components, such assystemd-cryptsetup
. There should still be convenience targets (think asystem.build.isoImage
, but based on the unified builder interface), which should be compatible with the current builder interface. For continuous development of such a unified interface, a first step could port a basic builder, and then the exisiting builders (e.g.system.build.isoImage
) could be ported from their existing build scripts to the unified builder, maintaining compatibility. This would be a huge step for both installation- as well as image-based NixOS, increasing nixpkgs-internal development velocity on these topics, many of which are very desirable for NixOS in enterprise use-cases.