NixOS Root on ZFS: use Nix-config for multi-disk

NixOS has enjoyed popularity among ZFS users thanks to
its declarative configuration and native ZFS support.
However, the installation guide used hardcoded disk
names in configuration files, which is unnecessary and
is the source of difficulties in multidisk setups.

The guide is now rewritten to leverage expressions in
the Nix language to manage multidisk setups.

Also adds instruction on replacing failed disk.

Closes #385.

Signed-off-by: Maurice Zhou <ja@apvc.uk>
This commit is contained in:
Maurice Zhou
2023-02-10 16:40:30 +01:00
committed by George Melikov
parent d8713058b3
commit cc6d72c02d
5 changed files with 651 additions and 84 deletions

View File

@@ -8,7 +8,7 @@ Preparation
#. Disable Secure Boot. ZFS modules can not be loaded if Secure Boot is enabled.
#. Download `NixOS Live Image
<https://channels.nixos.org/nixos-22.05/latest-nixos-gnome-x86_64-linux.iso>`__ and boot from it.
<https://nixos.org/download.html#download-nixos>`__ and boot from it.
#. Connect to the Internet.
#. Set root password or ``/root/.ssh/authorized_keys``.
#. Start SSH server::
@@ -17,15 +17,15 @@ Preparation
#. Connect from another computer::
ssh root@192.168.1.19
ssh root@192.168.1.91
#. Target disk
List available disks with::
ls /dev/disk/by-id/*
find /dev/disk/by-id/
If using virtio as disk bus, use ``/dev/disk/by-path/*``.
If using virtio as disk bus, use ``/dev/disk/by-path/``.
Declare disk array::
@@ -37,11 +37,10 @@ Preparation
#. Set partition size:
Set swap size. It's `recommended <https://chrisdown.name/2018/01/02/in-defence-of-swap.html>`__
to setup a swap partition. If you intend to use hibernation,
the minimum should be no less than RAM size. Skip if swap is not needed::
Set swap size, set to 1 if you don't want swap to
take up too much space::
INST_PARTSIZE_SWAP=8
INST_PARTSIZE_SWAP=4
Root pool size, use all remaining disk space if not set::

View File

@@ -16,7 +16,7 @@ System Installation
sgdisk -n2:0:+4G -t2:BE00 $i
test -z $INST_PARTSIZE_SWAP || sgdisk -n4:0:+${INST_PARTSIZE_SWAP}G -t4:8200 $i
sgdisk -n4:0:+${INST_PARTSIZE_SWAP}G -t4:8200 $i
if test -z $INST_PARTSIZE_RPOOL; then
sgdisk -n3:0:0 -t3:BF00 $i
@@ -25,6 +25,12 @@ System Installation
fi
sgdisk -a1 -n5:24K:+1000K -t5:EF02 $i
sync && udevadm settle && sleep 3
cryptsetup open --type plain --key-file /dev/random $i-part4 ${i##*/}-part4
mkswap /dev/mapper/${i##*/}-part4
swapon /dev/mapper/${i##*/}-part4
done
#. Create boot pool::
@@ -84,9 +90,7 @@ System Installation
If not using a multi-disk setup, remove ``mirror``.
#. This section implements dataset layout as described in `overview <1-preparation.html>`__.
Create root system container:
#. Create root system container:
- Unencrypted::
@@ -108,18 +112,25 @@ System Installation
-o keyformat=passphrase \
rpool/nixos
Create system datasets::
You can automate this step (insecure) with: ``echo POOLPASS | zfs create ...``.
zfs create -o canmount=on -o mountpoint=/ rpool/nixos/root
zfs create -o canmount=on -o mountpoint=/home rpool/nixos/home
zfs create -o canmount=off -o mountpoint=/var rpool/nixos/var
zfs create -o canmount=on rpool/nixos/var/lib
zfs create -o canmount=on rpool/nixos/var/log
Create system datasets, let NixOS declaratively
manage mountpoints with ``mountpoint=legacy``::
Create boot dataset::
zfs create -o canmount=off -o mountpoint=none bpool/nixos
zfs create -o canmount=on -o mountpoint=/boot bpool/nixos/root
zfs create -o mountpoint=legacy rpool/nixos/root
mount -t zfs rpool/nixos/root /mnt/
zfs create -o mountpoint=legacy rpool/nixos/home
mkdir /mnt/home
mount -t zfs rpool/nixos/home /mnt/home
zfs create -o mountpoint=legacy rpool/nixos/var
zfs create -o mountpoint=legacy rpool/nixos/var/lib
zfs create -o mountpoint=legacy rpool/nixos/var/log
zfs create -o mountpoint=none bpool/nixos
zfs create -o mountpoint=legacy bpool/nixos/root
mkdir /mnt/boot
mount -t zfs bpool/nixos/root /mnt/boot
zfs create -o mountpoint=legacy rpool/nixos/empty
zfs snapshot rpool/nixos/empty@start
#. Format and mount ESP::

View File

@@ -6,83 +6,48 @@ System Configuration
.. contents:: Table of Contents
:local:
#. Generate initial system configuration::
#. Download system configuration from this repo::
nixos-generate-config --root /mnt
mkdir -p /mnt/etc/nixos/
curl -o /mnt/etc/nixos/configuration.nix -L \
https://github.com/openzfs/openzfs-docs/raw/master/docs/Getting%20Started/NixOS/Root%20on%20ZFS/configuration.nix
#. Import ZFS-specific configuration::
#. Customize configuration to your hardware::
sed -i "s|./hardware-configuration.nix|./hardware-configuration.nix ./zfs.nix|g" /mnt/etc/nixos/configuration.nix
for i in $DISK; do
sed -i \
"s|PLACEHOLDER_FOR_DEV_NODE_PATH|\"${i%/*}/\"|" \
/mnt/etc/nixos/configuration.nix
break
done
#. Configure hostid::
tee -a /mnt/etc/nixos/zfs.nix <<EOF
{ config, pkgs, ... }:
{ boot.supportedFilesystems = [ "zfs" ];
networking.hostId = "$(head -c 8 /etc/machine-id)";
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
diskNames=""
for i in $DISK; do
diskNames="$diskNames \"${i##*/}\""
done
tee -a /mnt/etc/nixos/machine.nix <<EOF
{
bootDevices = [ $diskNames ];
}
EOF
#. Configure bootloader for both legacy boot and UEFI boot and mirror bootloader::
sed -i '/boot.loader/d' /mnt/etc/nixos/configuration.nix
sed -i '/services.xserver/d' /mnt/etc/nixos/configuration.nix
tee -a /mnt/etc/nixos/zfs.nix <<EOF
boot.loader.efi.efiSysMountPoint = "/boot/efis/$(echo $DISK | cut -f1 -d\ | sed 's|/dev/disk/by-id/||')-part1";
EOF
tee -a /mnt/etc/nixos/zfs.nix <<-'EOF'
boot.loader.efi.canTouchEfiVariables = false;
boot.loader.generationsDir.copyKernels = true;
boot.loader.grub.efiInstallAsRemovable = true;
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.copyKernels = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.zfsSupport = true;
boot.loader.grub.extraInstallCommands = ''
ESP_MIRROR=$(mktemp -d)
cp -r ${config.boot.loader.efi.efiSysMountPoint}/EFI $ESP_MIRROR
for i in /boot/efis/*; do
cp -r $ESP_MIRROR/EFI $i
done
rm -rf $ESP_MIRROR
'';
boot.loader.grub.devices = [
EOF
for i in $DISK; do
printf " \"$i\"\n" >>/mnt/etc/nixos/zfs.nix
done
tee -a /mnt/etc/nixos/zfs.nix <<EOF
];
EOF
#. Mount datasets with zfsutil option::
sed -i 's|fsType = "zfs";|fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];|g' \
/mnt/etc/nixos/hardware-configuration.nix
#. Mount EFI partitions on demand::
sed -i 's|fsType = "vfat";|fsType = "vfat"; options = [ "x-systemd.idle-timeout=1min" "x-systemd.automount" "noauto" "nofail" ];|g' \
/mnt/etc/nixos/hardware-configuration.nix
#. Set root password::
rootPwd=$(mkpasswd -m SHA-512 -s)
Declare password in configuration::
tee -a /mnt/etc/nixos/zfs.nix <<EOF
users.users.root.initialHashedPassword = "${rootPwd}";
}
EOF
sed -i \
"s|PLACEHOLDER_FOR_ROOT_PWD_HASH|\""${rootPwd}"\"|" \
/mnt/etc/nixos/configuration.nix
#. Optional: enable NetworkManager for easier wireless configuration and enable desktop
environments. See ``man configuration.nix`` for details. By default, the system is
installed without any other software.
#. Install system and apply configuration::
nixos-install -v --show-trace --no-root-passwd --root /mnt
nixos-install --no-root-passwd --root /mnt
#. Unmount filesystems::
@@ -92,3 +57,116 @@ System Configuration
#. Reboot::
reboot
#. Optional: manage system configuration with git.
#. Optional: immutable root filesystem can be enabled by
using this `configuration file
<https://github.com/openzfs/openzfs-docs/raw/master/docs/Getting%20Started/NixOS/Root%20on%20ZFS/configuration-immutable.nix>`__.
Apply your own hardware configuration in this file,
then execute::
nixos-rebuild boot
Then reboot. You may need to make certain
adjustments to where configuration files are stored,
see `NixOS wiki <https://nixos.wiki/wiki/ZFS>`__ for
details.
Replace a failed disk
=====================
When a disk fails in a mirrored setup, the disk can be
replaced with the following procedure.
#. Shutdown the computer.
#. Replace the failed disk with another disk. The
replacement should be at least the same size or
larger than the failed disk.
#. Boot the computer. When a disk fails, the system will boot, albeit
several minutes slower than normal. This is due to
the initrd and systemd designed to only import a pool
in degraded state after a 90s timeout. Swap
partition on that disk will also fail.
#. Launch a ephemeral nix shell with gptfdisk::
nix-shell -p gptfdisk
#. Identify the bad disk and a working old disk::
ZPOOL_VDEV_NAME_PATH=1 zpool status
pool: bpool
status: DEGRADED
action: Replace the device using 'zpool replace'.
...
config: bpool
mirror-0
2387489723748 UNAVAIL 0 0 0 was /dev/disk/by-id/ata-BAD-part2
/dev/disk/by-id/ata-OLD-part2 ONLINE 0 0 0
#. Store the bad disk and a working old disk in a variable, omit the partition number ``-partN``::
BAD=/dev/disk/by-id/ata-BAD
OLD=/dev/disk/by-id/ata-OLD
#. Identify the new disk::
find /dev/disk/by-id/
/dev/disk/by-id/ata-OLD-part1
/dev/disk/by-id/ata-OLD-part2
...
/dev/disk/by-id/ata-OLD-part5
/dev/disk/by-id/ata-NEW <-- new disk w/o partition table
#. Store the new disk in a variable::
NEW=/dev/disk/by-id/ata-NEW
#. Replicate partition table on the new disk::
sgdisk -Z $NEW
sgdisk --backup=backup $OLD
sgdisk --load-backup=backup $NEW
sgdisk --randomize-guids $NEW
#. If the new disk is larger than the old disk, expand root pool partition size::
sgdisk --delete=3 $NEW
# expand to all remaining disk space
sgdisk -n3:0:0 -t3:BF00 $NEW
Note that this space will only become available once all disks in the mirrored pool are
replaced with larger disks.
#. Format and mount EFI system partition::
mkfs.vfat -n EFI ${NEW}-part1
mkdir -p /boot/efis/${NEW##*/}-part1
mount -t vfat ${NEW}-part1 /boot/efis/${NEW##*/}-part1
#. Replace failed disk in pool::
zpool offline bpool ${BAD}-part2
zpool offline rpool ${BAD}-part3
zpool replace bpool ${BAD}-part2 ${NEW}-part2
zpool replace rpool ${BAD}-part3 ${NEW}-part3
zpool online bpool ${NEW}-part2
zpool online rpool ${NEW}-part3
Let the new disk resilver. Check status with ``zpool status``.
#. Update NixOS system configuration::
sed -i "s|${BAD##*/}|${NEW##*/}|" /etc/nixos/machine.nix
#. Apply the updated NixOS system configuration, reinstall bootloader, then reboot::
nixos-rebuild boot --install-bootloader
reboot

View File

@@ -0,0 +1,252 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, lib, pkgs, modulesPath, ... }:
let
zfsRoot.partitionScheme = {
biosBoot = "-part5";
efiBoot = "-part1";
swap = "-part4";
bootPool = "-part2";
rootPool = "-part3";
};
zfsRoot.devNodes = PLACEHOLDER_FOR_DEV_NODE_PATH; # MUST have trailing slash! /dev/disk/by-id/
zfsRoot.bootDevices = (import ./machine.nix).bootDevices;
zfsRoot.mirroredEfi = "/boot/efis/";
in {
# adjust according to your platform, such as
imports = [
# (modulesPath + "/profiles/qemu-guest.nix")
# (modulesPath + "/profiles/all-hardware.nix")
(modulesPath + "/installer/scan/not-detected.nix")
];
systemd.services.zfs-mount.enable = false;
# networking.hostName = "nixos"; # Define your hostname.
# Pick only one of the below networking options.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
# Set your time zone.
# time.timeZone = "Europe/Amsterdam";
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
# i18n.defaultLocale = "en_US.UTF-8";
# console = {
# font = "Lat2-Terminus16";
# keyMap = "us";
# useXkbConfig = true; # use xkbOptions in tty.
# };
# Enable the X11 windowing system.
# Configure keymap in X11
# "eurosign:e";
# "caps:escape" # map caps to escape.
# };
# Enable CUPS to print documents.
# services.printing.enable = true;
# Enable sound.
# sound.enable = true;
# hardware.pulseaudio.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
# Define a user account. Don't forget to set a password with passwd.
# users.users.alice = {
# isNormalUser = true;
# extraGroups = [ "wheel" ]; # Enable sudo for the user.
# packages = with pkgs; [
# firefox
# thunderbird
# ];
# };
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs;
[
# vim
## Do not forget to add an editor to edit configuration.nix!
## The Nano editor is also installed by default.
# wget
mg
];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = false;
users.users.root = {
##hash: mkpasswd -m SHA-512 -s
initialHashedPassword = PLACEHOLDER_FOR_ROOT_PWD_HASH;
openssh.authorizedKeys.keys = [
];
};
programs.git.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
system.copySystemConfiguration = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.11"; # Did you read the comment?
boot.initrd.availableKernelModules = [
"ahci"
"xhci_pci"
"virtio_pci"
"virtio_blk"
"ehci_pci"
"nvme"
"uas"
"sd_mod"
"sr_mod"
"sdhci_pci"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems = {
"/" = {
device = "rpool/nixos/empty";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
"/oldroot" = {
device = "rpool/nixos/root";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
neededForBoot = true;
};
"/nix" = {
device = "/oldroot/nix";
fsType = "none";
options = [ "bind" "X-mount.mkdir" ];
};
"/etc/nixos" = {
device = "/oldroot/etc/nixos";
fsType = "none";
options = [ "bind" "X-mount.mkdir" ];
};
"/home" = {
device = "rpool/nixos/home";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
"/var/lib" = {
device = "rpool/nixos/var/lib";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
"/var/log" = {
device = "rpool/nixos/var/log";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
"/boot" = {
device = "bpool/nixos/root";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
} // (builtins.listToAttrs (map (diskName: {
name = zfsRoot.mirroredEfi + diskName + zfsRoot.partitionScheme.efiBoot;
value = {
device = zfsRoot.devNodes + diskName + zfsRoot.partitionScheme.efiBoot;
fsType = "vfat";
options = [
"x-systemd.idle-timeout=1min"
"x-systemd.automount"
"noauto"
"nofail"
];
};
}) zfsRoot.bootDevices));
swapDevices = (map (diskName: {
device = zfsRoot.devNodes + diskName + zfsRoot.partitionScheme.swap;
discardPolicy = "both";
randomEncryption = {
enable = true;
allowDiscards = true;
};
}) zfsRoot.bootDevices);
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.networkmanager.enable = true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode =
lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware.cpu.amd.updateMicrocode =
lib.mkDefault config.hardware.enableRedistributableFirmware;
boot.supportedFilesystems = [ "zfs" ];
networking.hostId = "abcd1234";
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
boot.loader.efi.efiSysMountPoint = with builtins;
(zfsRoot.mirroredEfi + (head zfsRoot.bootDevices) + zfsRoot.partitionScheme.efiBoot);
boot.zfs.devNodes = zfsRoot.devNodes;
boot.loader.efi.canTouchEfiVariables = false;
boot.loader.generationsDir.copyKernels = true;
boot.loader.grub.efiInstallAsRemovable = true;
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.copyKernels = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.zfsSupport = true;
boot.loader.grub.extraInstallCommands = with builtins;
(toString (map (diskName:
"cp -r " + config.boot.loader.efi.efiSysMountPoint + "/EFI" + " "
+ zfsRoot.mirroredEfi + diskName + zfsRoot.partitionScheme.efiBoot + "\n")
(tail zfsRoot.bootDevices)));
boot.loader.grub.devices =
(map (diskName: zfsRoot.devNodes + diskName) zfsRoot.bootDevices);
boot.initrd.postDeviceCommands = ''
zpool import -Nf rpool
zfs rollback -r rpool/nixos/empty@start
zpool export -a
'';
}

View File

@@ -0,0 +1,227 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, lib, pkgs, modulesPath, ... }:
let
zfsRoot.partitionScheme = {
biosBoot = "-part5";
efiBoot = "-part1";
swap = "-part4";
bootPool = "-part2";
rootPool = "-part3";
};
zfsRoot.devNodes = PLACEHOLDER_FOR_DEV_NODE_PATH; # MUST have trailing slash! /dev/disk/by-id/
zfsRoot.bootDevices = (import ./machine.nix).bootDevices;
zfsRoot.mirroredEfi = "/boot/efis/";
in {
# adjust according to your platform, such as
imports = [
# (modulesPath + "/profiles/qemu-guest.nix")
# (modulesPath + "/profiles/all-hardware.nix")
(modulesPath + "/installer/scan/not-detected.nix")
];
systemd.services.zfs-mount.enable = false;
# networking.hostName = "nixos"; # Define your hostname.
# Pick only one of the below networking options.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
# Set your time zone.
# time.timeZone = "Europe/Amsterdam";
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
# i18n.defaultLocale = "en_US.UTF-8";
# console = {
# font = "Lat2-Terminus16";
# keyMap = "us";
# useXkbConfig = true; # use xkbOptions in tty.
# };
# Enable the X11 windowing system.
# Configure keymap in X11
# "eurosign:e";
# "caps:escape" # map caps to escape.
# };
# Enable CUPS to print documents.
# services.printing.enable = true;
# Enable sound.
# sound.enable = true;
# hardware.pulseaudio.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
# Define a user account. Don't forget to set a password with passwd.
# users.users.alice = {
# isNormalUser = true;
# extraGroups = [ "wheel" ]; # Enable sudo for the user.
# packages = with pkgs; [
# firefox
# thunderbird
# ];
# };
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs;
[
# vim
## Do not forget to add an editor to edit configuration.nix!
## The Nano editor is also installed by default.
# wget
mg
];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = false;
users.users.root = {
##hash: mkpasswd -m SHA-512 -s
initialHashedPassword = PLACEHOLDER_FOR_ROOT_PWD_HASH;
openssh.authorizedKeys.keys = [
];
};
programs.git.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
system.copySystemConfiguration = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.11"; # Did you read the comment?
boot.initrd.availableKernelModules = [
"ahci"
"xhci_pci"
"virtio_pci"
"virtio_blk"
"ehci_pci"
"nvme"
"uas"
"sd_mod"
"sr_mod"
"sdhci_pci"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems = {
"/" = {
device = "rpool/nixos/root";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
"/home" = {
device = "rpool/nixos/home";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
"/var/lib" = {
device = "rpool/nixos/var/lib";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
"/var/log" = {
device = "rpool/nixos/var/log";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
"/boot" = {
device = "bpool/nixos/root";
fsType = "zfs";
options = [ "X-mount.mkdir" ];
};
} // (builtins.listToAttrs (map (diskName: {
name = zfsRoot.mirroredEfi + diskName + zfsRoot.partitionScheme.efiBoot;
value = {
device = zfsRoot.devNodes + diskName + zfsRoot.partitionScheme.efiBoot;
fsType = "vfat";
options = [
"x-systemd.idle-timeout=1min"
"x-systemd.automount"
"noauto"
"nofail"
];
};
}) zfsRoot.bootDevices));
swapDevices = (map (diskName: {
device = zfsRoot.devNodes + diskName + zfsRoot.partitionScheme.swap;
discardPolicy = "both";
randomEncryption = {
enable = true;
allowDiscards = true;
};
}) zfsRoot.bootDevices);
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.networkmanager.enable = true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode =
lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware.cpu.amd.updateMicrocode =
lib.mkDefault config.hardware.enableRedistributableFirmware;
boot.supportedFilesystems = [ "zfs" ];
networking.hostId = "abcd1234";
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
boot.loader.efi.efiSysMountPoint = with builtins;
(zfsRoot.mirroredEfi + (head zfsRoot.bootDevices) + zfsRoot.partitionScheme.efiBoot);
boot.zfs.devNodes = zfsRoot.devNodes;
boot.loader.efi.canTouchEfiVariables = false;
boot.loader.generationsDir.copyKernels = true;
boot.loader.grub.efiInstallAsRemovable = true;
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.copyKernels = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.zfsSupport = true;
boot.loader.grub.extraInstallCommands = with builtins;
(toString (map (diskName:
"cp -r " + config.boot.loader.efi.efiSysMountPoint + "/EFI" + " "
+ zfsRoot.mirroredEfi + diskName + zfsRoot.partitionScheme.efiBoot + "\n")
(tail zfsRoot.bootDevices)));
boot.loader.grub.devices =
(map (diskName: zfsRoot.devNodes + diskName) zfsRoot.bootDevices);
}