Fold dotfiles-nixos into this repository #1
31
.claude/tasks/0002-neogaia-disk-and-boot.md
Normal file
31
.claude/tasks/0002-neogaia-disk-and-boot.md
Normal 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
21
flake.lock
generated
@@ -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",
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
66
hosts/neogaia/disk.nix
Normal 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"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user