Partitioning NixOS with Disko
Published: 2024-03-27 • Reading time: 5 min
#linux #nixos #disko #sysadminAbout a month ago I decided to spend my free time getting more familiar with NixOS. In order to install NixOS, I needed to figure out what Linux Partitioning scheme I would use. Rather than manually partitioning, I decided I would dive straight into learning Disko the declarative disk partitioning system.
Diving into Disko ended up being quite an adventure, as I suspect much of my exploration of NixOS will be. I'm not content to simple type magic incantations into a configuration file, but rather I want to know what each magic incantation does. Let me share with you my journey, what I've learned so far, and my Disko configuration.
Exploring NixOS seems to be deeply rooted in "mess around and find out." There's a common thread across the Internet that NixOS documentation is lacking, especially when compared to Arch Linux which mostly has outstanding documentation. Fortunately, messing around and finding out seems to be a pretty normal pattern for me to learn new things and something I mostly enjoy.
Still, I can't decide if the time I'm investing in trying to figure out how Disko works for partitioning is worth the investment. I could have just used parted, pvcreate, vgcreate, lvcreate, mkfs and been done already.
Building my Disko Configuration
In my initial exploration of the example configurations in the Disko git repository I can't shake the feeling that there's quite a bit of TIMTOWTDI (There Is More Than One Way To Do It, the reason why Perl scripts are so easy to write and so difficult to read) with Disko configuration. Is there an advantage to using start and end when specifying partitions, or is size good enough. I'm not sure I care about the start and end assuming Disko is smart enough to align the partitions.
I ended up diving into the Disko source code to get a better feel for the differences between start, end, and size. Here I discovered my first surprise: Disko is written in the Nix language. It felt like a moment where I discovered it's "turtles all the way down."
As I dug through the source I ran into a valuable comment from /lib/types/table.nix: The legacy table is outdated and should not be used. We recommend using the gpt type instead. This helped invalidate various Disko configurations I was looking at that were still using table.
As I continued to scan the source code I was particularly interested in how Disko would handle LVM configuration, as I had already decided that I would be using LVM as part of my partition configuration. Disko has a type for lvm_pv and lvm_vg but not lvm_lv. Within lvm_vg there's an lvs item where you specify your logical volumes.
As a reminder, my partition scheme:
/dev/sda1 -- /boot, 1 GB, FAT32
/dev/sda2 -- (LVM vg1), the rest, LVM
- /dev/vg1/swap -- (swap), 8G, swap
- /dev/vg1/nix -- /nix, 50G, ext4
- /dev/vg1/root -- /, the rest, ext4
Based on the above, I was able to build the Disko configuration below:
{
disko.devices = {
disk.sda = {
type = "disk";
device = "/dev/sda";
content = {
type = "gpt"; # Initialize the disk with a GPT partition table
partitions = {
ESP = { # Setup the EFI System Partition
type = "EF00"; # Set the partition type
size = "1000M"; # Make the partition a gig
content = {
type = "filesystem";
format = "vfat"; # Format it as a FAT32 filesystem
mountpoint = "/boot"; # Mount it to /boot
};
};
primary = { # Setup the LVM partition
size = "100%"; # Fill up the rest of the drive with it
content = {
type = "lvm_pv"; # pvcreate
vg = "vg1";
};
};
};
};
};
lvm_vg = { # vgcreate
vg1 = { # /dev/vg1
type = "lvm_vg";
lvs = { # lvcreate
swap = { # Logical Volume = "swap", /dev/vg1/swap
size = "8G";
content = {
type = "swap";
};
};
nix = { # Logical Volume = "nix", /dev/vg1/nix
size = "50G";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/nix";
mountOptions = [
"noatime" # Reduce writes--we don't care about access times
];
};
};
root = { # Logical Volume = "root", /dev/vg1/root
size = "100%FREE"; # Use the remaining space in the Volume Group
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [
"defaults"
];
};
};
};
};
};
};
}
How to run Disko
The configuration file alone isn't enough to get the partitions created. You've got to actually run Disko.
- First, you need to boot up the NixOS installer.
- I stored my
disko-config.nixas a gist on GitHub. Seemed like as good as place as any to host it. - I created a TinyURL shortcut for that link because there's no way I'm going to attempt to type that whole URL.
- Download the file using
curl. Switch-Lwill follow redirects,-ospecifies the file to store the output. My URL is a direct link raw disko-config.nix from GitHub.curl -L <url> -o /tmp/disko-config.nix
- Run disko:
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko /tmp/disko-config.nix- There's a couple of modes
--mode diskowill unmount and destroy all filesystems on the disks we want to format before creating and mounting our filesystems specified in the config file--mode formatwill create partition tables, logical volumes, and filesystems--mode mountwill mount the partition at the specified root-mountpoint- I'm not sure when the
formatandmountoptions are useful. I didn't try either.
- Complete the NixOS install
nixos-generate-config --no-filesystems --root /mnt- The
--no-filesystemsswitch is used because we're defining the filesystems in disko-config.nix.
- The
cp /tmp/disko-config.nix /mnt/etc/nixos- Copy our disko config to the future /etc/nixos directory.
- Edit
/mnt/etc/nixos/configuration.nixto add thediskoNixOS module and ourdisko-config.nixfile to the imports section:
imports =
[
./hardware-configuration.nix
"${builtins.fetchTarball} "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix"
./disko-config.nix
];
- And finally:
- Edit additional options in
/mnt/etc/nixos/configuration.nix:networking.hostNamenetworking.networkmanager.enabletime.timeZoneenvironment.systemPackagesDon't forget to install an editor!
- Execute the install
nixos-installreboot
- Edit additional options in
This is a fine first step into NixOS and Disko but there's more to learn about getting a system off the ground with Flakes. But that's a story for another day.