Compare commits

..

29 Commits

Author SHA1 Message Date
5e17fd7dde merge: accept remote flake.nix 2026-07-04 23:50:01 -04:00
7172c7face fix: update compose submodule to fix hermes user ownership 2026-07-04 23:49:52 -04:00
3778069baf fix: use configureFlags to set PYTHON path for john cross-compile 2026-06-21 15:18:14 -04:00
8ec9ffe6a9 fix: clean john overlay with python3 + preConfigure symlink for cross-compile 2026-06-21 15:15:01 -04:00
16ec40b237 fix: use python3 + preConfigure symlink for john cross-compile (python not in PATH) 2026-06-21 15:12:12 -04:00
3ec8bab25b fix: add python to john nativeBuildInputs for cross-compile (opencl_generate_dynamic_loader.py) 2026-06-21 15:09:53 -04:00
2a4856e447 fix: add python3 to aiov2_ctl buildInputs so patchShebangs fixes the shebang 2026-06-21 15:07:49 -04:00
01f8166529 feat: add uConsole as remote builder for aarch64-linux native builds 2026-06-20 20:04:04 -04:00
84ce9de5ca restore native-build packages in config (wsjtx, fldigi, chirp, sdrpp, gqrx, inspectrum, john, foxtrotgps, viking, gpsbabel, trustedqsl) 2026-06-20 20:02:56 -04:00
14755f1ea6 revert native-build packages — cross-compile still fails for Qt5/gpsbabel/john, install via nix profile instead 2026-06-20 20:01:36 -04:00
f51155823e temp: comment out Qt5 packages (wsjtx, fldigi, sdrpp, gqrx, inspectrum) — cross-compile fails, installed via nix profile instead 2026-06-20 19:59:36 -04:00
73c12abec2 feat: re-integrate native-build packages (wsjtx, fldigi, chirp, sdrpp, gqrx, inspectrum, hashcat, john, foxtrotgps, viking, gpsbabel, trustedqsl) 2026-06-20 19:00:39 -04:00
a97c68fd81 fix: add rtkit and pipewire service for uConsole audio 2026-06-20 18:16:43 -04:00
bf2500dce8 fix: add missing packages (swww, emacs, udiskie, hyprshade) and wallpapers for uConsole 2026-06-20 18:16:00 -04:00
f0fa8ac942 fix: update dotfiles for transform 3 2026-06-20 17:54:16 -04:00
7899bf28f2 fix: sync dotfiles submodule, home.nix paths to hosts/ 2026-06-20 17:51:50 -04:00
282b4bc229 chore: remove stale temp file 2026-06-20 17:50:18 -04:00
905998466c fix: update home.nix host/ paths after dotfiles rename 2026-06-20 17:50:13 -04:00
6c34b92186 fix: update dotfiles submodule for host/ rename 2026-06-20 17:48:15 -04:00
7b3a5802a5 fix: update dotfiles submodule 2026-06-20 17:35:01 -04:00
1ab11b76d6 chore: update dotfiles submodule for per-host 2026-06-20 17:01:59 -04:00
3ce550691c fix: use zsh.initExtra for dotfiles config (no home.file conflict) 2026-06-20 16:25:50 -04:00
256979e6e5 fix: update dotfiles submodule for uConsole keyboard docs 2026-06-20 16:25:21 -04:00
095fa4c200 fix: add .zshrc to home-manager dotfiles 2026-06-20 16:25:06 -04:00
c430427617 fix: update dotfiles submodule for uConsole transform+keyboard 2026-06-20 16:22:20 -04:00
eeb10db5ed fix: define dotfiles as local path in home.nix (via submodule), fix swaync name 2026-06-20 16:03:58 -04:00
60a0bcfdd6 fix: dotfiles path via self (submodule), fix Nix syntax 2026-06-20 16:02:34 -04:00
7827638c5a fix: dotfiles path from submodule, not flake input 2026-06-20 16:01:37 -04:00
ceca908457 fix: replace dotfiles flake input with self.submodules=true (git submodule) 2026-06-20 16:01:00 -04:00
8 changed files with 304 additions and 314 deletions

288
flake.nix
View File

