{ description = "Gortium infra flake"; inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; agenix = { url = "github:ryantm/agenix"; inputs.darwin.follows = ""; inputs.nixpkgs.follows = "nixpkgs"; }; agenix-rekey = { url = "github:oddlama/agenix-rekey"; inputs.nixpkgs.follows = "nixpkgs"; }; lix = { url = "git+https://git.lix.systems/lix-project/lix?ref=main"; inputs.nixpkgs.follows = "nixpkgs"; }; nixpkgs-uconsole.url = "github:NixOS/nixpkgs/nixos-25.11"; nixos-uconsole = { url = "github:gortium/nixos-uconsole/pr/dcs-panel-detection"; inputs.nixpkgs.follows = "nixpkgs-uconsole"; inputs.nixos-raspberrypi.follows = "nixos-raspberrypi"; }; nixos-raspberrypi = { url = "github:gortium/nixos-raspberrypi/cm5-cross-v1"; inputs.nixpkgs.follows = "nixpkgs-uconsole"; }; home-manager = { url = "github:nix-community/home-manager/release-25.11"; inputs.nixpkgs.follows = "nixpkgs-uconsole"; }; }; outputs = { self, nixpkgs, agenix, agenix-rekey, lix , nixpkgs-uconsole, nixos-uconsole, nixos-raspberrypi , home-manager , ... }@inputs: let system = "x86_64-linux"; keys = import ./lib/keys.nix; paths = { flake = "/home/gortium/infra"; identities = [ "/home/gortium/.ssh/gortium_ssh_key" "/etc/ssh/ssh_host_ed25519_key" "/root/.age/bootstrap.key" ]; }; overlays = [ agenix.overlays.default (import ./overlays/reticulum.nix) ]; pkgs = import nixpkgs { inherit system overlays; config.allowUnfree = true; config.permittedInsecurePackages = [ "openclaw-2026.3.12" ]; }; devShell = import ./shells/nix_dev.nix { inherit pkgs system agenix; }; ############################################################################## # CROSS-COMPILE WORKAROUNDS — packages that fail aarch64 cross-compile # # These packages need NATIVE COMPILATION on the uConsole itself (aarch64). # They cannot cross-compile from x86_64 for various reasons listed below. # We work around them in the overlay until we set up distributed builds # with the uConsole as a native aarch64 builder. # # ==== Cross-compile failures ==== # # libcamera / libcamera-rpi / libpisp: # meta.platforms excludes aarch64. pipewire hard-depends on them in nixos-25.11. # Fix: empty meta.platforms + strip from pipewire buildInputs. # # gjs: # Need native display (GTK3/4 tests) for cross-compile configure. # Fix: meson -Dskip_gtk_tests=true. # # hyprland: # Qt6Quick missing from aarch64 qtdeclarative, breaks hyprland-qt-support. # Fix: wrapRuntimeDeps=false (Qt UI components disabled, WM still works). # # boost.mpi: # Boost.Build has no b2 architecture alternatives for ARM. # Fix: useMpi=false. # # perl-ldap (perlPackages.perlldap): # Module::Install requires Perl dynamic loading (Fcntl) which is # unavailable in cross-compiled Perl. # Fix: stripped from john.s propagatedBuildInputs. # # john (John the Ripper): # Indirectly affected — depends on perl-ldap for perl utility scripts. # Fix: perl-ldap stripped from propagatedBuildInputs (john still works, # just loses sha-dump.pl etc. LDAP support). # # gss (GNU Generic Security Service): # autogen.sh fails cross-compile. Pulled by mailutils → emacs-pgtk. # Fix: emacs withMailutils=false. # # emacs-pgtk: # Indirectly affected — depends on mailutils which depends on gss. # Fix: withMailutils=false (no mail/IMAP within emacs). # # qtquick3d (Qt6): # Qt::Quick not available in aarch64 cross-compile qtdeclarative. # cmake skips build, ninja has no install target. # Fix: removed js8call, switched wireshark → wireshark-cli. # # js8call: # REMOVED from system packages. Depends on Qt6 multimedia → qtquick3d. # # wireshark-qt: # SWITCHED to wireshark-cli. Same Qt6 multimedia → qtquick3d chain. # # neovim: # `libnlua0.so` built for aarch64, luajit (x86_64) tries to load it # during codegen (preload_nlua.lua). No clean override option. # Fix: remove from system packages + install via native build # once uConsole is set up as remote builder. # # clamav: # cmake try_run() + Rust proc-macro can't find native linker in # cross-compile (cc crate uses cross CC, no cc in PATH for build # scripts). Chain: clamav → system-path → etc → dbus → polkit. # Fix: remove from system packages; clamscan available from server. # # ==== Remote builder setup (bidirectional) — TODO ==== # To eliminate cross-compile exceptions, set up distributed builds: # 1. Create a dedicated `builder` user on both hosts (no shell, home=/var/empty) # 2. Add the same SSH key to both hosts (symmetric) # 3. On lazyworkhorse — `nix.buildMachines` pointing to uConsole for aarch64-linux # 4. On uConsole — `nix.buildMachines` pointing to lazyworkhorse for x86_64-linux # 5. Remove the uconsoleCrossOverlay workarounds above # 6. Nix auto-dispatches derivations by `system` — no per-package exceptions needed # Example buildMachines config: # Server dispatches aarch64 builds to uConsole (4 cores, less power): # nix.buildMachines = [{ # hostName = "uConsole.local"; # systems = ["aarch64-linux"]; # maxJobs = 4; # sshUser = "builder"; # sshKey = "/etc/ssh/builder_key"; # }]; # uConsole dispatches x86_64 builds to server (36 cores, 256GB RAM): # nix.buildMachines = [{ # hostName = "lazyworkhorse.net"; # port = 2424; # systems = ["x86_64-linux"]; # maxJobs = 36; # sshUser = "builder"; # sshKey = "/etc/ssh/builder_key"; # }]; # ==== How to build natively on uConsole ==== # To native-compile these on the uConsole: # 1. Add uConsole as a remote builder (nix.buildMachines) # 2. Set nix.extra-platforms = [ "aarch64-linux" ] on server # 3. Remove the overlay workarounds below # 4. Packages will auto-dispatch to uConsole for native builds ############################################################################## uconsoleCrossOverlay = final: prev: { libcamera = prev.libcamera.overrideAttrs (_: { meta.platforms = []; }); libcamera-rpi = prev.libcamera-rpi.overrideAttrs (_: { meta.platforms = []; }); libpisp = prev.libpisp.overrideAttrs (_: { meta.platforms = []; }); pipewire = prev.pipewire.overrideAttrs (old: { buildInputs = builtins.filter (x: !(x?pname && x.pname == "libcamera")) (old.buildInputs or []); mesonFlags = builtins.filter (flag: !(builtins.isString flag && builtins.match ".*libcamera.*" flag != null)) (old.mesonFlags or []) ++ [ "-Dlibcamera=disabled" ]; }); gjs = prev.gjs.overrideAttrs (old: { mesonFlags = (old.mesonFlags or []) ++ [ "-Dskip_gtk_tests=true" ]; }); hyprland = prev.hyprland.override { wrapRuntimeDeps = false; }; boost = prev.boost.override { useMpi = false; }; # perl-ldap cannot cross-compile (Module::Install needs dynamic loading) xdg-desktop-portal-hyprland = prev.xdg-desktop-portal-hyprland.overrideAttrs (old: { preConfigure = (old.preConfigure or "") + '' cmakeFlags="$cmakeFlags -Dhyprwayland-scanner_DIR=${prev.buildPackages.hyprwayland-scanner}/lib/cmake/hyprwayland-scanner" 2>/dev/null || true export PKG_CONFIG_PATH="${prev.buildPackages.hyprwayland-scanner}/lib/pkgconfig:$PKG_CONFIG_PATH" ''; }); emacs-pgtk = prev.emacs-pgtk.override { withMailutils = false; }; # perl-ldap fails cross-compile (Module::Install needs dynamic loading) # Strip it from john deps -- the perl scripts that need it are not critical john = prev.john.overrideAttrs (old: { propagatedBuildInputs = builtins.filter (x: x?pname && x.pname != "perl-ldap") (old.propagatedBuildInputs or []); }); # clamav: removed from system packages (see note above). }; uconsoleRpiPipewireOverlay = final: prev: { pipewire = prev.pipewire.overrideAttrs (old: { buildInputs = builtins.filter (x: !(x?pname && x.pname == "libcamera")) (old.buildInputs or []); mesonFlags = builtins.filter (flag: !(builtins.isString flag && builtins.match ".*libcamera.*" flag != null)) (old.mesonFlags or []) ++ [ "-Dlibcamera=disabled" ]; }); }; uconsoleBaseModules = [ { nixpkgs.buildPlatform = "x86_64-linux"; nixpkgs.hostPlatform = "aarch64-linux"; nixpkgs.config.allowUnfree = true; boot.loader.raspberry-pi.bootloader = "kernel"; nixpkgs.overlays = [ uconsoleCrossOverlay (import ./overlays/reticulum.nix) ]; } nixos-raspberrypi.nixosModules.nixpkgs-rpi ({ config, lib, pkgs, ... }: { nixpkgs.overlays = [ uconsoleRpiPipewireOverlay ]; }) nixos-raspberrypi.nixosModules.raspberry-pi-5.base nixos-raspberrypi.lib.inject-overlays nixos-raspberrypi.lib.inject-overlays-global nixos-uconsole.nixosModules.uconsole-cm5 ./modules/nixos/hardware/uconsole-cm5-aio-v2.nix ({ config, lib, pkgs, inputs, ... }: let lixCross = import inputs.nixpkgs-uconsole { localSystem = { system = "x86_64-linux"; }; crossSystem = { system = "aarch64-linux"; }; overlays = [ inputs.lix.overlays.default ]; }; in { nix.package = lixCross.lix; }) inputs.home-manager.nixosModules.home-manager agenix.nixosModules.default agenix-rekey.nixosModules.default ./hosts/uconsole-cm5/configuration.nix ./hosts/uconsole-cm5/hardware-configuration.nix ./modules/nixos/services/remote-builder.nix ./modules/nixos/services/wireguard-client.nix ./modules/nixos/services/clamav.nix ./modules/nixos/security/ai-worker-restricted.nix ./users/gortium/gortium.nix ./users/ai-worker/ai-worker.nix ]; in { nixosConfigurations = { lazyworkhorse = nixpkgs.lib.nixosSystem { specialArgs = { inherit system self keys paths inputs; }; modules = [ { nixpkgs.overlays = overlays; nixpkgs.config.allowUnfree = true; nixpkgs.config.rocmSupport = true; nixpkgs.config.permittedInsecurePackages = [ "openclaw-2026.3.12" ]; nix.package = lix.packages.${system}.default; } inputs.home-manager.nixosModules.home-manager agenix.nixosModules.default ./hosts/lazyworkhorse/configuration.nix ./hosts/lazyworkhorse/hardware-configuration.nix ./modules/nixos/filesystem/hoardingcow-mount.nix ./modules/nixos/services/docker_manager.nix ./modules/nixos/filesystem/poup-16t-disk.nix ./modules/nixos/services/ollama_init_custom_models.nix ./modules/nixos/services/open_code_server.nix ./modules/nixos/services/clamav.nix ./modules/nixos/security/ai-worker-restricted.nix ./users/gortium/gortium.nix ./users/ai-worker/ai-worker.nix ]; }; cyt-pi = nixpkgs.lib.nixosSystem { specialArgs = { inherit self keys paths inputs; }; modules = [ { nixpkgs.overlays = overlays; nixpkgs.config.allowUnfree = true; nixpkgs.hostPlatform = "aarch64-linux"; nix.package = lix.packages."aarch64-linux".default; } ./hosts/cyt-pi/configuration.nix ./hosts/cyt-pi/hardware-configuration.nix ./modules/nixos/services/remote-builder.nix ./modules/nixos/services/wireguard-client.nix ./users/gortium/gortium.nix ]; }; uconsole-cm5 = nixpkgs-uconsole.lib.nixosSystem { system = "aarch64-linux"; specialArgs = { inherit self keys paths inputs; nixos-raspberrypi = nixos-raspberrypi; isCM4 = false; }; modules = uconsoleBaseModules; }; }; agenix-rekey = agenix-rekey.configure { userFlake = self; nixosConfigurations = self.nixosConfigurations; }; devShells.${system}.default = devShell; packages.${system} = { uconsole-cm5-image = (nixos-raspberrypi.lib.nixosSystem { system = "aarch64-linux"; specialArgs = { inherit self keys inputs; nixos-raspberrypi = nixos-raspberrypi; isCM4 = false; }; modules = uconsoleBaseModules ++ [ nixos-raspberrypi.nixosModules.sd-image ]; }).config.system.build.sdImage; }; }; }