feat: nomarchy-install — guided live-ISO installer (disko + mkFlake)

Ported from the previous iteration's installer (3bdfc35), adapted to the
mkFlake world. gum TUI: disk pick, optional LUKS2, user/hostname/timezone,
DMI → nixos-hardware autodetection (hardware-db.sh). disko partitions
GPT + 1 GiB ESP + BTRFS subvolumes; the generated machine flake lands at
~user/.nomarchy (one mkFlake call, /etc/nixos symlinks to it) and
nixos-install makes it bootable (UEFI/systemd-boot, v1 single disk).

Offline by construction: the target flake.lock is composed from the rev
the ISO was built from (compose-lock.py), `nix flake archive` seeds the
target store, and the ISO pre-builds the template system + desktop.
First boot lands themed: the HM generation is pre-activated in chroot.

mkFlake grows two things for this: hardwareProfile now also takes a list
(autodetection emits several common-* modules), and installed systems get
the standalone home-manager CLI from the pinned input. Unattended mode
(NOMARCHY_UNATTENDED=1 + env) documented in docs/TESTING.md §4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-06-10 16:05:29 +01:00
parent 8ded92ea63
commit f3707357a6
10 changed files with 862 additions and 18 deletions

View File

@@ -33,6 +33,28 @@
inherit system;
overlays = [ self.overlays.default ];
};
# The guided installer — live-ISO only (not in the overlay): it bakes
# in the downstream template, this checkout's flake.lock, and the
# source identity of this very revision so installs work offline.
gitUrl = "https://git.bemagri.xyz/bernardo/nomarchy.git";
nomarchyInstall = pkgs.callPackage ./pkgs/nomarchy-install {
templateDir = ./templates/downstream;
nomarchyLock = ./flake.lock;
hardwareModuleNames = pkgs.writeText "nixos-hardware-modules.txt"
(nixpkgs.lib.concatStringsSep "\n"
(builtins.attrNames nixos-hardware.nixosModules));
flakeUrl = "git+${gitUrl}";
originalNode = { type = "git"; url = gitUrl; };
lockedNode = {
type = "git";
url = gitUrl;
rev = self.rev or null; # null on a dirty tree → installer needs network
narHash = self.narHash;
lastModified = self.lastModified or 0;
revCount = self.revCount or 0;
};
};
in
{
# ─── Downstream API ────────────────────────────────────────────
@@ -75,6 +97,7 @@
packages.${system} = {
nomarchy-theme-sync = pkgs.nomarchy-theme-sync;
nomarchy-install = nomarchyInstall;
default = pkgs.nomarchy-theme-sync;
};
@@ -163,9 +186,11 @@
};
# The standalone CLI that `nomarchy-theme-sync apply` runs for
# theme switching, from the same pinned input.
# theme switching, from the same pinned input — plus the
# guided installer.
environment.systemPackages = [
home-manager.packages.${system}.home-manager
nomarchyInstall
];
# Keep the locked flake inputs in the ISO store so theme
@@ -179,7 +204,20 @@
[ input.outPath ] ++ builtins.concatMap collectInputs
(builtins.attrValues (input.inputs or { }));
in
collectInputs self;
collectInputs self ++ (
# Pre-build the downstream template's system + desktop so
# nomarchy-install can build the target offline (and fast):
# a custom username/hostname changes only a handful of
# derivations on top of these. No hardware profile — that
# matches a VM install; profiled installs share most of it.
let template = self.lib.mkFlake {
src = ./templates/downstream;
username = username;
}; in [
template.nixosConfigurations.default.config.system.build.toplevel
template.homeConfigurations.${username}.activationPackage
]
);
}
];
};