main
1{
2 description = "System Config";
3
4 nixConfig = {
5 extra-substituters = [
6 "https://nixos-raspberrypi.cachix.org"
7 ];
8 extra-trusted-public-keys = [
9 "nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
10 ];
11 };
12
13 outputs =
14 { self, ... }@inputs:
15 let
16 inherit (self) outputs;
17 stateVersion = "24.11";
18
19 libx = import ./lib {
20 inherit
21 self
22 inputs
23 outputs
24 stateVersion
25 ;
26 };
27
28 supportedSystems = [
29 "x86_64-linux"
30 "aarch64-linux"
31 ];
32 forAllSystems = inputs.nixpkgs.lib.genAttrs supportedSystems;
33 in
34 {
35 githubActions = inputs.nix-github-actions.lib.mkGithubMatrix {
36 checks = inputs.nixpkgs.lib.getAttrs [ "x86_64-linux" ] self.packages;
37 };
38 githubActionsMatrix = builtins.toJSON (
39 inputs.nixpkgs.lib.mapAttrsToList
40 (name: value: {
41 inherit name;
42 arch = value._module.specialArgs.system;
43 })
44 (
45 inputs.nixpkgs.lib.attrsets.filterAttrs (
46 _: config:
47 (
48 builtins.hasAttr "system" config._module.specialArgs && config._module.specialArgs.hostname != "foo"
49 )
50 ) self.nixosConfigurations
51 )
52 );
53 # Standalone home configurations
54 # FIXME set this up
55 homeConfigurations = {
56 # Fedora CSB workstations
57 "vdemeest@aomi" = libx.mkHome {
58 username = "vdemeest";
59 hostname = "aomi";
60 desktop = "niri";
61 };
62 "vdemeest@kyushu" = libx.mkHome {
63 username = "vdemeest";
64 hostname = "kyushu";
65 desktop = "niri";
66 };
67 "vincent@nagoya" = libx.mkHome {
68 username = "vincent";
69 hostname = "nagoya";
70 system = "aarch64-linux";
71 };
72 "vincent@sakhalin" = libx.mkHome {
73 username = "vincent";
74 hostname = "sakhalin";
75 standaloneFedora = true;
76 };
77 # headless machine
78 "vincent@aion" = libx.mkHome {
79 username = "vincent";
80 hostname = "aion";
81 system = "aarch64-linux";
82 };
83 "houbeb@aion" = libx.mkHome {
84 username = "houbeb";
85 hostname = "aion";
86 system = "aarch64-linux";
87 };
88 };
89 nixosConfigurations = {
90 # Laptop for LLM workloads (unstable)
91 okinawa = libx.mkHost {
92 hostname = "okinawa";
93 desktop = "niri"; # or "sway"
94 };
95 # Servers (unstable)
96 # sakhalin = libx.mkHost {
97 # hostname = "sakhalin";
98 # };
99 shikoku = libx.mkHost {
100 hostname = "shikoku";
101 pkgsInput = inputs.nixpkgs-26_05;
102 homeInput = inputs.home-manager-26_05;
103 agenixInput = inputs.agenix-26_05;
104 };
105 # Servers (stable)
106 aix = libx.mkHost {
107 hostname = "aix";
108 system = "aarch64-linux";
109 hardwareType = "rpi4";
110 pkgsInput = inputs.nixpkgs-26_05;
111 homeInput = inputs.home-manager-26_05;
112 agenixInput = inputs.agenix-26_05;
113 };
114 aion = libx.mkHost {
115 hostname = "aion";
116 system = "aarch64-linux";
117 pkgsInput = inputs.nixpkgs-26_05;
118 homeInput = inputs.home-manager-26_05;
119 agenixInput = inputs.agenix-26_05;
120 };
121 rhea = libx.mkHost {
122 hostname = "rhea";
123 system = "aarch64-linux";
124 pkgsInput = inputs.nixpkgs-26_05;
125 homeInput = inputs.home-manager-26_05;
126 agenixInput = inputs.agenix-26_05;
127 };
128 lutece = libx.mkHost {
129 hostname = "lutece";
130 pkgsInput = inputs.nixpkgs-26_05;
131 homeInput = inputs.home-manager-26_05;
132 agenixInput = inputs.agenix-26_05;
133 };
134 carthage = libx.mkHost {
135 hostname = "carthage";
136 pkgsInput = inputs.nixpkgs-26_05;
137 homeInput = inputs.home-manager-26_05;
138 agenixInput = inputs.agenix-26_05;
139 };
140 };
141
142 nixosModules = {
143 # provided modules (to be upstreamed)
144 wireguard-client = ./modules/wireguard/client.nix;
145 wireguard-server = ./modules/wireguard/server.nix;
146 govanityurl = ./modules/govanityurl;
147 gosmee = ./modules/gosmee;
148 rsync-replica = ./modules/rsync-replica;
149 microshift = ./modules/microshift;
150 harmonia = ./modules/harmonia;
151 praetorian = inputs.praetorian.nixosModules.praetorian;
152 };
153
154 # Fedora config files (no system-manager, just the useful files)
155 fedoraConfigs =
156 let
157 mkFedoraConfigs =
158 hostname:
159 let
160 pkgs = import inputs.nixpkgs { system = "x86_64-linux"; };
161 globals = import ./globals.nix {
162 inherit (inputs.nixpkgs) lib;
163 inherit hostname;
164 };
165 fedoraLibx = import ./lib/functions.nix { inherit (inputs.nixpkgs) lib; };
166 in
167 import ./systems/common/fedora-work/gen-configs.nix {
168 inherit (inputs.nixpkgs) lib;
169 inherit pkgs globals hostname;
170 libx = fedoraLibx;
171 };
172 in
173 {
174 kyushu = mkFedoraConfigs "kyushu";
175 aomi = mkFedoraConfigs "aomi";
176 sakhalin =
177 let
178 pkgs = import inputs.nixpkgs { system = "x86_64-linux"; };
179 globals = import ./globals.nix {
180 inherit (inputs.nixpkgs) lib;
181 hostname = "sakhalin";
182 };
183 fedoraLibx = import ./lib/functions.nix { inherit (inputs.nixpkgs) lib; };
184 in
185 import ./systems/sakhalin/gen-configs.nix {
186 inherit pkgs globals;
187 libx = fedoraLibx;
188 };
189 };
190
191 hostConfigs = {
192 nagoya =
193 let
194 pkgs = import inputs.nixpkgs { system = "aarch64-linux"; };
195 globals = import ./globals.nix {
196 inherit (inputs.nixpkgs) lib;
197 hostname = "nagoya";
198 };
199 hostLibx = import ./lib/functions.nix { inherit (inputs.nixpkgs) lib; };
200 in
201 import ./systems/nagoya/gen-configs.nix {
202 inherit pkgs globals;
203 libx = hostLibx;
204 };
205 };
206
207 images = {
208 # sdimages
209 aix =
210 (self.nixosConfigurations.aix.extendModules {
211 modules = [
212 "${inputs.nixpkgs-26_05}/nixos/modules/installer/sd-card/sd-image-aarch64.nix"
213 ];
214 }).config.system.build.sdImage;
215 };
216
217 overlays = import ./overlays { inherit inputs; };
218
219 packages = forAllSystems (
220 system:
221 let
222 pkgs = import inputs.nixpkgs {
223 system = system;
224 config.allowAliases = false;
225 overlays = [
226 self.overlays.additions
227 ];
228 };
229 skipDarwinPackages =
230 system: n:
231 if lib.strings.hasSuffix "darwin" system then !(lib.strings.hasPrefix "koff" n) else true;
232 inherit (inputs.nixpkgs) lib;
233 drvAttrs = builtins.filter (n: lib.isDerivation pkgs.${n} && skipDarwinPackages system n) (
234 builtins.attrNames (self.overlays.additions pkgs pkgs)
235 );
236 in
237 lib.listToAttrs (map (n: lib.nameValuePair n pkgs.${n}) drvAttrs)
238 // {
239 dns-zones =
240 let
241 globals = import ./globals.nix { };
242 dns = inputs.dns;
243 mkZoneFile =
244 zoneName: zoneFile:
245 pkgs.writeText "db.${zoneName}" (
246 dns.lib.toString zoneName (import zoneFile { inherit dns globals; })
247 );
248 in
249 pkgs.runCommand "dns-zones" { } ''
250 mkdir -p $out
251 cp ${mkZoneFile "sbr.pm" ./systems/common/services/dns/sbr.pm.nix} $out/db.sbr.pm
252 cp ${mkZoneFile "home" ./systems/common/services/dns/home.nix} $out/db.home
253 cp ${mkZoneFile "vpn" ./systems/common/services/dns/vpn.nix} $out/db.vpn
254 cp ${mkZoneFile "demeester.fr" ./systems/common/services/dns/demeester.fr.nix} $out/db.demeester.fr
255 cp ${mkZoneFile "192.168.1.in-addr.arpa" ./systems/common/services/dns/192.168.1.nix} $out/db.192.168.1
256 cp ${mkZoneFile "10.100.0.in-addr.arpa" ./systems/common/services/dns/10.100.0.nix} $out/db.10.100.0
257 '';
258
259 wg-configs =
260 let
261 globals = import ./globals.nix { };
262 serverPubkey = globals.machines.carthage.net.vpn.pubkey;
263 endpoint = globals.net.vpn.endpoint;
264 mkWgConfig =
265 hostname:
266 let
267 machine = globals.machines.${hostname};
268 vpnIp = builtins.head machine.net.vpn.ips;
269 in
270 pkgs.writeText "wg0-${hostname}.conf" ''
271 [Interface]
272 Address = ${vpnIp}/32
273 PostUp = test -f /persist/wireguard/private.key && wg set %i private-key /persist/wireguard/private.key || true
274
275 [Peer]
276 PublicKey = ${serverPubkey}
277 Endpoint = ${endpoint}:51820
278 AllowedIPs = 10.100.0.0/24
279 PersistentKeepalive = 25
280 '';
281 in
282 pkgs.runCommand "wg-configs" { } ''
283 mkdir -p $out
284 cp ${mkWgConfig "aix"} $out/wg0-aix.conf
285 cp ${mkWgConfig "athena"} $out/wg0-athena.conf
286 cp ${mkWgConfig "demeter"} $out/wg0-demeter.conf
287 '';
288 }
289 );
290
291 checks = forAllSystems (system: {
292 pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
293 src = ./.;
294 # Run hooks on pre-push instead of pre-commit for less intrusive workflow
295 default_stages = [
296 "manual"
297 "pre-push"
298 ];
299 hooks = {
300 # go
301 gofmt.enable = true;
302 # golangci-lint.enable = true;
303 # nix
304 deadnix.enable = true;
305 nixfmt.enable = true;
306 # statix.enable = true;
307 # python
308 ruff.enable = true;
309 # shell
310 shellcheck = {
311 enable = true;
312 excludes = [ "dots/config/zsh/.*" ]; # zsh files use zsh-specific syntax
313 };
314 # emacs lisp - basic syntax checking
315 elisp-byte-compile = {
316 enable = false; # Disabled - causes issues with missing packages in pre-push hook
317 name = "Emacs Lisp byte-compile";
318 entry =
319 let
320 pkgs = import inputs.nixpkgs { system = system; };
321 # Create a wrapper that runs Emacs byte-compilation
322 elisp-check = pkgs.writeShellScript "elisp-check" ''
323 ${pkgs.emacs}/bin/emacs --batch \
324 --eval "(setq byte-compile-error-on-warn t)" \
325 -f batch-byte-compile "$@"
326 '';
327 in
328 toString elisp-check;
329 files = "\\.el$";
330 excludes = [
331 "dots/\\.config/emacs/old/.*"
332 "dots/\\.config/emacs/elpa/.*"
333 "dots/\\.config/emacs/transient/.*"
334 "dots/\\.config/emacs/eshell/.*"
335 "dots/\\.config/emacs/custom\\.el"
336 "dots/\\.config/emacs/\\.chatgpt-shell\\.el"
337 "dots/\\.config/emacs/site-lisp/.*"
338 "\\.dir-locals\\.el"
339 ];
340 };
341 };
342 };
343 });
344
345 devShells = forAllSystems (system: {
346 default =
347 let
348 pkgs = import inputs.nixpkgs {
349 system = system;
350 config.allowUnfree = true;
351 };
352 in
353 inputs.nixpkgs.legacyPackages.${system}.mkShell {
354 inherit (self.checks.${system}.pre-commit-check) shellHook;
355 buildInputs = self.checks.${system}.pre-commit-check.enabledPackages;
356 packages = [
357 pkgs.git
358 pkgs.prettier
359 pkgs.deadnix
360 pkgs.nixfmt
361 inputs.agenix.packages.${system}.default
362 ];
363 name = "home";
364 DIRENV_LOG_FORMAT = "";
365 };
366 });
367 };
368
369 inputs = {
370 # Flake for compatibility with non-flake commands
371 flake-compat = {
372 type = "github";
373 owner = "edolstra";
374 repo = "flake-compat";
375 flake = false;
376 };
377
378 buildkit-tekton = {
379 url = "github:vdemeester/buildkit-tekton";
380 inputs.nixpkgs.follows = "nixpkgs";
381 };
382 flake-parts.url = "github:hercules-ci/flake-parts";
383 go-org-readwise = {
384 url = "git+https://codeberg.org/vdemeester/go-org-readwise";
385 inputs.nixpkgs.follows = "nixpkgs";
386 inputs.flake-parts.follows = "flake-parts";
387 };
388 pass-run = {
389 url = "github:vdemeester/pass-run/v0.1.0";
390 inputs.nixpkgs.follows = "nixpkgs";
391 };
392 radian = {
393 url = "github:vdemeester/radian";
394 inputs.nixpkgs.follows = "nixpkgs";
395 inputs.flake-parts.follows = "flake-parts";
396 };
397
398 # nixpkgs
399 nixpkgs = {
400 type = "github";
401 owner = "NixOS";
402 repo = "nixpkgs";
403 ref = "nixos-unstable";
404 };
405 nixpkgs-26_05 = {
406 type = "github";
407 owner = "NixOS";
408 repo = "nixpkgs";
409 ref = "nixos-26.05";
410 };
411 nixpkgs-master.url = "github:nixos/nixpkgs/master";
412 nono = {
413 url = "github:nolabs-ai/nono/v0.78.0";
414 inputs.nixpkgs.follows = "nixpkgs";
415 };
416 nixpkgs-wip-consolidated = {
417 type = "github";
418 owner = "vdemeester";
419 repo = "nixpkgs";
420 ref = "wip-consolidated";
421 };
422 pre-commit-hooks.url = "github:cachix/git-hooks.nix";
423 pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs";
424 pre-commit-hooks.inputs.flake-compat.follows = "flake-compat";
425 # Home Manager
426 home-manager = {
427 type = "github";
428 owner = "nix-community";
429 repo = "home-manager";
430 inputs.nixpkgs.follows = "nixpkgs";
431 };
432 dns = {
433 url = "github:nix-community/dns.nix";
434 inputs.nixpkgs.follows = "nixpkgs";
435 };
436 home-manager-26_05 = {
437 type = "github";
438 owner = "nix-community";
439 repo = "home-manager";
440 ref = "release-26.05";
441 inputs.nixpkgs.follows = "nixpkgs-26_05";
442 };
443
444 emacs-overlay = {
445 url = "github:nix-community/emacs-overlay";
446 inputs.nixpkgs.follows = "nixpkgs";
447 inputs.nixpkgs-stable.follows = "nixpkgs-26_05";
448 };
449
450 nixos-hardware = {
451 type = "github";
452 owner = "NixOS";
453 "repo" = "nixos-hardware";
454 };
455
456 # Me :D
457 chick-group = {
458 type = "github";
459 owner = "vdemeester";
460 repo = "chick-group";
461 inputs.nixpkgs.follows = "nixpkgs";
462 inputs.flake-parts.follows = "flake-parts";
463 inputs.pre-commit-hooks.follows = "pre-commit-hooks";
464 };
465 # Red Hat
466 chapeau-rouge = {
467 type = "github";
468 owner = "vdemeester";
469 repo = "chapeau-rouge";
470 inputs.nixpkgs.follows = "nixpkgs";
471 inputs.flake-parts.follows = "flake-parts";
472 inputs.pre-commit-hooks.follows = "pre-commit-hooks";
473 };
474 agenix.url = "github:ryantm/agenix";
475 agenix.inputs.nixpkgs.follows = "nixpkgs";
476 agenix.inputs.home-manager.follows = "home-manager";
477 agenix-26_05.url = "github:ryantm/agenix";
478 agenix-26_05.inputs.nixpkgs.follows = "nixpkgs-26_05";
479 agenix-26_05.inputs.home-manager.follows = "home-manager-26_05";
480
481 nix-cachyos-kernel = {
482 url = "github:xddxdd/nix-cachyos-kernel";
483 inputs.nixpkgs.follows = "nixpkgs";
484 };
485
486 lanzaboote.url = "github:nix-community/lanzaboote";
487 lanzaboote.inputs.nixpkgs.follows = "nixpkgs";
488
489 disko.url = "github:nix-community/disko";
490 disko.inputs.nixpkgs.follows = "nixpkgs";
491
492 harmonia.url = "github:nix-community/harmonia";
493 harmonia.inputs.nixpkgs.follows = "nixpkgs";
494
495 nix-github-actions.url = "github:nix-community/nix-github-actions";
496 nix-github-actions.inputs.nixpkgs.follows = "nixpkgs";
497
498 nixos-raspberrypi.url = "github:nvmd/nixos-raspberrypi/develop";
499 nixos-raspberrypi.inputs.nixpkgs.follows = "nixpkgs";
500 nixos-raspberrypi.inputs.flake-compat.follows = "flake-compat";
501
502 llm-agents.url = "github:numtide/llm-agents.nix";
503 llm-agents.inputs.nixpkgs.follows = "nixpkgs";
504 llm-agents.inputs.flake-parts.follows = "flake-parts";
505
506 voxtype.url = "github:peteonrails/voxtype/main";
507 voxtype.inputs.nixpkgs.follows = "nixpkgs";
508
509 praetorian.url = "github:vdemeester/praetorian/v2.0.0-rc2";
510 praetorian.inputs.nixpkgs.follows = "nixpkgs";
511 };
512}