Fold dotfiles-nixos into this repository #1
37
.claude/tasks/0001-skeleton-and-building-host.md
Normal file
37
.claude/tasks/0001-skeleton-and-building-host.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
spec: laptop-mvi
|
||||||
|
---
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Stand up the `Skeleton` and a minimal `neogaia` `Host` that evaluates and whose system toplevel builds — the walking skeleton every later slice extends and re-verifies against.
|
||||||
|
|
||||||
|
The `Skeleton` is a hand-rolled flake (no flake-parts): `nixos-unstable` base channel, an `unstable overlay` exposing `nixpkgs-unstable` as `unstable.<name>`, a `stable overlay` exposing `nixos-25.05` as `stable.<name>`, and chaotic-nyx wired as an input with its overlay and binary cache.
|
||||||
|
The helper lib is trimmed to three pieces: the `Auto-loader` (recursively discovers and imports every `Module` under `modules/` and every `Host` under `hosts/` with no null-placeholder traversal hack), the host-builder, and the script-from-file helper.
|
||||||
|
`with lib.my` is not used — dependencies are `inherit`ed explicitly.
|
||||||
|
The `Enable convention` uses the stdlib enable-option helper; every `Module` is imported unconditionally and guards its body with `mkIf config.modules.<path>.enable`.
|
||||||
|
home-manager is sourced from `nix-community` (master, nixpkgs followed) and integrated as a NixOS module with global packages and user packages.
|
||||||
|
The `user` is an explicit option defaulting to `alexion` (no impure environment lookup), placed in `wheel`, driving the system user and the home-manager user in lockstep.
|
||||||
|
The `neogaia` `Host` carries only enough (placeholder `hardware-configuration.nix`, filesystems/bootloader stubs, `stateVersion`) to make `nixosConfigurations.neogaia.config.system.build.toplevel` evaluate and build; real disk/kernel/networking arrive in later slices.
|
||||||
|
|
||||||
|
Design the per-`Host` layout so disk layout, kernel, and channel are all per-`Host` concerns from the start (story 20), so the desktop and servers extend this foundation without restructuring.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [x] `nix flake check` succeeds and the flake exposes `nixosConfigurations.neogaia`.
|
||||||
|
- [x] `nixosConfigurations.neogaia.config.system.build.toplevel` builds.
|
||||||
|
- [x] Adding a new `.nix` file under `modules/` is auto-discovered and imported without editing any `imports` list, and stays inert until its `enable` flag is set.
|
||||||
|
- [x] All three overlays resolve: `unstable.<pkg>`, `stable.<pkg>`, and a chaotic-nyx package are each reachable in a `Host`.
|
||||||
|
- [x] home-manager builds as part of the same `nixos-rebuild switch` toplevel (system + user environment atomic).
|
||||||
|
- [x] The `user` option defaults to `alexion`, has no impure environment lookup, places the user in `wheel`, and drives both the system and home-manager user.
|
||||||
|
- [x] The old `nixosModules` flake output and the `with lib.my` idiom are absent.
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
- **Verification.** `nix flake check` builds `checks.x86_64-linux.neogaia` = the Host toplevel (the spec's primary seam). Overlays confirmed via `nix eval` of `pkgs.unstable.hello` (2.12.3), `pkgs.stable.hello` (2.12.1), and `pkgs.linuxPackages_cachyos.kernel` (7.1.3, from chaotic). Auto-loader inertness confirmed both ways: the reference `modules/example.nix` is off by default, and `extendModules` with `modules.example.enable = true` activates its body.
|
||||||
|
- **chaotic binary cache.** Wired via `inputs.chaotic.nixosModules.default`, which puts both the `nyx-cache.chaotic.cx` substituter and its trusted public key into the built config (verified by evaluating `config.nix.settings.substituters`/`trusted-public-keys`). chaotic deliberately does **not** follow our nixpkgs, so the cache stays usable. Making the substituter/key explicit is task 0003's concern; here it is inherited from the module.
|
||||||
|
- **Shared base lives in `system/`.** The Skeleton's shared base config (overlays, `user`, flakes, home-manager wiring) is a `system/` module always imported by the host-builder, kept separate from the auto-loaded feature `Module`s under `modules/` so the base is never gated by an `enable` flag.
|
||||||
|
- **`modules/example.nix` kept intentionally.** It is the Auto-loader / Enable-convention reference every real Module copies; remove it once a real Module supersedes its teaching value.
|
||||||
|
- **`scriptFromFile` present but unused.** The task mandates the helper lib carry it ("the script-from-file helper"); its first caller lands with a later Module.
|
||||||
|
- **Home-manager base user only.** The base sets `home.username`/`homeDirectory`/`stateVersion` for the `user`; `extraSpecialArgs` passes both `inputs` and `my` (the flake lib) so upcoming HM Modules (fish/tmux/nvim) can reach `scriptFromFile`.
|
||||||
|
- **Deviations from plan.** Added an `options.user.description` (GECOS) alongside `user.name` — small and expected for a real account. Baseline `git` + global `allowUnfree` are set in the base (git is required for flakes; unfree is needed by chaotic/home-manager and later Claude Code). Placeholder `fileSystems`/bootloader and `hardware-configuration.nix` in `neogaia` are stubs that task 0002 (disko) replaces.
|
||||||
17
CLAUDE.md
Normal file
17
CLAUDE.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# dotfiles-nixos
|
||||||
|
|
||||||
|
One flake that builds every machine the user owns.
|
||||||
|
The domain model (Host, Module, Skeleton, Auto-loader, Enable convention, overlays) lives in `.claude/CONTEXT.md`; the current deliverable's spec is `.claude/spec/laptop-mvi.md`.
|
||||||
|
|
||||||
|
## Gotchas
|
||||||
|
|
||||||
|
- Nix on the dev host needs experimental features passed per-command.
|
||||||
|
This repo is developed on `neogaia` while it still runs **CachyOS** (the migration target), where Nix is the distro package at `/usr/bin/nix` in multi-user daemon mode.
|
||||||
|
The system `/etc/nix/nix.conf` does not enable flakes, so export `NIX_CONFIG="experimental-features = nix-command flakes"` (or pass `--extra-experimental-features 'nix-command flakes'`) for every command.
|
||||||
|
- The dev user is a non-trusted daemon client (`nix store info` reports `Trusted: 0`).
|
||||||
|
You cannot add substituters from the CLI, so rely on what the flake/config declares (e.g. the chaotic cache is wired by the chaotic module, not a CLI flag).
|
||||||
|
- If `/nix/store` is missing or `nix-daemon` is inactive after a fresh Nix install, initialise it with `sudo systemd-tmpfiles --create nix-daemon.conf && sudo systemctl enable --now nix-daemon.socket`.
|
||||||
|
- The primary build/verify seam for any Host is `nix flake check`, which builds `checks.x86_64-linux.<host>` (the system toplevel); cheap targeted checks use `nix eval .#nixosConfigurations.<host>.config...`.
|
||||||
|
- chaotic-nyx must **not** follow our `nixpkgs`, and its packages are built against chaotic's own pinned nixpkgs (its overlay defaults to `onTopOf = "flake-nixpkgs"`, the cache-friendly path).
|
||||||
|
That is what lets the `nyx-cache.chaotic.cx` binary cache hit instead of compiling the CachyOS kernel from source; the tradeoff is that chaotic packages do not see our `unstable`/`stable` overlays.
|
||||||
|
- The remote is self-hosted Gitea (`git.alexion.dev`); the forge CLI is `tea` (login `axi`), and `gh` is not installed.
|
||||||
155
flake.lock
generated
Normal file
155
flake.lock
generated
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"chaotic": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-schemas": "flake-schemas",
|
||||||
|
"home-manager": "home-manager",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1784318604,
|
||||||
|
"narHash": "sha256-P/N5ZbGWITiTfmiWpE/1uyXdOCagpgw/YAZLZJSzx/I=",
|
||||||
|
"owner": "chaotic-cx",
|
||||||
|
"repo": "nyx",
|
||||||
|
"rev": "21a8ef816f34558a438d778057a8809322ea2415",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "chaotic-cx",
|
||||||
|
"ref": "nyxpkgs-unstable",
|
||||||
|
"repo": "nyx",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-schemas": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1780327564,
|
||||||
|
"narHash": "sha256-HiRPtA0spK+Dkgbhz/1zW9glXxNVB+L4Rj2VYmdawb8=",
|
||||||
|
"rev": "6cc9bd98891b1fc6bb2b8cb3277df8bc72799ca6",
|
||||||
|
"revCount": 149,
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/flake-schemas/0.5.0/019e83cf-9af3-78b1-ac5b-70e68ad1efe1/source.tar.gz"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://flakehub.com/f/DeterminateSystems/flake-schemas/%3D0.5.0.tar.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"home-manager": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"chaotic",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1784129366,
|
||||||
|
"narHash": "sha256-N5JiyICSeQF14x+OQebNyPpYowOT9Rs1iKyeCylSzOA=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "165228b0efefc3e635e5174020c40ea64271dc25",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"home-manager_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1784351324,
|
||||||
|
"narHash": "sha256-By+kuRJZRqs2TuXgtR8vJ8cTKWXw33YG/Yollu5cO1U=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "460108009ca1ff69ca2ff19079ca2c838d6e3080",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1784120854,
|
||||||
|
"narHash": "sha256-KesHgItiZPgGX740axSiQLcIQ8D24MDqNpkKYWIek8k=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "753cc8a3a87467296ddd1fa93f0cc3e81120ee46",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1767313136,
|
||||||
|
"narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-25.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-unstable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1784347607,
|
||||||
|
"narHash": "sha256-VI5cdo27nEZ3m1SlgB8RvBbrqFUO2/dUgrrLWe407oA=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "31cd72fdba8fa052e437ce7e6879c4fe62def10f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1784120854,
|
||||||
|
"narHash": "sha256-KesHgItiZPgGX740axSiQLcIQ8D24MDqNpkKYWIek8k=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "753cc8a3a87467296ddd1fa93f0cc3e81120ee46",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"chaotic": "chaotic",
|
||||||
|
"home-manager": "home-manager_2",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"nixpkgs-stable": "nixpkgs-stable",
|
||||||
|
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
42
flake.nix
Normal file
42
flake.nix
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
description = "Alexion's NixOS configuration — one flake for every Host";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
# Base channel: nixos-unstable (rolling, but gated by the NixOS test suite).
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
|
# Fresher-than-base packages, reachable per-package as `unstable.<name>`.
|
||||||
|
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
|
|
||||||
|
# Latest stable release, reachable per-package as `stable.<name>`.
|
||||||
|
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||||
|
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager";
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ self, nixpkgs, ... }@inputs:
|
||||||
|
let
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
my = import ./lib { inherit lib inputs self; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# The trimmed helper lib: the Auto-loader, the host-builder, the script-from-file helper.
|
||||||
|
lib = my;
|
||||||
|
|
||||||
|
# Every Host under hosts/ is auto-discovered and built.
|
||||||
|
nixosConfigurations = my.mkHosts (self + "/hosts");
|
||||||
|
|
||||||
|
# `nix flake check` builds each Host's toplevel — the primary test seam.
|
||||||
|
checks.x86_64-linux = lib.mapAttrs (
|
||||||
|
_name: host: host.config.system.build.toplevel
|
||||||
|
) self.nixosConfigurations;
|
||||||
|
};
|
||||||
|
}
|
||||||
26
hosts/neogaia/default.nix
Normal file
26
hosts/neogaia/default.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{ ... }:
|
||||||
|
# neogaia — Dell XPS 13 9380 laptop.
|
||||||
|
#
|
||||||
|
# Minimum viable Host: enough to evaluate and build the system toplevel. The
|
||||||
|
# real disk layout (disko: LUKS + btrfs + zram), the CachyOS kernel, networking,
|
||||||
|
# and the terminal Modules arrive in later tasks; the placeholders below are
|
||||||
|
# replaced by disko in task 0002.
|
||||||
|
{
|
||||||
|
imports = [ ./hardware-configuration.nix ];
|
||||||
|
|
||||||
|
system.stateVersion = "25.05";
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
# Placeholder filesystems so the toplevel builds; superseded by the disko
|
||||||
|
# layout in task 0002.
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-label/nixos";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-label/BOOT";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
}
|
||||||
20
hosts/neogaia/hardware-configuration.nix
Normal file
20
hosts/neogaia/hardware-configuration.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{ lib, modulesPath, ... }:
|
||||||
|
# Placeholder hardware profile — regenerated on the target machine at install
|
||||||
|
# time (`nixos-generate-config` / `disko-install`). Carries only enough for the
|
||||||
|
# toplevel to evaluate: the host platform and the XPS 13's initrd modules.
|
||||||
|
{
|
||||||
|
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"thunderbolt"
|
||||||
|
"nvme"
|
||||||
|
"usb_storage"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
}
|
||||||
83
lib/default.nix
Normal file
83
lib/default.nix
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
self,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
attrNames
|
||||||
|
filterAttrs
|
||||||
|
genAttrs
|
||||||
|
flatten
|
||||||
|
hasSuffix
|
||||||
|
mapAttrsToList
|
||||||
|
;
|
||||||
|
|
||||||
|
# --- Auto-loader ---------------------------------------------------------
|
||||||
|
# Recursively collect every `.nix` file under `dir`, returned as a flat list
|
||||||
|
# of paths suitable for a module `imports`. No null-placeholder traversal
|
||||||
|
# hack: a directory recurses, a `.nix` file is taken, anything else is skipped.
|
||||||
|
collectNixFiles =
|
||||||
|
dir:
|
||||||
|
flatten (
|
||||||
|
mapAttrsToList (
|
||||||
|
name: type:
|
||||||
|
let
|
||||||
|
path = dir + "/${name}";
|
||||||
|
in
|
||||||
|
if type == "directory" then
|
||||||
|
collectNixFiles path
|
||||||
|
else if type == "regular" && hasSuffix ".nix" name then
|
||||||
|
[ path ]
|
||||||
|
else
|
||||||
|
[ ]
|
||||||
|
) (builtins.readDir dir)
|
||||||
|
);
|
||||||
|
|
||||||
|
# --- Host-builder --------------------------------------------------------
|
||||||
|
# Build one Host: every Module is imported unconditionally (inert until its
|
||||||
|
# `enable` flag is set), alongside home-manager, chaotic, the shared base,
|
||||||
|
# and the Host's own directory.
|
||||||
|
mkHost =
|
||||||
|
{
|
||||||
|
hostName,
|
||||||
|
system ? "x86_64-linux",
|
||||||
|
}:
|
||||||
|
inputs.nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
specialArgs = {
|
||||||
|
inherit inputs;
|
||||||
|
my = self.lib;
|
||||||
|
};
|
||||||
|
modules =
|
||||||
|
(collectNixFiles (self + "/modules"))
|
||||||
|
++ [
|
||||||
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
inputs.chaotic.nixosModules.default
|
||||||
|
(self + "/system")
|
||||||
|
(self + "/hosts/${hostName}")
|
||||||
|
{ networking.hostName = hostName; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Discover every Host (a subdirectory of `hostsDir`) and build each one.
|
||||||
|
mkHosts =
|
||||||
|
hostsDir:
|
||||||
|
let
|
||||||
|
hostNames = attrNames (filterAttrs (_name: type: type == "directory") (builtins.readDir hostsDir));
|
||||||
|
in
|
||||||
|
genAttrs hostNames (hostName: mkHost { inherit hostName; });
|
||||||
|
|
||||||
|
# --- Script-from-file helper --------------------------------------------
|
||||||
|
# Turn a standalone script file into a package on PATH, keeping the script
|
||||||
|
# itself editable as a real file rather than an inlined heredoc.
|
||||||
|
scriptFromFile = pkgs: name: path: pkgs.writeShellScriptBin name (builtins.readFile path);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit
|
||||||
|
collectNixFiles
|
||||||
|
mkHost
|
||||||
|
mkHosts
|
||||||
|
scriptFromFile
|
||||||
|
;
|
||||||
|
}
|
||||||
14
modules/example.nix
Normal file
14
modules/example.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
# The Auto-loader reference example. Every real Module copies this shape: it is
|
||||||
|
# imported unconditionally but its body stays inert until a Host sets the
|
||||||
|
# `enable` flag, so each Host reads as a checklist of `enable = true` lines.
|
||||||
|
let
|
||||||
|
cfg = config.modules.example;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modules.example.enable = lib.mkEnableOption "the Auto-loader reference example Module";
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.etc."skeleton-example".text = "This Module is enabled.\n";
|
||||||
|
};
|
||||||
|
}
|
||||||
84
system/default.nix
Normal file
84
system/default.nix
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
# The Skeleton's shared base config: the pieces every Host carries regardless of
|
||||||
|
# which Modules it enables — overlays, the `user`, flakes, and home-manager.
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
user = config.user;
|
||||||
|
|
||||||
|
# Instantiate an extra nixpkgs source for the same platform as the base pkgs.
|
||||||
|
pinArgs = prev: {
|
||||||
|
inherit (prev.stdenv.hostPlatform) system;
|
||||||
|
config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.user = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "alexion";
|
||||||
|
description = ''
|
||||||
|
The primary interactive user this Host is built for. An explicit option
|
||||||
|
with no impure environment lookup, so the config is reproducible and
|
||||||
|
honest about who the user is. Drives both the system account and the
|
||||||
|
home-manager user in lockstep.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
description = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Alexion";
|
||||||
|
description = "Human-readable description (GECOS field) for the primary user.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# Base is nixos-unstable; reach a package fresher with `unstable.<name>` or
|
||||||
|
# pin it rock-solid with `stable.<name>`. chaotic's overlay is added by its
|
||||||
|
# own NixOS module, imported by the host-builder.
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(_final: prev: {
|
||||||
|
unstable = import inputs.nixpkgs-unstable (pinArgs prev);
|
||||||
|
stable = import inputs.nixpkgs-stable (pinArgs prev);
|
||||||
|
})
|
||||||
|
];
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
|
# Flakes + a baseline so `nixos-rebuild switch` works from the console.
|
||||||
|
nix.settings.experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
environment.systemPackages = [ pkgs.git ];
|
||||||
|
|
||||||
|
# Primary user, in wheel. The bootstrap password is set by hand at install
|
||||||
|
# time and never committed; moving it to a sops-backed hashedPasswordFile is
|
||||||
|
# the first post-boot task (out of scope for the MVI).
|
||||||
|
users.users.${user.name} = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = user.description;
|
||||||
|
extraGroups = [ "wheel" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# home-manager as a NixOS module: one `nixos-rebuild switch` builds the
|
||||||
|
# system and the user environment atomically, sharing the system's pkgs
|
||||||
|
# (with our overlays) and installing user packages into the system profile.
|
||||||
|
home-manager = {
|
||||||
|
useGlobalPkgs = true;
|
||||||
|
useUserPackages = true;
|
||||||
|
extraSpecialArgs = {
|
||||||
|
inherit inputs;
|
||||||
|
my = inputs.self.lib;
|
||||||
|
};
|
||||||
|
users.${user.name} = {
|
||||||
|
home.username = user.name;
|
||||||
|
home.homeDirectory = "/home/${user.name}";
|
||||||
|
home.stateVersion = "25.05";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user