Compare commits
1 Commits
fix/backup
...
hermes-bac
| Author | SHA1 | Date | |
|---|---|---|---|
| d0c9ae96ba |
Submodule assets/compose updated: 4729af5774...dab158da0a
Submodule assets/dotfiles updated: 3c06c3938c...f45387456b
23
flake.nix
23
flake.nix
@@ -57,7 +57,6 @@
|
|||||||
inherit pkgs system agenix;
|
inherit pkgs system agenix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# CROSS-COMPILE WORKAROUNDS — packages that fail aarch64 cross-compile
|
# CROSS-COMPILE WORKAROUNDS — packages that fail aarch64 cross-compile
|
||||||
#
|
#
|
||||||
@@ -188,12 +187,6 @@
|
|||||||
# perl-ldap fails cross-compile (Module::Install needs dynamic loading)
|
# perl-ldap fails cross-compile (Module::Install needs dynamic loading)
|
||||||
# Strip it from john deps -- the perl scripts that need it are not critical
|
# Strip it from john deps -- the perl scripts that need it are not critical
|
||||||
john = prev.john.overrideAttrs (old: {
|
john = prev.john.overrideAttrs (old: {
|
||||||
nativeBuildInputs = (old.nativeBuildInputs or []) ++ [
|
|
||||||
prev.buildPackages.python3 # python3 for opencl_generate_dynamic_loader.py
|
|
||||||
];
|
|
||||||
configureFlags = (old.configureFlags or []) ++ [
|
|
||||||
"ac_cv_prog_PYTHON=${prev.buildPackages.python3}/bin/python3"
|
|
||||||
];
|
|
||||||
propagatedBuildInputs = builtins.filter
|
propagatedBuildInputs = builtins.filter
|
||||||
(x: x?pname && x.pname != "perl-ldap")
|
(x: x?pname && x.pname != "perl-ldap")
|
||||||
(old.propagatedBuildInputs or []);
|
(old.propagatedBuildInputs or []);
|
||||||
@@ -228,7 +221,7 @@
|
|||||||
nixos-raspberrypi.lib.inject-overlays
|
nixos-raspberrypi.lib.inject-overlays
|
||||||
nixos-raspberrypi.lib.inject-overlays-global
|
nixos-raspberrypi.lib.inject-overlays-global
|
||||||
nixos-uconsole.nixosModules.uconsole-cm5
|
nixos-uconsole.nixosModules.uconsole-cm5
|
||||||
./modules/nixos/hardware/uConsole-aio-v2.nix
|
./modules/nixos/hardware/uconsole-cm5-aio-v2.nix
|
||||||
({ config, lib, pkgs, inputs, ... }: let
|
({ config, lib, pkgs, inputs, ... }: let
|
||||||
lixCross = import inputs.nixpkgs-uconsole {
|
lixCross = import inputs.nixpkgs-uconsole {
|
||||||
localSystem = { system = "x86_64-linux"; };
|
localSystem = { system = "x86_64-linux"; };
|
||||||
@@ -239,8 +232,8 @@
|
|||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
agenix.nixosModules.default
|
agenix.nixosModules.default
|
||||||
agenix-rekey.nixosModules.default
|
agenix-rekey.nixosModules.default
|
||||||
./hosts/uConsole/configuration.nix
|
./hosts/uconsole-cm5/configuration.nix
|
||||||
./hosts/uConsole/hardware-configuration.nix
|
./hosts/uconsole-cm5/hardware-configuration.nix
|
||||||
./modules/nixos/services/remote-builder.nix
|
./modules/nixos/services/remote-builder.nix
|
||||||
./modules/nixos/services/wireguard-client.nix
|
./modules/nixos/services/wireguard-client.nix
|
||||||
./modules/nixos/services/clamav.nix
|
./modules/nixos/services/clamav.nix
|
||||||
@@ -262,7 +255,6 @@
|
|||||||
}
|
}
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
agenix.nixosModules.default
|
agenix.nixosModules.default
|
||||||
agenix-rekey.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
|
||||||
@@ -271,12 +263,9 @@
|
|||||||
./modules/nixos/services/ollama_init_custom_models.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/clamav.nix
|
||||||
./modules/nixos/services/wireguard-client.nix
|
|
||||||
./modules/nixos/services/remote-builder.nix
|
|
||||||
./modules/nixos/security/ai-worker-restricted.nix
|
./modules/nixos/security/ai-worker-restricted.nix
|
||||||
./users/gortium/gortium.nix
|
./users/gortium/gortium.nix
|
||||||
./users/ai-worker/ai-worker.nix
|
./users/ai-worker/ai-worker.nix
|
||||||
./users/builder.nix
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -289,8 +278,6 @@
|
|||||||
nixpkgs.hostPlatform = "aarch64-linux";
|
nixpkgs.hostPlatform = "aarch64-linux";
|
||||||
nix.package = lix.packages."aarch64-linux".default;
|
nix.package = lix.packages."aarch64-linux".default;
|
||||||
}
|
}
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
agenix.nixosModules.default
|
|
||||||
./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/remote-builder.nix
|
||||||
@@ -299,7 +286,7 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
uConsole = nixpkgs-uconsole.lib.nixosSystem {
|
uconsole-cm5 = nixpkgs-uconsole.lib.nixosSystem {
|
||||||
system = "aarch64-linux";
|
system = "aarch64-linux";
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit self keys paths inputs;
|
inherit self keys paths inputs;
|
||||||
@@ -318,7 +305,7 @@
|
|||||||
devShells.${system}.default = devShell;
|
devShells.${system}.default = devShell;
|
||||||
|
|
||||||
packages.${system} = {
|
packages.${system} = {
|
||||||
uConsole-image = (nixos-raspberrypi.lib.nixosSystem {
|
uconsole-cm5-image = (nixos-raspberrypi.lib.nixosSystem {
|
||||||
system = "aarch64-linux";
|
system = "aarch64-linux";
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit self keys inputs;
|
inherit self keys inputs;
|
||||||
|
|||||||
@@ -21,7 +21,14 @@
|
|||||||
settings.PermitRootLogin = "prohibit-password";
|
settings.PermitRootLogin = "prohibit-password";
|
||||||
};
|
};
|
||||||
|
|
||||||
# User (defined in users/gortium/gortium.nix)
|
# User
|
||||||
|
users.users.gortium = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" "networkmanager" "kismet" ];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
# Populate with your public key
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
# CYT Project Dependencies (Headless)
|
# CYT Project Dependencies (Headless)
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
@@ -70,12 +77,6 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# Age secrets
|
|
||||||
age.secrets.gortium_password = {
|
|
||||||
file = ../../secrets/gortium_password.age;
|
|
||||||
};
|
|
||||||
|
|
||||||
# CYT Application Service
|
# CYT Application Service
|
||||||
systemd.services.cyt-app = {
|
systemd.services.cyt-app = {
|
||||||
description = "Chasing Your Tail - Target Detector";
|
description = "Chasing Your Tail - Target Detector";
|
||||||
|
|||||||
@@ -9,12 +9,8 @@
|
|||||||
hoardingcow-mount.enable = true;
|
hoardingcow-mount.enable = true;
|
||||||
|
|
||||||
# Flakesss
|
# Flakesss
|
||||||
nix.settings.experimental-features = [ "nix-command" "flakes" "flake-self-attrs" ];
|
nix.settings.experimental-features = [ "nix-command" "flakes" "flake-self-attrs" "ca-derivations" ];
|
||||||
nix.settings.trusted-users = [ "root" "gortium" ];
|
nix.settings.trusted-users = [ "root" "gortium" ];
|
||||||
nix.settings.extra-platforms = [ "aarch64-linux" ];
|
|
||||||
|
|
||||||
# QEMU binfmt for cross-building aarch64 NixOS targets
|
|
||||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
|
||||||
|
|
||||||
# Garbage collection
|
# Garbage collection
|
||||||
nix.gc = {
|
nix.gc = {
|
||||||
@@ -170,8 +166,9 @@
|
|||||||
settings = {
|
settings = {
|
||||||
PasswordAuthentication = false;
|
PasswordAuthentication = false;
|
||||||
KbdInteractiveAuthentication = false;
|
KbdInteractiveAuthentication = false;
|
||||||
};
|
# ============================================================
|
||||||
hostKeys = [
|
# ClamAV antivirus — daemon, hourly updates, daily scan, on-access
|
||||||
|
# ============================================================
|
||||||
{
|
{
|
||||||
path = "/etc/ssh/ssh_host_ed25519_key";
|
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||||
type = "ed25519";
|
type = "ed25519";
|
||||||
@@ -251,9 +248,7 @@
|
|||||||
|
|
||||||
# Private host ssh key managed by agenix
|
# Private host ssh key managed by agenix
|
||||||
age = {
|
age = {
|
||||||
identityPaths = paths.identities ++ [
|
identityPaths = paths.identities;
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
|
||||||
];
|
|
||||||
secrets = {
|
secrets = {
|
||||||
containers_env = {
|
containers_env = {
|
||||||
file = ../../secrets/containers.env.age;
|
file = ../../secrets/containers.env.age;
|
||||||
@@ -276,6 +271,13 @@
|
|||||||
mode = "0600";
|
mode = "0600";
|
||||||
path = "/home/ai-worker/.ssh/ai_ssh_key";
|
path = "/home/ai-worker/.ssh/ai_ssh_key";
|
||||||
};
|
};
|
||||||
|
openclaw_gateway_token = {
|
||||||
|
file = ../../secrets/openclaw_gateway_token.age;
|
||||||
|
owner = "root";
|
||||||
|
group = "ai-worker";
|
||||||
|
mode = "0440";
|
||||||
|
path = "/run/secrets/openclaw_gateway_token";
|
||||||
|
};
|
||||||
wireguard_private_key = {
|
wireguard_private_key = {
|
||||||
file = ../../secrets/wireguard_private_key.age;
|
file = ../../secrets/wireguard_private_key.age;
|
||||||
owner = "root";
|
owner = "root";
|
||||||
@@ -290,21 +292,17 @@
|
|||||||
mode = "0400";
|
mode = "0400";
|
||||||
path = "/run/secrets/wireguard_preshared_key";
|
path = "/run/secrets/wireguard_preshared_key";
|
||||||
};
|
};
|
||||||
builder_key = {
|
|
||||||
file = ../../secrets/builder_key.age;
|
|
||||||
owner = "root";
|
|
||||||
group = "root";
|
|
||||||
mode = "0600";
|
|
||||||
path = "/etc/ssh/builder_key";
|
|
||||||
};
|
|
||||||
gortium_password = {
|
|
||||||
file = ../../secrets/gortium_password.age;
|
|
||||||
owner = "gortium";
|
|
||||||
group = "gortium";
|
|
||||||
mode = "0400";
|
|
||||||
path = "/run/secrets/gortium_password";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# OpenClaw Node service (host-side execution for Docker gateway)
|
||||||
|
services.openclaw-node = {
|
||||||
|
enable = true;
|
||||||
|
user = "ai-worker";
|
||||||
|
gatewayHost = "127.0.0.1";
|
||||||
|
gatewayPort = 18789;
|
||||||
|
gatewayTokenFile = "/run/secrets/openclaw_gateway_token";
|
||||||
|
displayName = "lazyworkhorse-host";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Public host ssh key (kept in sync with the private one)
|
# Public host ssh key (kept in sync with the private one)
|
||||||
@@ -569,29 +567,5 @@
|
|||||||
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
||||||
system.stateVersion = "25.05"; # Did you read the comment?
|
system.stateVersion = "25.05"; # Did you read the comment?
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# Remote builder — dispatches aarch64-linux builds to uConsole
|
|
||||||
# ============================================================
|
|
||||||
services.remoteBuilder = {
|
|
||||||
enable = true;
|
|
||||||
machines = [
|
|
||||||
{
|
|
||||||
hostName = "192.168.1.120";
|
|
||||||
port = 22;
|
|
||||||
sshUser = "builder";
|
|
||||||
sshKey = config.age.secrets.builder_key.path;
|
|
||||||
systems = [ "aarch64-linux" ];
|
|
||||||
maxJobs = 4;
|
|
||||||
}
|
}
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
# agenix-rekey — automatic re-encryption for each target host
|
|
||||||
age.rekey = {
|
|
||||||
masterIdentities = [
|
|
||||||
"/home/gortium/.ssh/gortium_ssh_key"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,240 +0,0 @@
|
|||||||
{ config, lib, pkgs, keys, ... }:
|
|
||||||
{
|
|
||||||
networking.hostName = "uConsole";
|
|
||||||
time.timeZone = "America/Montreal";
|
|
||||||
i18n.defaultLocale = "en_CA.UTF-8";
|
|
||||||
system.stateVersion = "25.11";
|
|
||||||
# Boot & Hardware
|
|
||||||
boot.loader.raspberry-pi.bootloader = "kernel";
|
|
||||||
# SSH — root access avec clés gortium + ai-worker
|
|
||||||
services.openssh = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
PermitRootLogin = lib.mkForce "prohibit-password";
|
|
||||||
PasswordAuthentication = lib.mkForce false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
users.users.root.openssh.authorizedKeys.keys = with keys; [
|
|
||||||
users.gortium.main
|
|
||||||
users.ai-worker.main
|
|
||||||
];
|
|
||||||
# Age secret for gortium password (file created by user)
|
|
||||||
age.secrets.gortium_password = {
|
|
||||||
file = ../../secrets/gortium_password.age;
|
|
||||||
};
|
|
||||||
# WiFi via NetworkManager
|
|
||||||
networking.networkmanager.enable = true;
|
|
||||||
# Firmware
|
|
||||||
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)
|
|
||||||
programs.hyprland = {
|
|
||||||
enable = true;
|
|
||||||
xwayland.enable = true;
|
|
||||||
};
|
|
||||||
# HackerGadgets AIO v2 board
|
|
||||||
hardware.uconsole-cm5-aio-v2 = {
|
|
||||||
enable = true;
|
|
||||||
bootRails = {
|
|
||||||
GPS = false;
|
|
||||||
LORA = false;
|
|
||||||
SDR = false;
|
|
||||||
USB = 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 (native-only, needs remote build)
|
|
||||||
# fldigi # removed for bootstrap - now native (native-only, needs remote build)
|
|
||||||
pat # Winlink client
|
|
||||||
direwolf # AX.25 packet modem
|
|
||||||
# chirp # Radio programming tool - now native (native-only, needs remote build)
|
|
||||||
hamlib # Ham radio control libraries
|
|
||||||
# trustedqsl # Logbook of the World (LoTW) - now native (native-only, needs remote build)
|
|
||||||
# ===== SDR / RF =====
|
|
||||||
# sdrpp # removed for bootstrap - now native (native-only, needs remote build)
|
|
||||||
# gqrx # removed for bootstrap - now native (native-only, needs remote build)
|
|
||||||
rtl-sdr # RTL-SDR drivers & utilities
|
|
||||||
# inspectrum # removed for bootstrap - now native (native-only, needs remote build)
|
|
||||||
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 (native-only, needs remote build)
|
|
||||||
#viking # removed for bootstrap - now native (native-only, needs remote build)
|
|
||||||
#gpsbabel # GPS data conversion - now native (native-only, needs remote build)
|
|
||||||
];
|
|
||||||
# ============================================================
|
|
||||||
# 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 = [ ];
|
|
||||||
# ============================================================
|
|
||||||
# Remote builder — dispatches x86_64-linux builds to lazyworkhorse
|
|
||||||
# ============================================================
|
|
||||||
services.remoteBuilder = {
|
|
||||||
enable = true;
|
|
||||||
machines = [
|
|
||||||
{
|
|
||||||
hostName = "lazyworkhorse.net";
|
|
||||||
port = 2424;
|
|
||||||
sshUser = "builder";
|
|
||||||
sshKey = config.age.secrets.builder_key.path;
|
|
||||||
systems = [ "x86_64-linux" ];
|
|
||||||
maxJobs = 36;
|
|
||||||
supportedFeatures = [ "benchmark" "big-parallel" "nixos-test" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
# Age secret for builder SSH key (remote building)
|
|
||||||
age.secrets.builder_key = {
|
|
||||||
file = ../../secrets/builder_key.age;
|
|
||||||
};
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
age.identityPaths = [
|
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
|
||||||
];
|
|
||||||
|
|
||||||
# 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 = "age1un8td4jzkhg5fm4jja7z3aznskc8hlcm8ky0j2f70tv74rulwgaqtpemn2"; # uConsole CM5 SSH host key
|
|
||||||
};
|
|
||||||
|
|
||||||
# Pipewire overlay: drop libcamera (fixes aarch64 cross-compile — rpi-pisp blocks)
|
|
||||||
nixpkgs.overlays = [
|
|
||||||
(final: prev: {
|
|
||||||
pipewire = prev.pipewire.override { libcamera = null; };
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
||||||
62
hosts/uconsole-cm5/configuration.nix
Normal file
62
hosts/uconsole-cm5/configuration.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{ config, lib, pkgs, keys, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
networking.hostName = "uConsole";
|
||||||
|
time.timeZone = "America/Montreal";
|
||||||
|
i18n.defaultLocale = "en_CA.UTF-8";
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
|
||||||
|
# SSH — root access avec clés gortium + ai-worker
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PermitRootLogin = lib.mkForce "prohibit-password";
|
||||||
|
PasswordAuthentication = lib.mkForce false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.root.openssh.authorizedKeys.keys = with keys; [
|
||||||
|
users.gortium.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.secrets.gortium_password = {
|
||||||
|
file = ../secrets/gortium_password.age;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Password file for gortium (merges with users/gortium/default.nix)
|
||||||
|
|
||||||
|
# WiFi via NetworkManager + secret agenix
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
|
||||||
|
# Firmware
|
||||||
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|
||||||
|
# Hyprland Wayland compositor (manual start — no SDDM)
|
||||||
|
programs.hyprland = {
|
||||||
|
enable = true;
|
||||||
|
xwayland.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# HackerGadgets AIO v2 board — GPIO rail control, aiov2_ctl CLI
|
||||||
|
hardware.uconsole-cm5-aio-v2 = {
|
||||||
|
enable = true;
|
||||||
|
bootRails = {
|
||||||
|
GPS = false;
|
||||||
|
LORA = false;
|
||||||
|
SDR = false;
|
||||||
|
USB = false;
|
||||||
|
};
|
||||||
|
enableGPS = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
11
lib/keys.nix
11
lib/keys.nix
@@ -9,13 +9,6 @@
|
|||||||
ai-worker = {
|
ai-worker = {
|
||||||
main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAXeGtPPcsP2IYRQNvII41NVWhJsarEk8c4qxs/a5sXf";
|
main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAXeGtPPcsP2IYRQNvII41NVWhJsarEk8c4qxs/a5sXf";
|
||||||
};
|
};
|
||||||
|
|
||||||
builder = {
|
|
||||||
# Same key on both hosts for bidirectional remote building.
|
|
||||||
# Generate with: ssh-keygen -t ed25519 -f /etc/ssh/builder_key -N ""
|
|
||||||
# Replace the placeholder below with the public key (builder_key.pub).
|
|
||||||
main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIByG79NM/rk13q3MTow9Ezb8pe3RWoQ76Mv8atASp3Ri";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hosts = {
|
hosts = {
|
||||||
@@ -25,9 +18,5 @@
|
|||||||
gitea = "";
|
gitea = "";
|
||||||
bootstrap = "age1r796v2uldtspawyh863pks74sd2pwcan8j4e4pjzsvkmr3vjja9qpz5ste";
|
bootstrap = "age1r796v2uldtspawyh863pks74sd2pwcan8j4e4pjzsvkmr3vjja9qpz5ste";
|
||||||
};
|
};
|
||||||
uConsole = {
|
|
||||||
main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICasvsmaHuNVaWnjwuBfoMXyY/6PIqGL8yxstPBb46u4";
|
|
||||||
bootstrap = "age1un8td4jzkhg5fm4jja7z3aznskc8hlcm8ky0j2f70tv74rulwgaqtpemn2";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ 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
|
||||||
64
modules/nixos/services/openclaw_node.nix
Normal file
64
modules/nixos/services/openclaw_node.nix
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.openclaw-node;
|
||||||
|
openclawPkg = pkgs.openclaw;
|
||||||
|
in {
|
||||||
|
options.services.openclaw-node = {
|
||||||
|
enable = lib.mkEnableOption "OpenClaw Node service";
|
||||||
|
|
||||||
|
user = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "ai-worker";
|
||||||
|
description = "User to run the OpenClaw headless node as.";
|
||||||
|
};
|
||||||
|
|
||||||
|
gatewayHost = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "127.0.0.1";
|
||||||
|
description = "Gateway host (IP or hostname).";
|
||||||
|
};
|
||||||
|
|
||||||
|
gatewayPort = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 18789;
|
||||||
|
description = "Gateway WebSocket port.";
|
||||||
|
};
|
||||||
|
|
||||||
|
gatewayTokenFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "";
|
||||||
|
description = "Path to file containing the gateway auth token.";
|
||||||
|
};
|
||||||
|
|
||||||
|
displayName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "lazyworkhorse-host";
|
||||||
|
description = "Display name for this node (shown in pairing).";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
systemd.services.openclaw-node = {
|
||||||
|
description = "OpenClaw Headless Node Service";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "exec";
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.user;
|
||||||
|
WorkingDirectory = "/home/${cfg.user}";
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.bash}/bin/bash -c 'export OPENCLAW_GATEWAY_TOKEN=$(cat ${cfg.gatewayTokenFile}) && exec ${openclawPkg}/bin/openclaw node run --host ${cfg.gatewayHost} --port ${toString cfg.gatewayPort} --display-name "${cfg.displayName}"'
|
||||||
|
'';
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 5;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
NODE_ENV = "production";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,71 +3,69 @@ let
|
|||||||
cfg = config.services.remoteBuilder;
|
cfg = config.services.remoteBuilder;
|
||||||
in {
|
in {
|
||||||
options.services.remoteBuilder = {
|
options.services.remoteBuilder = {
|
||||||
enable = lib.mkEnableOption "remote Nix build machine";
|
enable = lib.mkEnableOption "remote Nix build machine (lazyworkhorse server)";
|
||||||
|
|
||||||
machines = lib.mkOption {
|
buildMachine = {
|
||||||
type = lib.types.listOf (lib.types.submodule {
|
host = lib.mkOption {
|
||||||
options = {
|
|
||||||
hostName = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
|
default = "lazyworkhorse.net";
|
||||||
description = "Hostname or IP of the remote build machine.";
|
description = "Hostname or IP of the remote build machine.";
|
||||||
};
|
};
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 22;
|
|
||||||
description = "SSH port.";
|
|
||||||
};
|
|
||||||
sshUser = lib.mkOption {
|
sshUser = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "builder";
|
default = "ai-worker";
|
||||||
description = "SSH user on the remote build machine.";
|
description = "SSH user on the remote build machine.";
|
||||||
};
|
};
|
||||||
sshKey = lib.mkOption {
|
port = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.port;
|
||||||
description = "Path to SSH private key for the builder.";
|
default = 2424;
|
||||||
|
description = "SSH port — added via ~root/.ssh/config since nix.buildMachines has no sshPort option.";
|
||||||
};
|
};
|
||||||
systems = lib.mkOption {
|
systems = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ "aarch64-linux" ];
|
default = [ "aarch64-linux" "x86_64-linux" ];
|
||||||
description = "System types the remote builder can build for.";
|
description = "System types the remote builder can build for.";
|
||||||
};
|
};
|
||||||
maxJobs = lib.mkOption {
|
maxJobs = lib.mkOption {
|
||||||
type = lib.types.int;
|
type = lib.types.int;
|
||||||
default = 4;
|
default = 16;
|
||||||
description = "Max parallel jobs on the remote builder.";
|
description = "Max parallel jobs on the remote builder.";
|
||||||
};
|
};
|
||||||
supportedFeatures = lib.mkOption {
|
supportedFeatures = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ "benchmark" "big-parallel" "nixos-test" ];
|
default = [ "big-parallel" "nixos-test" "benchmark" ];
|
||||||
description = "Features the remote builder supports.";
|
description = "Features the remote builder supports.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
|
||||||
default = [];
|
fallbackLocal = lib.mkOption {
|
||||||
description = "List of remote Nix build machines.";
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Fall back to local build when remote builder is unreachable.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
nix.distributedBuilds = true;
|
nix.distributedBuilds = true;
|
||||||
nix.buildMachines = map (m: {
|
nix.buildMachines = [{
|
||||||
hostName = m.hostName;
|
hostName = cfg.buildMachine.host;
|
||||||
sshUser = m.sshUser;
|
sshUser = cfg.buildMachine.sshUser;
|
||||||
sshKey = m.sshKey;
|
systems = cfg.buildMachine.systems;
|
||||||
systems = m.systems;
|
maxJobs = cfg.buildMachine.maxJobs;
|
||||||
maxJobs = m.maxJobs;
|
supportedFeatures = cfg.buildMachine.supportedFeatures;
|
||||||
supportedFeatures = m.supportedFeatures;
|
}];
|
||||||
}) cfg.machines;
|
|
||||||
|
|
||||||
# SSH config for port + key (nix.buildMachines has no port option)
|
nix.extraOptions = lib.optionalString cfg.fallbackLocal ''
|
||||||
programs.ssh.extraConfig = lib.concatStringsSep "\n" (map (m: ''
|
builders-use-substitutes = true
|
||||||
Host ${m.hostName}
|
fallback = true
|
||||||
HostName ${m.hostName}
|
'';
|
||||||
Port ${toString m.port}
|
|
||||||
User ${m.sshUser}
|
# SSH config for the remote builder (since nix.buildMachines has no port option)
|
||||||
IdentityFile ${m.sshKey}
|
programs.ssh.extraConfig = ''
|
||||||
StrictHostKeyChecking no
|
Host ${cfg.buildMachine.host}
|
||||||
UserKnownHostsFile /dev/null
|
HostName ${cfg.buildMachine.host}
|
||||||
'') cfg.machines);
|
Port ${toString cfg.buildMachine.port}
|
||||||
|
User ${cfg.buildMachine.sshUser}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
11
secrets/openclaw_gateway_token.age
Normal file
11
secrets/openclaw_gateway_token.age
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IEdoTUQ4QSBCWEpO
|
||||||
|
cG9yNnFpcHFqTkNzTngxU1MxN0NYK0hrZFhUTjVORWFrK3JNd2tZCmtMTGpwQk1E
|
||||||
|
WlUwL3N6SGRWblpnNEkrWkkyU2hQMkRIK0M3R0pOVEREV3MKLT4gY2osLWdyZWFz
|
||||||
|
ZSBacSozVVQgUCAxRS1OQSAuKXxDPCoKbStWNW1BZjBZQzNDaTlDbU5EZkxsRWxM
|
||||||
|
cXJ3dDU1RDNpOXRlV0tzdEp2NUo3S1lhRG5Md0RHTGlJdkFSYmt5YQo4R1hiQWRG
|
||||||
|
V2VxekJKZwotLS0geG1XSi9VbkhXZHQzcEFVS3hKNzVueXFLa2xnZTc3Q2tJTVZ5
|
||||||
|
eXJabWk5Ywp6bJCP3s0xxzjE+eTR+cv7ZUnkoliT/n7uIprq1BTn/LIRLkUTUqs3
|
||||||
|
NiDwrXcoq4/QKd0Dt+8ap3vFAuusjGxRlnYMaRrZie2AGtTV8U7Q7durm9o2K+/4
|
||||||
|
QzRQ/MtumIQm
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
@@ -12,7 +12,5 @@ in
|
|||||||
"home_wifi.age".publicKeys = authorizedKeys;
|
"home_wifi.age".publicKeys = authorizedKeys;
|
||||||
"lazyworkhorse_host_ssh_key.age".publicKeys = authorizedKeys;
|
"lazyworkhorse_host_ssh_key.age".publicKeys = authorizedKeys;
|
||||||
"n8n_ssh_key.age".publicKeys = authorizedKeys;
|
"n8n_ssh_key.age".publicKeys = authorizedKeys;
|
||||||
"builder_key.age".publicKeys = authorizedKeys ++ [
|
"openclaw_gateway_token.age".publicKeys = authorizedKeys;
|
||||||
keys.hosts.uConsole.bootstrap
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
{ config, lib, pkgs, keys, ... }: {
|
|
||||||
users.users.builder = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = "builder";
|
|
||||||
home = "/var/empty";
|
|
||||||
createHome = false;
|
|
||||||
shell = "${pkgs.shadow}/bin/nologin";
|
|
||||||
openssh.authorizedKeys.keys = with keys; [
|
|
||||||
users.builder.main
|
|
||||||
];
|
|
||||||
};
|
|
||||||
users.groups.builder = {};
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
{ pkgs, inputs, config, keys, ... }: {
|
{ pkgs, inputs, config, keys, ... }: {
|
||||||
home-manager.extraSpecialArgs = {
|
home-manager.extraSpecialArgs = { inherit (config.networking) hostName; dotfiles = inputs.dotfiles.outPath # flake input (not submodule); };
|
||||||
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;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
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";
|
||||||
@@ -34,9 +33,6 @@ 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
|
||||||
@@ -47,45 +43,22 @@ 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/hosts/monitors.conf".source =
|
".config/hypr/host/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
|
||||||
htop unzip wget jq
|
] ++ lib.optionals (!isUconsole) [
|
||||||
hyprland hyprlock hypridle hyprpaper
|
waybar wofi swww hyprshot
|
||||||
waybar wofi dunst
|
] ++ lib.optionals isUconsole [
|
||||||
libnotify mako
|
brightnessctl
|
||||||
swaynotificationcenter
|
|
||||||
swww
|
|
||||||
emacs
|
|
||||||
udiskie
|
|
||||||
hyprshade
|
|
||||||
networkmanagerapplet
|
|
||||||
pavucontrol
|
|
||||||
];
|
];
|
||||||
|
|
||||||
xdg.userDirs = {
|
programs.zsh.enable = true;
|
||||||
enable = true;
|
programs.starship.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";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user