diff options
author | Lassulus <github@lassul.us> | 2021-08-17 22:36:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-17 22:36:41 +0200 |
commit | 6a74d5562e76748bc8f51a9c647d305591cec144 (patch) | |
tree | cab96e958026d7c58c3df5e262e48c18e3a6cf24 /nixos | |
parent | cac66b3b96d76856f1e7c504554c75739b1c065b (diff) | |
parent | 2937038bf36a50993a7548e9ba805332db8a0910 (diff) |
Merge pull request #132583 from blaggacao/fix/soft-force-the-file-system-layout-for-boot-media
nixos/boot-media: soft-force entire fs layout
Diffstat (limited to 'nixos')
5 files changed, 156 insertions, 86 deletions
diff --git a/nixos/doc/manual/development/building-nixos.chapter.md b/nixos/doc/manual/development/building-nixos.chapter.md index 699a75f41152..3310dee98f96 100644 --- a/nixos/doc/manual/development/building-nixos.chapter.md +++ b/nixos/doc/manual/development/building-nixos.chapter.md @@ -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. diff --git a/nixos/doc/manual/from_md/development/building-nixos.chapter.xml b/nixos/doc/manual/from_md/development/building-nixos.chapter.xml index ceb744447dab..ad9349da0686 100644 --- a/nixos/doc/manual/from_md/development/building-nixos.chapter.xml +++ b/nixos/doc/manual/from_md/development/building-nixos.chapter.xml @@ -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</screen> + <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 doesn’t 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 + 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. + </para> + </section> </chapter> diff --git a/nixos/modules/installer/cd-dvd/installation-cd-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-base.nix index aecb65b8c576..618057618d0c 100644 --- a/nixos/modules/installer/cd-dvd/installation-cd-base.nix +++ b/nixos/modules/installer/cd-dvd/installation-cd-base.nix @@ -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 diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index f03845132476..78cbf14bbaf6 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -615,57 +615,19 @@ in }; - config = { - assertions = [ + # store them in lib so we can mkImageMediaOverride the + # entire file system layout in installation media (only) + config.lib.isoFileSystems = { + "/" = mkImageMediaOverride { - assertion = !(stringLength config.isoImage.volumeID > 32); - # https://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor - # Volume Identifier can only be 32 bytes - message = let - length = stringLength config.isoImage.volumeID; - howmany = toString length; - toomany = toString (length - 32); - in - "isoImage.volumeID ${config.isoImage.volumeID} is ${howmany} characters. That is ${toomany} characters longer than the limit of 32."; - } - ]; - - boot.loader.grub.version = 2; - - # Don't build the GRUB menu builder script, since we don't need it - # here and it causes a cyclic dependency. - boot.loader.grub.enable = false; - - environment.systemPackages = [ grubPkgs.grub2 grubPkgs.grub2_efi ] - ++ optional canx86BiosBoot pkgs.syslinux - ; - - # In stage 1 of the boot, mount the CD as the root FS by label so - # that we don't need to know its device. We pass the label of the - # root filesystem on the kernel command line, rather than in - # `fileSystems' below. This allows CD-to-USB converters such as - # UNetbootin to rewrite the kernel command line to pass the label or - # UUID of the USB stick. It would be nicer to write - # `root=/dev/disk/by-label/...' here, but UNetbootin doesn't - # recognise that. - boot.kernelParams = - [ "root=LABEL=${config.isoImage.volumeID}" - "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"; + 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. - fileSystems."/iso" = + "/iso" = mkImageMediaOverride { device = "/dev/root"; neededForBoot = true; noCheck = true; @@ -673,20 +635,20 @@ in # In stage 1, mount a tmpfs on top of /nix/store (the squashfs # image) to make this a live CD. - fileSystems."/nix/.ro-store" = + "/nix/.ro-store" = mkImageMediaOverride { fsType = "squashfs"; device = "/iso/nix-store.squashfs"; options = [ "loop" ]; neededForBoot = true; }; - fileSystems."/nix/.rw-store" = + "/nix/.rw-store" = mkImageMediaOverride { fsType = "tmpfs"; options = [ "mode=0755" ]; neededForBoot = true; }; - fileSystems."/nix/store" = + "/nix/store" = mkImageMediaOverride { fsType = "overlay"; device = "overlay"; options = [ @@ -694,13 +656,53 @@ in "upperdir=/nix/.rw-store/store" "workdir=/nix/.rw-store/work" ]; - depends = [ "/nix/.ro-store" "/nix/.rw-store/store" "/nix/.rw-store/work" ]; }; + }; + + config = { + assertions = [ + { + assertion = !(stringLength config.isoImage.volumeID > 32); + # https://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor + # Volume Identifier can only be 32 bytes + message = let + length = stringLength config.isoImage.volumeID; + howmany = toString length; + toomany = toString (length - 32); + in + "isoImage.volumeID ${config.isoImage.volumeID} is ${howmany} characters. That is ${toomany} characters longer than the limit of 32."; + } + ]; + + boot.loader.grub.version = 2; + + # Don't build the GRUB menu builder script, since we don't need it + # here and it causes a cyclic dependency. + boot.loader.grub.enable = false; + + environment.systemPackages = [ grubPkgs.grub2 grubPkgs.grub2_efi ] + ++ optional canx86BiosBoot pkgs.syslinux + ; + + # In stage 1 of the boot, mount the CD as the root FS by label so + # that we don't need to know its device. We pass the label of the + # root filesystem on the kernel command line, rather than in + # `fileSystems' below. This allows CD-to-USB converters such as + # UNetbootin to rewrite the kernel command line to pass the label or + # UUID of the USB stick. It would be nicer to write + # `root=/dev/disk/by-label/...' here, but UNetbootin doesn't + # recognise that. + boot.kernelParams = + [ "root=LABEL=${config.isoImage.volumeID}" + "boot.shell_on_fail" + ]; + + fileSystems = config.lib.isoFileSystems; boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "uas" "overlay" ]; diff --git a/nixos/modules/installer/netboot/netboot.nix b/nixos/modules/installer/netboot/netboot.nix index f7543fdf4a23..28b6c39b29df 100644 --- a/nixos/modules/installer/netboot/netboot.nix +++ b/nixos/modules/installer/netboot/netboot.nix @@ -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 = [ |