Merge pull request #132583 from blaggacao/fix/soft-force-the-file-system-layout-for-boot-media

nixos/boot-media: soft-force entire fs layout
This commit is contained in:
Lassulus 2021-08-17 22:36:41 +02:00 committed by GitHub
commit 6a74d5562e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 157 additions and 86 deletions

View File

@ -710,6 +710,7 @@ rec {
mkOptionDefault = mkOverride 1500; # priority of option defaults
mkDefault = mkOverride 1000; # used in config sections of non-user modules to set a default
mkImageMediaOverride = mkOverride 60; # image media profiles can be derived by inclusion into host config, hence needing to override host config, but do allow user to mkForce
mkForce = mkOverride 50;
mkVMOverride = mkOverride 10; # used by nixos-rebuild build-vm

View File

@ -1,7 +1,22 @@
# Building Your Own NixOS CD {#sec-building-cd}
Building a NixOS CD is as easy as configuring your own computer. The idea is to use another module which will replace your `configuration.nix` to configure the system that would be installed on the CD.
# Building a NixOS (Live) ISO {#sec-building-image}
Default CD/DVD configurations are available inside `nixos/modules/installer/cd-dvd`
Default live installer configurations are available inside `nixos/modules/installer/cd-dvd`.
For building other system images, [nixos-generators] is a good place to start looking at.
You have two options:
- Use any of those default configurations as is
- Combine them with (any of) your host config(s)
System images, such as the live installer ones, know how to enforce configuration settings
on wich they immediately depend in order to work correctly.
However, if you are confident, you can opt to override those
enforced values with `mkForce`.
[nixos-generators]: https://github.com/nix-community/nixos-generators
## Practical Instructions {#sec-building-image-instructions}
```ShellSession
$ git clone https://github.com/NixOS/nixpkgs.git
@ -9,10 +24,23 @@ $ cd nixpkgs/nixos
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-minimal.nix default.nix
```
Before burning your CD/DVD, you can check the content of the image by mounting anywhere like suggested by the following command:
To check the content of an ISO image, mount it like so:
```ShellSession
# mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
# mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso
```
If you want to customize your NixOS CD in more detail, or generate other kinds of images, you might want to check out [nixos-generators](https://github.com/nix-community/nixos-generators). This can also be a good starting point when you want to use Nix to build a 'minimal' image that doesn't include a NixOS installation.
## Technical Notes {#sec-building-image-tech-notes}
The config value enforcement is implemented via `mkImageMediaOverride = mkOverride 60;`
and therefore primes over simple value assignments, but also yields to `mkForce`.
This property allows image designers to implement in semantically correct ways those
configuration values upon which the correct functioning of the image depends.
For example, the iso base image overrides those file systems which it needs at a minimum
for correct functioning, while the installer base image overrides the entire file system
layout because there can't be any other guarantees on a live medium than those given
by the live medium itself. The latter is especially true befor formatting the target
block device(s). On the other hand, the netboot iso only overrides its minimum dependencies
since netboot images are always made-to-target.

View File

@ -1,33 +1,72 @@
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-building-cd">
<title>Building Your Own NixOS CD</title>
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-building-image">
<title>Building a NixOS (Live) ISO</title>
<para>
Building a NixOS CD is as easy as configuring your own computer. The
idea is to use another module which will replace your
<literal>configuration.nix</literal> to configure the system that
would be installed on the CD.
Default live installer configurations are available inside
<literal>nixos/modules/installer/cd-dvd</literal>. For building
other system images,
<link xlink:href="https://github.com/nix-community/nixos-generators">nixos-generators</link>
is a good place to start looking at.
</para>
<para>
Default CD/DVD configurations are available inside
<literal>nixos/modules/installer/cd-dvd</literal>
You have two options:
</para>
<programlisting>
<itemizedlist spacing="compact">
<listitem>
<para>
Use any of those default configurations as is
</para>
</listitem>
<listitem>
<para>
Combine them with (any of) your host config(s)
</para>
</listitem>
</itemizedlist>
<para>
System images, such as the live installer ones, know how to enforce
configuration settings on wich they immediately depend in order to
work correctly.
</para>
<para>
However, if you are confident, you can opt to override those
enforced values with <literal>mkForce</literal>.
</para>
<section xml:id="sec-building-image-instructions">
<title>Practical Instructions</title>
<programlisting>
$ git clone https://github.com/NixOS/nixpkgs.git
$ cd nixpkgs/nixos
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-minimal.nix default.nix
</programlisting>
<para>
Before burning your CD/DVD, you can check the content of the image
by mounting anywhere like suggested by the following command:
</para>
<programlisting>
# mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso&lt;/screen&gt;
<para>
To check the content of an ISO image, mount it like so:
</para>
<programlisting>
# mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso
</programlisting>
<para>
If you want to customize your NixOS CD in more detail, or generate
other kinds of images, you might want to check out
<link xlink:href="https://github.com/nix-community/nixos-generators">nixos-generators</link>.
This can also be a good starting point when you want to use Nix to
build a <quote>minimal</quote> image that doesnt include a NixOS
installation.
</para>
</section>
<section xml:id="sec-building-image-tech-notes">
<title>Technical Notes</title>
<para>
The config value enforcement is implemented via
<literal>mkImageMediaOverride = mkOverride 60;</literal> and
therefore primes over simple value assignments, but also yields to
<literal>mkForce</literal>.
</para>
<para>
This property allows image designers to implement in semantically
correct ways those configuration values upon which the correct
functioning of the image depends.
</para>
<para>
For example, the iso base image overrides those file systems which
it needs at a minimum for correct functioning, while the installer
base image overrides the entire file system layout because there
cant be any other guarantees on a live medium than those given by
the live medium itself. The latter is especially true befor
formatting the target block device(s). On the other hand, the
netboot iso only overrides its minimum dependencies since netboot
images are always made-to-target.
</para>
</section>
</chapter>

View File

@ -30,6 +30,11 @@ with lib;
# Add Memtest86+ to the CD.
boot.loader.grub.memtest86.enable = true;
# An installation media cannot tolerate a host config defined file
# system layout on a fresh machine, before it has been formatted.
swapDevices = mkImageMediaOverride [ ];
fileSystems = mkImageMediaOverride config.lib.isoFileSystems;
boot.postBootCommands = ''
for o in $(</proc/cmdline); do
case "$o" in

View File

@ -615,6 +615,55 @@ in
};
# store them in lib so we can mkImageMediaOverride the
# entire file system layout in installation media (only)
config.lib.isoFileSystems = {
"/" = mkImageMediaOverride
{
fsType = "tmpfs";
options = [ "mode=0755" ];
};
# Note that /dev/root is a symlink to the actual root device
# specified on the kernel command line, created in the stage 1
# init script.
"/iso" = mkImageMediaOverride
{ device = "/dev/root";
neededForBoot = true;
noCheck = true;
};
# In stage 1, mount a tmpfs on top of /nix/store (the squashfs
# image) to make this a live CD.
"/nix/.ro-store" = mkImageMediaOverride
{ fsType = "squashfs";
device = "/iso/nix-store.squashfs";
options = [ "loop" ];
neededForBoot = true;
};
"/nix/.rw-store" = mkImageMediaOverride
{ fsType = "tmpfs";
options = [ "mode=0755" ];
neededForBoot = true;
};
"/nix/store" = mkImageMediaOverride
{ fsType = "overlay";
device = "overlay";
options = [
"lowerdir=/nix/.ro-store"
"upperdir=/nix/.rw-store/store"
"workdir=/nix/.rw-store/work"
];
depends = [
"/nix/.ro-store"
"/nix/.rw-store/store"
"/nix/.rw-store/work"
];
};
};
config = {
assertions = [
{
@ -653,54 +702,7 @@ in
"boot.shell_on_fail"
];
fileSystems."/" =
# This module is often over-layed onto an existing host config
# that defines `/`. We use mkOverride 60 to override standard
# values, but at the same time leave room for mkForce values
# targeted at the image build.
{ fsType = mkOverride 60 "tmpfs";
options = [ "mode=0755" ];
};
# Note that /dev/root is a symlink to the actual root device
# specified on the kernel command line, created in the stage 1
# init script.
fileSystems."/iso" =
{ device = "/dev/root";
neededForBoot = true;
noCheck = true;
};
# In stage 1, mount a tmpfs on top of /nix/store (the squashfs
# image) to make this a live CD.
fileSystems."/nix/.ro-store" =
{ fsType = "squashfs";
device = "/iso/nix-store.squashfs";
options = [ "loop" ];
neededForBoot = true;
};
fileSystems."/nix/.rw-store" =
{ fsType = "tmpfs";
options = [ "mode=0755" ];
neededForBoot = true;
};
fileSystems."/nix/store" =
{ fsType = "overlay";
device = "overlay";
options = [
"lowerdir=/nix/.ro-store"
"upperdir=/nix/.rw-store/store"
"workdir=/nix/.rw-store/work"
];
depends = [
"/nix/.ro-store"
"/nix/.rw-store/store"
"/nix/.rw-store/work"
];
};
fileSystems = config.lib.isoFileSystems;
boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "uas" "overlay" ];

View File

@ -29,31 +29,27 @@ with lib;
then []
else [ pkgs.grub2 pkgs.syslinux ]);
fileSystems."/" =
# This module is often over-layed onto an existing host config
# that defines `/`. We use mkOverride 60 to override standard
# values, but at the same time leave room for mkForce values
# targeted at the image build.
{ fsType = mkOverride 60 "tmpfs";
fileSystems."/" = mkImageMediaOverride
{ fsType = "tmpfs";
options = [ "mode=0755" ];
};
# In stage 1, mount a tmpfs on top of /nix/store (the squashfs
# image) to make this a live CD.
fileSystems."/nix/.ro-store" =
fileSystems."/nix/.ro-store" = mkImageMediaOverride
{ fsType = "squashfs";
device = "../nix-store.squashfs";
options = [ "loop" ];
neededForBoot = true;
};
fileSystems."/nix/.rw-store" =
fileSystems."/nix/.rw-store" = mkImageMediaOverride
{ fsType = "tmpfs";
options = [ "mode=0755" ];
neededForBoot = true;
};
fileSystems."/nix/store" =
fileSystems."/nix/store" = mkImageMediaOverride
{ fsType = "overlay";
device = "overlay";
options = [