Skip to content

Latest commit

 

History

History
187 lines (131 loc) · 8.37 KB

install-media.adoc

File metadata and controls

187 lines (131 loc) · 8.37 KB

NixOS installation media

For now, the installation media only targets my main use case which is deploying workstations:

  • UEFI compatible x86_64-linux hosts

  • one physical storage device

🔥

The build of the installation media image is Flake based. You will need to enable flakes for this to work.

All development environment constraints should be guaranteed by the provided nix-shell environment. Issue nix-shell or nix-shell --pure on the command line to start this environment.
This shell will be called the phoenix shell thereafter.

ℹ️
Unless stated otherwise, all relative paths (in particular starting with ./) assume that the current working directory is the project path.

Building the image

In order to build the installation media image, issue phx-build in the phoenix shell.
The resulting ISO image will be available in ./result.iso/iso.

ℹ️
Use the standard NixOS installation media creation procedures to obtain a physical installation media.

Install procedure

Two install procedures are available depending on whether a NixOS configuration flake is available or not for the platform:

  • the new host install procedure is for unconfigured platforms with no existing NixOS configuration to apply

  • the flake install procedure is for platforms registered in a reachable flake configuration

New host install

Boot the target on the installation media. Once the boot sequence is complete and the command prompt is available, enter the following commands on the target:

sudo setup-storage <block device>
sudo generate-configuration
sudo nixos-install
sudo reboot
ℹ️

<block device> is the device file pointing to the storage where to install the new NixOS operating system.

It should be /dev/vda when testing the installation media image with phx-test (see Testing).

Flake install

Follow the same procedure as in New host install but with the following commands on the target:

sudo setup-storage <block device>
# A network connection is needed for the next step, to setup Wi-Fi:
# nmcli device wifi connect <SSID> password <password>
sudo nixos-install --flake <flake URI>#<hostname>
sudo reboot
ℹ️
For testing purposes, you can use the following flake configuration:
github:gautaz/phoenix#testbox

The setup-storage command

The goal of the setup-storage command is to ensure the following layout on a block device:

  1. boot as the FAT32 partition used by UEFI

  2. pv as the LUKS encrypted device that contains a LVM physical volume which will be part of a volume group named vg containing:

    • a logical volume named swap holding the swap space

    • a logical volume named system containing a Btrfs filesystem separated in subvolumes:

      • root as the root filesystem

      • home as the users home directories

      • nix as the operating system’s Nix store

ℹ️

The main reasons for this layout are:

  • most x86_64 workstations systems now supports UEFI

  • btrfs ensures subvolumes isolation while avoiding the hassle to allocate space per subvolumes (which is not a top priority on a workstation)

  • LVM was needed because I was unable to get hibernation working with swap on btrfs

The only argument required by the command is the block device on which to install the storage layout. After a few verifications, setup-storage will ask the following questions:

Enter passphrase for <path of pv device>:
Enter passphrase for /dev/disk/by-label/pv:
ℹ️
<path of pv device> is the second partition on the device provided as an argument to setup-storage.

The first password asked is the one used by LUKS to encrypt the pv device.
The second password asked must be the same as the first one as it is used by LUKS to open the pv device (/dev/disk/by-label/pv is in fact a symbolic link to <path of pv device>).

Asking the same password twice offers the additional guarantee that no password misspell occurred.

ℹ️
In case of a password mismatch, simply issue the setup-storage command again to start over.

The generate-configuration command

Usually having UUIDs in the hardware-configuration.nix file is not an issue until this file is kept in a git repository for reuse. The goal of the generate-configuration command is to avoid identifying the target’s devices in the /mnt/etc/nixos/hardware-configuration.nix file with UUIDs.

As the setup-storage command ensures that all devices are accessible through labels, generate-configuration will simply:

  1. generate the target NixOS configuration with nixos-generate-config --root /mnt

  2. replace all UUIDs generated by nixos-generate-config with their corresponding labels

Once the target is successfully deployed, the hardware-configuration.nix file can be kept in configuration in a repository for future use (flake deployment for instance).

ℹ️
generate-configuration will also ensure that LUKS opens /dev/disk/by-label/pv on boot to work around this issue.

Testing

In order to test the installation media image, issue phx-test to start a test virtual machine from the phoenix shell. The test VM uses TianoCore UEFI implementation as the installation media is primarily targeted at systems supporting UEFI.

Once the test VM has started, it will boot:

  • either on the installation media if no successful install occurred previously

  • or on a previously successfully installed NixOS system (to discard it simply issue rm ./disk.qcow2 in a command shell)

If the installation media has started, issue the commands from the Install procedure section on the virtual machine console.

⚠️
Do NOT use these commands on your current host shell, as they may mess up your host operating system if it is NixOS based.

Mounting the test VM filesystems

In order to mount the test VM filesystems on the development host, issue the following command in a phoenix shell:

sudo phx-mount <mountpoint>

Where <mountpoint> must be a previously created directory.

In order to later unmount the test VM filesystems, issue the following command in a phoenix shell:

sudo phx-umount <mountpoint>

Roadmap

  • ✓ Initial extensible ISO image (implemented by the initial revision)

  • ✓ Tooling to prepare the local storage (implemented by setup-storage)

  • ✓ Tooling to install NixOS (nothing to do, standard NixOS install simply works)

  • ✓ Tooling to make hardware-configuration.nix more generic

  • ✓ Tooling to mount test filesystems on the host

  • ✓ Tooling to install the NixOS configuration from a flake on a Git server (done with nixos-install --flake)

  • ✓ Add a shell.nix file to ensure project’s requirements with nix-shell

  • ✓ Ensure hibernate is possible

  • ❏ Override nixos-generate-config with generate-configuration (and also make it available for installed flake configurations)

  • ❏ Optionally replace LUKS password by a FIDO2 compatible dongle