feat(nix): bound the store, generations and boot menu (task 0014) #7

Merged
alexion merged 2 commits from task-0014-nix-store-housekeeping into main 2026-07-20 10:43:51 -04:00
2 changed files with 37 additions and 5 deletions
Showing only changes of commit c63c3079be - Show all commits

View File

@@ -10,9 +10,21 @@ Retained boot configurations are capped at 15. Each generation stores a kernel a
## Acceptance criteria ## Acceptance criteria
- [ ] Automatic garbage collection is enabled weekly, deleting generations older than 30 days - [x] Automatic garbage collection is enabled weekly, deleting generations older than 30 days
- [ ] Store optimisation is scheduled weekly, rather than performed at build time - [x] Store optimisation is scheduled weekly, rather than performed at build time
- [ ] Retained boot configurations are capped at 15 - [x] Retained boot configurations are capped at 15
- [ ] These are declared as plumbing in the shared base config, so every future `Host` inherits them - [x] These are declared as plumbing in the shared base config, so every future `Host` inherits them
- [ ] `nix flake check` builds the `neogaia` toplevel - [x] `nix flake check` builds the `neogaia` toplevel
- [ ] Manual confirmation after a rebuild: the collection and optimisation timers exist and are scheduled - [ ] Manual confirmation after a rebuild: the collection and optimisation timers exist and are scheduled
## Implementation Notes
The two schedules are named days rather than the bare `weekly` keyword.
systemd expands `weekly` to `Mon *-*-* 00:00:00`, which would have started collection and deduplication at the same instant every week, leaving `nix-optimise` hard-linking paths `nix-gc` was concurrently deleting.
Collection now runs `Mon 03:15` and optimisation `Thu 03:45`, which keeps both weekly and keeps them apart.
The boot configuration cap sits in the shared base as the task asks, and is inert rather than an error on a host that does not use systemd-boot.
A future host on another bootloader therefore inherits no cap, which is the one place the "every future host inherits them" promise does not reach.
The last criterion is left open: confirming the timers on a running system needs a `nixos-rebuild switch`, which needs a sudo credential this session did not have.
It closes the way tasks 0013, 0016 and 0017 did, in a follow-up commit once the operator has switched the machine and read `systemctl list-timers`.

View File

@@ -58,6 +58,26 @@ in
nix.settings.extra-trusted-public-keys = [ nix.settings.extra-trusted-public-keys = [
"nyx-cache.chaotic.cx:dJxTrgMC3V3cFfyIiBQDQorG6k1LsqurH/srpMSq7qk=" "nyx-cache.chaotic.cx:dJxTrgMC3V3cFfyIiBQDQorG6k1LsqurH/srpMSq7qk="
]; ];
# A month of generations is kept, because on a rolling channel with a
# third-party kernel an old generation is a known-good system to boot when
# an update breaks something.
nix.gc.automatic = true;
nix.gc.dates = "Mon 03:15";
nix.gc.options = "--delete-older-than 30d";
# Deduplication runs on a timer, off the rebuild path, so it never adds
# latency to a `nixos-rebuild switch`.
# It falls on a different day from collection, so the two never contend.
nix.optimise.automatic = true;
nix.optimise.dates = [ "Thu 03:45" ];
# The EFI system partition holds a kernel and an initrd per entry at roughly
# 70 MiB apiece, and is fixed in size.
# An exhausted one fails at bootloader installation, after the build has
# already succeeded.
boot.loader.systemd-boot.configurationLimit = 15;
environment.systemPackages = [ pkgs.git ]; environment.systemPackages = [ pkgs.git ];
# Caps Lock is a second Escape; Shift+Caps Lock still toggles Caps Lock. # Caps Lock is a second Escape; Shift+Caps Lock still toggles Caps Lock.