@@ -8,240 +8,46 @@
inputs.darwin.follows = ""; inputs.darwin.follows = "";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
agenix-rekey = {
url = "github:oddlama/agenix-rekey";
inputs.nixpkgs.follows = "nixpkgs";
};
lix = { lix = {
url = "git+https://git.lix.systems/lix-project/lix?ref=main"; url = "git+https://git.lix.systems/lix-project/lix?ref=main";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nixpkgs-uconsole.url = "github:NixOS/nixpkgs/nixos-25.11";
nixos-uconsole = { nixos-uconsole = {
url = "github:gortium/nixos-uconsole/pr/dcs-panel-detection"; url = "github:nixos-uconsole/nixos-uconsole";
inputs.nixpkgs.follows = "nixpkgs-uconsole"; inputs.nixpkgs.follows = "nixpkgs";
inputs.nixos-raspberrypi.follows = "nixos-raspberrypi";
}; };
nixos-raspberrypi = { nixos-raspberrypi = {
url = "github:gortium/nixos-raspberrypi/cm5-cross-v1"; url = "github:nvmd/nixos-raspberrypi/v1.20260517.0";
inputs.nixpkgs.follows = "nixpkgs-uconsole"; inputs.nixpkgs.follows = "nixpkgs";
}; };
self.submodules = true;
home-manager = { home-manager = {
url = "github:nix-community/home-manager/release-25.11"; url = "github:nix-community/home-manager/release-25.11";
inputs.nixpkgs.follows = "nixpkgs-uconsole"; inputs.nixpkgs.follows = "nixpkgs";
}; };
self.submodules = true;
}; };
outputs = { self, nixpkgs, agenix, agenix-rekey, lix outputs = { self, nixpkgs, agenix, lix, nixos-uconsole, nixos-raspberrypi, home-manager, ... }@inputs:
, nixpkgs-uconsole, nixos-uconsole, nixos-raspberrypi
, home-manager
, ... }@inputs:
let let
system = "x86_64-linux"; system = "x86_64-linux";
keys = import ./lib/keys.nix; keys = import ./lib/keys.nix;
paths = { paths = import ./lib/paths.nix;
flake = "/home/gortium/infra"; overlays = [
identities = [ agenix.overlays.default
"/home/gortium/.ssh/gortium_ssh_key" (import ./overlays/reticulum.nix) ];
"/etc/ssh/ssh_host_ed25519_key"
"/root/.age/bootstrap.key" ];
};
overlays = [ agenix.overlays.default (import ./overlays/reticulum.nix) ];
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system overlays; inherit system overlays;
config.allowUnfree = true; config.allowUnfree = true;
config.permittedInsecurePackages = [ "openclaw-2026.3.12" ]; config.permittedInsecurePackages = [
"openclaw-2026.3.12"
];
}; };
devShell = import ./shells/nix_dev.nix { devShell = import ./shells/nix_dev.nix {
inherit pkgs system agenix; inherit pkgs system agenix;
}; };
in
##############################################################################
# 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 = { nixosConfigurations = {
lazyworkhorse = nixpkgs.lib.nixosSystem { lazyworkhorse = nixpkgs.lib.nixosSystem {
specialArgs = { inherit system self keys paths inputs; }; specialArgs = { inherit system self keys paths inputs; };
@@ -250,22 +56,23 @@
nixpkgs.overlays = overlays; nixpkgs.overlays = overlays;
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
nixpkgs.config.rocmSupport = true; nixpkgs.config.rocmSupport = true;
nixpkgs.config.permittedInsecurePackages = [ "openclaw-2026.3.12" ]; nixpkgs.config.permittedInsecurePackages = [
"openclaw-2026.3.12"
];
nix.package = lix.packages.${system}.default; nix.package = lix.packages.${system}.default;
} }
inputs.home-manager.nixosModules.home-manager
agenix.nixosModules.default agenix.nixosModules.default
./hosts/lazyworkhorse/configuration.nix ./hosts/lazyworkhorse/configuration.nix
./hosts/lazyworkhorse/hardware-configuration.nix ./hosts/lazyworkhorse/hardware-configuration.nix
./modules/nixos/filesystem/hoardingcow-mount.nix ./modules/nixos/filesystem/hoardingcow-mount.nix
./modules/nixos/services/docker_manager.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/open_code_server.nix
./modules/nixos/services/clamav.nix ./modules/nixos/services/ollama_init_custom_models.nix
./modules/nixos/services/openclaw_node.nix
./modules/nixos/filesystem/poup-16t-disk.nix
./modules/nixos/security/ai-worker-restricted.nix ./modules/nixos/security/ai-worker-restricted.nix
./users/gortium/gortium.nix ./users/gortium.nix
./users/ai-worker/ai-worker.nix ./users/ai-worker.nix
]; ];
}; };
@@ -280,42 +87,27 @@
} }
./hosts/cyt-pi/configuration.nix ./hosts/cyt-pi/configuration.nix
./hosts/cyt-pi/hardware-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 { uConsole = nixos-raspberrypi.lib.nixosSystem {
system = "aarch64-linux"; specialArgs = { inherit self keys paths inputs nixos-raspberrypi; };
specialArgs = { modules = [
inherit self keys paths inputs; {
nixos-raspberrypi = nixos-raspberrypi; nixpkgs.overlays = overlays;
isCM4 = false; nixpkgs.config.allowUnfree = true;
}; nixpkgs.hostPlatform = "aarch64-linux";
modules = uconsoleBaseModules; nix.package = lix.packages."aarch64-linux".default;
}
nixos-raspberrypi.nixosModules.raspberry-pi-5.base
nixos-uconsole.nixosModules.uconsole-cm5
agenix.nixosModules.default
./modules/nixos/hardware/uconsole-cm5-aio-v2.nix
./hosts/uConsole/configuration.nix
./hosts/uConsole/hardware-configuration.nix
];
}; };
}; };
agenix-rekey = agenix-rekey.configure {
userFlake = self;
nixosConfigurations = self.nixosConfigurations;
};
devShells.${system}.default = devShell; 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;
};
}; };
} }

