Fold dotfiles-nixos into this repository #1

Merged
alexion merged 32 commits from nixos-migration into main 2026-07-19 09:30:46 -04:00
6 changed files with 138 additions and 12 deletions
Showing only changes of commit da30375413 - Show all commits

View File

@@ -0,0 +1,31 @@
---
spec: laptop-mvi
blocked-by: 0001-skeleton-and-building-host
---
## What to build
Declare the `neogaia` laptop's disk with `disko` and make it unlock and boot on real hardware: a LUKS-encrypted btrfs volume with subvolumes plus zram swap, on an EFI system partition using systemd-boot, with the LUKS passphrase prompted at boot via the initrd.
The layout must build from the same tree as the `Host` toplevel (so the whole-`Host` build exercises it), and must be expressed as a per-`Host` disk concern so other machines can declare their own layouts later.
## Acceptance criteria
- [x] `neogaia` declares a `disko` layout: LUKS-encrypted btrfs with subvolumes plus zram swap on an EFI system partition.
- [x] systemd-boot is the bootloader; the initrd prompts for the LUKS passphrase so a normal boot unlocks the encrypted disk.
- [x] The `disko` layout builds as part of the `neogaia` toplevel build (no separate invocation needed to catch layout errors).
- [x] The disk layout is a per-`Host` concern, expressible differently for future `Host`s without restructuring the `Skeleton`.
## Implementation Notes
- **Layout.** One GPT disk at `/dev/nvme0n1`: a 512M EF00 ESP (vfat, `umask=0077`) mounted at `/boot`, and a 100%-fill LUKS partition (`cryptroot`, `allowDiscards`) holding a btrfs filesystem with three subvolumes — `@root``/`, `@home``/home`, `@nix``/nix` — each mounted `compress=zstd,noatime`.
There is deliberately no on-disk swap partition; swap is RAM-backed zram.
- **Skeleton vs. per-Host split.** The disko *module* (`inputs.disko.nixosModules.disko`) is wired into the host-builder in `lib/default.nix`, so every `Host` can interpret a `disko.devices` declaration; the *layout itself* lives in `hosts/neogaia/disk.nix`.
A future `Host` declares a different layout, or none at all (an undeclared `disko.devices` is a no-op), so servers that preserve an existing pool by import need no `Skeleton` change.
- **disko input follows nixpkgs.** Unlike chaotic (which must not), disko follows our `nixpkgs` so it builds against the same base.
- **Boot unlock.** disko's `type = "luks"` (no key file) generates `boot.initrd.luks.devices.cryptroot`, so the classic initrd prompts for the passphrase on a normal boot; the `nvme` initrd module was already present in `hardware-configuration.nix`.
- **zram enabled directly, not yet a Module.** Criterion 1 requires "plus zram swap," so `zramSwap.enable = true` is set on the `Host` now.
Task 0003 owns the reusable zram toggle `Module` and will lift this line into it; the placeholder `fileSystems`/bootloader stubs from task 0001 are removed here since disko now derives `fileSystems`.
- **Verification.** `nix flake check` (the `checks.x86_64-linux.neogaia` toplevel) builds green.
Confirmed via `nix eval`: disko-derived `fileSystems` = `/`,`/home`,`/nix` on btrfs `/dev/mapper/cryptroot` + `/boot` on the ESP; `boot.initrd.luks.devices` = `["cryptroot"]`; `systemd-boot.enable` and `zramSwap.enable` both true; `swapDevices` empty.
The genuine end-to-end confirmation is the manual `disko-install` reimage, which is irreversible by nature and not automated.

21
flake.lock generated
View File

@@ -21,6 +21,26 @@
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1781152676,
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
"owner": "nix-community",
"repo": "disko",
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"flake-schemas": {
"locked": {
"lastModified": 1780327564,
@@ -143,6 +163,7 @@
"root": {
"inputs": {
"chaotic": "chaotic",
"disko": "disko",
"home-manager": "home-manager_2",
"nixpkgs": "nixpkgs_2",
"nixpkgs-stable": "nixpkgs-stable",

View File

@@ -16,6 +16,13 @@
inputs.nixpkgs.follows = "nixpkgs";
};
# Declarative disk partitioning. Each Host declares its own layout; a Host
# that preserves an existing pool simply declares none.
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
# CachyOS kernel + binary cache. Deliberately NOT following our nixpkgs, so the
# chaotic cache stays usable and the kernel is fetched rather than compiled.
chaotic.url = "github:chaotic-cx/nyx/nyxpkgs-unstable";

View File

@@ -1,23 +1,23 @@
{ ... }:
# neogaia — Dell XPS 13 9380 laptop.
#
# The filesystems and hardware profile below are placeholder values, not the
# machine's real encrypted layout.
# The disk layout lives in ./disk.nix (disko); the resulting `fileSystems` are
# derived from it, so none are declared by hand here.
{
imports = [ ./hardware-configuration.nix ];
imports = [
./hardware-configuration.nix
./disk.nix
];
system.stateVersion = "26.05";
# systemd-boot on the EFI system partition disko creates. The initrd prompts
# for the LUKS passphrase (disko wires up boot.initrd.luks.devices), so a
# normal boot unlocks the encrypted root.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Placeholder label-based filesystems.
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/BOOT";
fsType = "vfat";
};
# Swap is RAM-backed zram rather than an on-disk partition. Task 0003 lifts
# this into the zram toggle Module; enabled directly here for now.
zramSwap.enable = true;
}

66
hosts/neogaia/disk.nix Normal file
View File

@@ -0,0 +1,66 @@
{ ... }:
# neogaia's disk layout, declared with disko and interpreted by the disko module
# the host-builder wires in. This is a per-Host concern: another Host declares a
# different `disko.devices` (or none, preserving an existing pool by importing it).
#
# One NVMe disk, GPT: an EFI system partition for systemd-boot, and a LUKS
# container holding a btrfs filesystem with subvolumes. Swap is zram (RAM-backed),
# so there is deliberately no on-disk swap partition. disko derives the matching
# `fileSystems.*` and `boot.initrd.luks.devices.*` from this, so a normal boot
# prompts for the passphrase in the initrd and unlocks the encrypted root.
{
disko.devices.disk.main = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "cryptroot";
settings.allowDiscards = true;
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
};
};
};
};
};
};
};
}

View File

@@ -54,6 +54,7 @@ let
++ [
inputs.home-manager.nixosModules.home-manager
inputs.chaotic.nixosModules.default
inputs.disko.nixosModules.disko
(self + "/system")
(self + "/hosts/${hostName}")
{ networking.hostName = hostName; }