View File

@@ -569,3 +569,19 @@
} }
# Remote builder — uConsole for aarch64-linux native builds
nix.distributedBuilds = true;
nix.buildMachines = [{
hostName = "192.168.1.120";
systems = ["aarch64-linux"];
maxJobs = 4;
supportedFeatures = ["big-parallel" "nixos-test" "benchmark" "gccarch-armv8-a"];
sshUser = "builder";
sshKey = "/home/ai-worker/id_deploy";
}];
nix.extraOptions = '
builders-use-substitutes = true
fallback = true
';

View File

@@ -1,11 +1,11 @@
{ config, lib, pkgs, keys, ... }: { config, lib, pkgs, keys, ... }:
{ {
networking.hostName = "uConsole"; networking.hostName = "uConsole";
time.timeZone = "America/Montreal"; time.timeZone = "America/Montreal";
i18n.defaultLocale = "en_CA.UTF-8"; i18n.defaultLocale = "en_CA.UTF-8";
system.stateVersion = "25.11"; system.stateVersion = "25.11";
# Boot & Hardware
boot.loader.raspberry-pi.bootloader = "kernel";
# SSH — root access avec clés gortium + ai-worker # SSH — root access avec clés gortium + ai-worker
services.openssh = { services.openssh = {
enable = true; enable = true;
@@ -14,41 +14,32 @@
PasswordAuthentication = lib.mkForce false; PasswordAuthentication = lib.mkForce false;
}; };
}; };
users.users.root.openssh.authorizedKeys.keys = with keys; [ users.users.root.openssh.authorizedKeys.keys = with keys; [
users.gortium.main users.gortium.main
users.ai-worker.main users.ai-worker.main
]; ];
# AI worker user (Hermes SSH access)
users.users.ai-worker = {
isNormalUser = false;
shell = pkgs.bash;
openssh.authorizedKeys.keys = with keys; [
users.ai-worker.main
];
};
# Age secret for gortium password (file created by user) # Age secret for gortium password (file created by user)
age.secrets.gortium_password = { age.secrets.gortium_password = {
file = ../secrets/gortium_password.age; file = ../../secrets/gortium_password.age;
}; };
# WiFi via NetworkManager
# Password file for gortium (merges with users/gortium/default.nix)
# WiFi via NetworkManager + secret agenix
networking.networkmanager.enable = true; networking.networkmanager.enable = true;
# Firmware # Firmware
hardware.enableRedistributableFirmware = true; hardware.enableRedistributableFirmware = true;
# RealtimeKit for PipeWire audio
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
# Hyprland Wayland compositor (manual start — no SDDM) # Hyprland Wayland compositor (manual start — no SDDM)
programs.hyprland = { programs.hyprland = {
enable = true; enable = true;
xwayland.enable = true; xwayland.enable = true;
}; };
# HackerGadgets AIO v2 board
# HackerGadgets AIO v2 board — GPIO rail control, aiov2_ctl CLI
hardware.uconsole-cm5-aio-v2 = { hardware.uconsole-cm5-aio-v2 = {
enable = true; enable = true;
bootRails = { bootRails = {
@@ -59,4 +50,165 @@
}; };
enableGPS = false; enableGPS = false;
}; };
# User
users.users.gortium = {
isNormalUser = true;
extraGroups = [ "wheel" "networkmanager" "video" "dialout" "kismet" ];
hashedPasswordFile = config.age.secrets.gortium_password.path;
openssh.authorizedKeys.keys = [
keys.users.gortium.main
keys.users.gortium.gitea
];
};
security.sudo.extraRules = [
{
users = [ "gortium" ];
commands = [{
command = "ALL";
options = [ "NOPASSWD" ];
}];
}
];
# ============================================================
# Package groups
# ============================================================
# ============================================================
# CROSS-COMPILE REMOVALS — packages removed for aarch64 bootstrap
# ============================================================
# These packages fail to cross-compile for aarch64.
# Install them natively AFTER the first successful switch.
#
# Removed: Reason:
# inspectrum — Qt5 cross-compile cascade fails (qtsvg mismatched qtbase deps)
# hashcat — Makefile calls gcc directly (cross-compiler not used)
# neovim — Same as hashcat: Makefile calls gcc directly (cross-compiler not used)
# clamav — cmake try_run + Rust proc-macro linker for aarch64
# sdrpp — glfw/wxPython cross-compile fails
# gqrx — Qt5 cross-compile cascade fails
# emacs-pgtk → emacs-nox — GTK3 + mailutils → gss → shishi chain
# viking — GTK3 GPS map editor
# foxtrotgps — GTK2 GPS app
# js8call — QtQuick3D dep
# wsjtx — qtbase/Qt5 linker fails (collect2: ld returned 1)
# fldigi — same: qtbase/Qt5 linker fails
# gpsbabel — qmake can't find cross-compiler g++
# john — configure script needs python (not in PATH during cross-compile)
# trustedqsl — needs wxWidgets (unavailable in cross-compile)
# chirp — depends on wxPython (fails cross-compile: GTK3 + wx build)
# ============================================================
environment.systemPackages = with pkgs; [
# ===== Base =====
# emacs-pgtk — removed for bootstrap (GTK3 cross-compile fails)
# emacs-nox — removed for bootstrap (depends on mailutils -> gss -> shishi, cross-compile fails)
git
ripgrep
fd
htop
tmux
# ===== HAM Radio =====
wsjtx # removed for bootstrap - now native
fldigi # removed for bootstrap - now native
pat # Winlink client
direwolf # AX.25 packet modem
chirp # Radio programming tool - now native
hamlib # Ham radio control libraries
trustedqsl # Logbook of the World (LoTW) - now native
# ===== SDR / RF =====
sdrpp # removed for bootstrap - now native
gqrx # removed for bootstrap - now native
rtl-sdr # RTL-SDR drivers & utilities
inspectrum # removed for bootstrap - now native
soapysdr-with-plugins # SoapySDR + hardware support plugins
# ===== Mesh / LoRa =====
reticulumStack # Reticulum Network Stack
lxmf # LXMF messaging protocol
nomadnet # Nomad Network client
# ===== Security =====
nmap
aircrack-ng
kismet # Wi-Fi monitor / IDS
bettercap # MITM/network attack framework
wireshark-cli # Packet analyzer
john # John the Ripper - now native
sqlmap # SQL injection tool
# ===== GPS / Maps =====
foxtrotgps # removed for bootstrap - now native
viking # removed for bootstrap - now native
gpsbabel # GPS data conversion - now native
];
# ============================================================
# Reticulum Service (rnsd)
# ============================================================
systemd.services.rnsd = {
description = "Reticulum Network Stack Daemon";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "gortium";
Group = "gortium";
ExecStart = "${pkgs.reticulumStack}/bin/rnsd";
Restart = "always";
RestartSec = "10s";
LimitNOFILE = 65536;
};
};
# ============================================================
# Kismet Service (Wi-Fi monitoring / mesh node)
# ============================================================
systemd.services.kismet = {
description = "Kismet Wi-Fi Monitor & IDS";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "gortium";
Group = "kismet";
ExecStart = "${pkgs.kismet}/bin/kismet -c wlan0 --log-prefix=/home/gortium/kismet_logs --no-nc-ui";
Restart = "always";
RestartSec = "10s";
};
};
# ============================================================
# Kernel modules for SDR and radio
# ============================================================
boot.kernelModules = [
"88x2bu" # Realtek 8812/8821BU USB WiFi
"rtl8xxxu" # RTL8188/8192/8723 USB WiFi
"rtl2832_sdr" # RTL-SDR kernel module
"dvb_usb_rtl28xxu" # RTL-SDR DVB-T
];
# ============================================================
# Extra udev rules for SDR and HAM radio devices
# ============================================================
services.udev.packages = with pkgs; [ rtl-sdr ];
# ============================================================
# Enable IPv6 for Reticulum mesh
# ============================================================
networking.enableIPv6 = true;
# ============================================================
# Firewall
# ============================================================
networking.firewall.allowedTCPPorts = [ 22 ];
networking.firewall.allowedUDPPorts = [ ];
# ============================================================
# agenix-rekey — automatic secret re-encryption at deploy time
# ============================================================
age.rekey = {
# Master identities for encrypting secrets (on Thierry's laptop)
masterIdentities = [
"/home/gortium/.ssh/gortium_ssh_key"
];
# uConsole SSH host pubkey — for automatic rekey at build time
# Once uConsole is deployed, replace with actual pubkey from:
# ssh-keyscan uConsole.local | ssh-to-age
hostPubkey = "age1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs3290gq"; # dummy — replace after bootstrap
};
# Pipewire overlay: drop libcamera (fixes aarch64 cross-compile — rpi-pisp blocks)
nixpkgs.overlays = [
(final: prev: {
pipewire = prev.pipewire.override { libcamera = null; };
})
];
} }

View File

@@ -47,6 +47,7 @@ let
}; };
dontUnpack = true; dontUnpack = true;
buildInputs = [ pkgs.python3 ];
installPhase = '' installPhase = ''
mkdir -p $out/bin $out/share/aiov2_ctl/img mkdir -p $out/bin $out/share/aiov2_ctl/img

View File

@@ -1,5 +1,7 @@
{ pkgs, inputs, config, keys, ... }: { { pkgs, inputs, config, keys, ... }: {
home-manager.extraSpecialArgs = { inherit (config.networking) hostName; dotfiles = inputs.dotfiles.outPath # flake input (not submodule); }; home-manager.extraSpecialArgs = {
inherit (config.networking) hostName;
};
home-manager.users.gortium = import ./home.nix; home-manager.users.gortium = import ./home.nix;
users.users.gortium = { users.users.gortium = {
isNormalUser = true; isNormalUser = true;

View File

@@ -2,6 +2,7 @@
let let
isUconsole = hostName == "uConsole"; isUconsole = hostName == "uConsole";
dotfiles = ../../assets/dotfiles;
in { in {
home.username = "gortium"; home.username = "gortium";
home.homeDirectory = "/home/gortium"; home.homeDirectory = "/home/gortium";
@@ -33,6 +34,9 @@ in {
".config/wofi/config".source = "${dotfiles}/wofi/.config/wofi/config"; ".config/wofi/config".source = "${dotfiles}/wofi/.config/wofi/config";
# yazi # yazi
# wallpapers
".config/wallpapers".source = "${dotfiles}/wallpapers/.config/wallpapers";
".config/yazi/yazi.toml".source = "${dotfiles}/yazi/.config/yazi/yazi.toml"; ".config/yazi/yazi.toml".source = "${dotfiles}/yazi/.config/yazi/yazi.toml";
# hyprland — common config # hyprland — common config
@@ -43,22 +47,45 @@ in {
".config/hypr/mocha.conf".source = "${dotfiles}/hypr/.config/hypr/mocha.conf"; ".config/hypr/mocha.conf".source = "${dotfiles}/hypr/.config/hypr/mocha.conf";
# hyprland — host-specific monitor config # hyprland — host-specific monitor config
".config/hypr/host/monitors.conf".source = ".config/hypr/hosts/monitors.conf".source =
if isUconsole if isUconsole
then "${dotfiles}/hypr/.config/hypr/hosts/uconsole.conf" then "${dotfiles}/hypr/.config/hypr/hosts/uconsole.conf"
else "${dotfiles}/hypr/.config/hypr/hosts/laptop.conf"; else "${dotfiles}/hypr/.config/hypr/hosts/laptop.conf";
}; };
programs.bash.enable = true;
programs.zsh = {
enable = true;
initExtra = builtins.readFile "${dotfiles}/zsh/.zshrc";
};
home.packages = with pkgs; [ home.packages = with pkgs; [
git zsh tmux starship git zsh tmux starship
neovim kitty neovim kitty
btop yazi ripgrep fd fzf btop yazi ripgrep fd fzf
] ++ lib.optionals (!isUconsole) [ htop unzip wget jq
waybar wofi swww hyprshot hyprland hyprlock hypridle hyprpaper
] ++ lib.optionals isUconsole [ waybar wofi dunst
brightnessctl libnotify mako
swaynotificationcenter
swww
emacs
udiskie
hyprshade
networkmanagerapplet
pavucontrol
]; ];
programs.zsh.enable = true; xdg.userDirs = {
programs.starship.enable = true; enable = true;
createDirectories = true;
desktop = "$HOME/desktop";
documents = "$HOME/documents";
download = "$HOME/downloads";
music = "$HOME/music";
pictures = "$HOME/pictures";
publicShare = "$HOME/public";
templates = "$HOME/templates";
videos = "$HOME/videos";
};
} }