dotfiles/nixos/hosts/trailblazer/default.nix
Kate Temkin 9193d6e469 flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/ae62fd8ad8347e6bb5b615057f39f33d595a1c47' (2025-07-12)
  → 'github:nix-community/home-manager/710771af3d1c8c3f86a9e5d562616973ed5f3f21' (2025-07-27)
• Updated input 'lix':
    'git+https://git@git.lix.systems/lix-project/lix?ref=refs/heads/main&rev=ae00b1298353a43a10bbecea8220471731db10ec' (2025-07-12)
  → 'git+https://git@git.lix.systems/lix-project/lix?ref=refs/heads/main&rev=ef94901156c0c688ffffaa2c5caf1498119f01d4' (2025-07-26)
• Updated input 'nil':
    'github:oxalica/nil/b043bfe1f3f4c4be4b688e24c5ae96e81f525805' (2025-07-01)
  → 'github:oxalica/nil/524ae2d67dd84d99a10f409ed6cd8e4e7b3cae3f' (2025-07-18)
• Updated input 'niri':
    'github:sodiboo/niri-flake/b658155b3c10d32c62fad3bde0097b87b47d2d08' (2025-07-12)
  → 'github:sodiboo/niri-flake/af1af659e690b3e535d94c54a64700767bfc9544' (2025-07-26)
• Updated input 'niri/niri-unstable':
    'github:YaLTeR/niri/37458d94b288945f6cfbd3c5c233f634d59f246c' (2025-06-24)
  → 'github:YaLTeR/niri/fefc0bc0a71556eb75352e2b611e50eb5d3bf9c2' (2025-07-18)
• Updated input 'niri/nixpkgs':
    'github:NixOS/nixpkgs/9807714d6944a957c2e036f84b0ff8caf9930bc0' (2025-07-08)
  → 'github:NixOS/nixpkgs/7fd36ee82c0275fb545775cc5e4d30542899511d' (2025-07-25)
• Updated input 'niri/nixpkgs-stable':
    'github:NixOS/nixpkgs/10e687235226880ed5e9f33f1ffa71fe60f2638a' (2025-07-10)
  → 'github:NixOS/nixpkgs/3ff0e34b1383648053bba8ed03f201d3466f90c9' (2025-07-24)
• Updated input 'nix-hardware':
    'github:nixos/nixos-hardware/7ced9122cff2163c6a0212b8d1ec8c33a1660806' (2025-07-09)
  → 'github:nixos/nixos-hardware/cc66fddc6cb04ab479a1bb062f4d4da27c936a22' (2025-07-21)
• Updated input 'nixos-hardware':
    'github:NixOS/nixos-hardware/7ced9122cff2163c6a0212b8d1ec8c33a1660806' (2025-07-09)
  → 'github:NixOS/nixos-hardware/cc66fddc6cb04ab479a1bb062f4d4da27c936a22' (2025-07-21)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/9807714d6944a957c2e036f84b0ff8caf9930bc0' (2025-07-08)
  → 'github:NixOS/nixpkgs/7fd36ee82c0275fb545775cc5e4d30542899511d' (2025-07-25)
• Updated input 'stylix':
    'github:danth/stylix/0da583a359fd911d5cbfd2c789424b888b777a4b' (2025-07-11)
  → 'github:danth/stylix/af85565aba0f4749cb18b118a7333a0745920950' (2025-07-26)
• Updated input 'stylix/base16-helix':
    'github:tinted-theming/base16-helix/6c711ab1a9db6f51e2f6887cc3345530b33e152e' (2025-05-28)
  → 'github:tinted-theming/base16-helix/27cf1e66e50abc622fb76a3019012dc07c678fac' (2025-07-20)
• Updated input 'waveforms/nixpkgs':
    'path:/nix/store/cd7fkv2r1nflz758r8bsnqfvkq7f72wj-source?lastModified=1751637120&narHash=sha256-xVNy/XopSfIG9c46nRmPaKfH1Gn/56vQ8%2B%2BxWA8itO4%3D&rev=5c724ed1388e53cc231ed98330a60eb2f7be4be3' (2025-07-04)
  → 'path:/nix/store/bgl6ldj5ihbwcq8p42z3a0qzgqafgk2b-source?lastModified=1751984180&narHash=sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X%2BxgOL0%3D&rev=9807714d6944a957c2e036f84b0ff8caf9930bc0' (2025-07-08)
2025-07-27 14:36:54 +02:00

434 lines
13 KiB
Nix

#
# Per-system configuration for Trailblazer.
#
# vim: et:ts=2:sw=2:
#
{
config,
lib,
pkgs,
modulesPath,
deprekages,
...
}:
let
ledOffScript = pkgs.writeScriptBin "ledsoff" ''
#!${pkgs.bash}/bin/bash
openrgb -d 0 -m off -b 0
openrgb -d 1 -m off -b 0
openrgb -d 2 -m off -b 0
openrgb -d 3 -m off -b 0
openrgb -d 4 -m off -b 0
openrgb -d "Corsair Lighting Node Pro" -m direct -z 0 -s 100 -b 0 -c black
openrgb -d "Corsair Lighting Node Pro" -m direct -z 1 -s 100 -b 0 -c black
'';
ledOnScript = pkgs.writeScriptBin "ledson" ''
#!${pkgs.bash}/bin/bash
openrgb -d 0 -m direct -c $1 -b 100
openrgb -d 1 -m direct -c $1 -b 100
openrgb -d 2 -m direct -c $1 -b 100
openrgb -d 3 -m direct -c $1 -b 100
openrgb -d 4 -m direct -c $1 -b 100
openrgb -d "Corsair Lighting Node Pro" -m direct -z 0 -s 100 -b 100 -c $1
openrgb -d "Corsair Lighting Node Pro" -m direct -z 1 -s 100 -b 100 -c $1
'';
mqttServer = "192.168.50.124";
commandScript = pkgs.writeScriptBin "trailblazer-command-daemon" ''
#!${pkgs.xonsh}/bin/xonsh
print("[I] Trailblazer command service started. Waiting for command.")
print("----------------------------")
for verb in !(${pkgs.mosquitto}/bin/mosquitto_sub -h ${mqttServer} -t trailblazer/command):
verb = verb.strip()
if verb == "lights/off":
print("[I] Got a 'lights out' request. Making things quiet.")
# Turn off monitors for any X11 anything.
for auth in g`/tmp/xauth_*`:
print(f"[I] Turning off monitors on X instance with auth file {auth}.")
!(env DISPLAY=:0 XAUTHORITY=@(auth) xset dpms force off)
# Turn off monitors on each niri session,
sockets = g`/var/run/user/1000/niri*.sock`
for socket in sockets:
print(f"[I] Turning off monitors on niri instance {socket}.")
!(env NIRI_SOCKET=@(socket) niri msg action power-off-monitors)
print("[I] Turning off RGB leds.")
!(${ledOffScript}/bin/ledsoff)
print("[I] Everything should be... well, not-shiny, captain!")
elif verb == "power/suspend":
print("[I] Got a 'sleep' request. Dozing.")
${pkgs.mosquitto}/bin/mosquitto_pub -h ${mqttServer} -t trailblazer/power/status -m sleep
systemctl suspend
elif verb == "power/off":
print("[I] Got a 'power off' request. Will I dream?")
${pkgs.mosquitto}/bin/mosquitto_pub -h ${mqttServer} -t trailblazer/power/status -m off
systemctl suspend
elif verb == "monitors/off":
print("[I] Got a 'monitors off' request. Adding DPMS nulls.")
# Turn off monitors for any X11 anything.
for auth in g`/tmp/xauth_*`:
print(f"[I] Turning off monitors on X instance with auth file {auth}.")
!(env DISPLAY=:0 XAUTHORITY=@(auth) xset dpms force off)
# Turn off monitors on each niri session,
sockets = g`/var/run/user/1000/niri*.sock`
for socket in sockets:
print(f"[I] Turning off monitors on niri instance {socket}.")
!(env NIRI_SOCKET=@(socket) niri msg action power-off-monitors)
elif verb == "monitors/on":
print("[I] Got a 'monitors on' request. Removing DPMS nulls.")
# Turn off monitors for any X11 anything.
for auth in g`/tmp/xauth_*`:
print(f"[I] Turning on monitors on X instance with auth file {auth}.")
!(env DISPLAY=:0 XAUTHORITY=@(auth) xset dpms force on)
# Turn off monitors on each niri session,
sockets = g`/var/run/user/1000/niri*.sock`
for socket in sockets:
print(f"[I] Turning on monitors on niri instance {socket}.")
!(env NIRI_SOCKET=@(socket) niri msg action power-on-monitors)
elif verb == "lights/ledsoff":
print("[I] Turning off RGB leds.")
!(${ledOffScript}/bin/ledsoff)
elif verb == "lights/o":
print("[I] Setting lights to 'sight colors.")
!(${ledOnScript}/bin/ledson white)
elif verb == "lights/t":
print("[I] Setting lights to tsu colors.")
!(${ledOnScript}/bin/ledson blue)
elif verb == "lights/k":
print("[I] Setting lights to Kaye colors.")
!(${ledOnScript}/bin/ledson purple)
elif verb == "lights/w":
print("[I] Setting lights to Whim colors.")
!(${ledOnScript}/bin/ledson green)
elif verb == "lights/s":
print("[I] Setting lights to Scar colors.")
!(${ledOnScript}/bin/ledson red)
elif verb == "lights/e":
print("[I] Setting lights to Echo colors.")
!(${ledOnScript}/bin/ledson gray)
elif verb == "suspend":
print("[I] Going to sleep, as requested.")
!(systemctl suspend)
else:
print(f"[W] ignoring unknown verb '{verb}'")
print("----------------------------")
'';
statusScript = pkgs.writeScriptBin "trailblazer-status-daemon" ''
#!${pkgs.xonsh}/bin/xonsh
print("[I] Trailblazer status service started. Updating every 10s.")
while True:
sleep 10
${pkgs.mosquitto}/bin/mosquitto_pub -h ${mqttServer} -t trailblazer/monitors/status -m $(cat /sys/class/drm/card1-HDMI-A-1/dpms)
${pkgs.mosquitto}/bin/mosquitto_pub -h ${mqttServer} -t trailblazer/power/status -m on
'';
in
{
system.stateVersion = "23.11";
imports = [
#./ups.nix
./energy.nix
./scanner.nix
(modulesPath + "/installer/scan/not-detected.nix")
../../configs/build-machine-users.nix
];
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Networking.
networking.hostName = "trailblazer";
networking.networkmanager.enable = true;
networking.firewall.enable = false;
# This is a local machine, rather than our typical network-accesed ones.
# Run an ssh-agent locally.
programs.ssh.startAgent = true;
# Let fuse run as our user and still mount with proper perms.
programs.fuse.userAllowOther = true;
# Optimize our system for virtualisation.
#boot.kernelPackages = pkgs.linuxPackages_zen;
# Disallow nouveau so the NVIDIA device is available for VFIO.
boot.blacklistedKernelModules = [ "nouveau" ];
# Allow IOMMU members to be sorted into their own groups for passthrough.
boot.kernelParams = [
"iommu=on"
"amd_iommu=on"
"xhci_hcd.quirks=270336" # fix random wakeups, maybe?
];
# Enable fingerprint reader.
services.fprintd.enable = true;
# Enable steam.
programs.gamescope = {
enable = true;
capSysNice = true;
};
programs.steam = {
enable = true;
gamescopeSession.enable = true;
};
#
# Niri configuration for our monitors.
#
home-manager.users.deprekated = {
programs.niri.settings = {
# Bottom monitor.
outputs."LG Electronics LG ULTRAFINE 408NTYT4A658" = {
position = {
x = 1440;
y = 0;
};
scale = 1.5;
};
# Top monitor.
outputs."LG Electronics LG ULTRAFINE 408NTEP4A260" = {
position = {
x = 1440;
y = 1440;
};
scale = 1.5;
};
# Side monitor.
outputs."LG Electronics LG ULTRAFINE 503NTEP2F044" = {
position = {
x = 0;
y = 0;
};
scale = 1.5;
transform.rotation = 270;
};
# Front panel display.
outputs."Shenzhen Soogeen Electronics Co., LTD. L01N8A 0x01348C5C" = {
scale = 1.0;
transform.rotation = 90;
};
};
# Also position waybar on only one monitor.
programs.waybar.settings.mainBar.output = "DP-1";
};
# Override stylix font sizes.
stylix.fonts.sizes.desktop = lib.mkForce 16;
# Use kwin for sddm instead of westin, to account for multi-monitor.
services.displayManager.sddm.wayland.compositor = "kwin";
# Use OpenRGB so we can silence our LEDs when appropriate.
services.hardware.openrgb = {
enable = true;
package = pkgs.openrgb-with-all-plugins;
motherboard = "amd";
};
# Provide docker for remote tasks.
virtualisation.docker.enable = true;
users.users.deprekated.extraGroups = [ "docker" ];
# Fix XHCI suprious wakeups.
#
# Trailblazer remote service (allows trailblazer things to be controlled via Home Assistant.
#
systemd.services.trailblazer-commands = {
description = "trailblazer command service";
# Start once we're online.
wantedBy = [ "default.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
script = "${commandScript}/bin/trailblazer-command-daemon";
serviceConfig.Restart = "always";
};
systemd.services.trailblazer-status = {
description = "trailblazer status service";
# Start once we're online.
wantedBy = [ "default.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
script = "${statusScript}/bin/trailblazer-status-daemon";
serviceConfig.Restart = "always";
};
systemd.services.suspend_notify = {
description = "trailblazer sleep notifier";
# Start once we're online.
wantedBy = [ "suspend.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
before = [ "suspend.target" ];
script = "${pkgs.mosquitto}/bin/mosquitto_pub -h ${mqttServer} -t trailblazer/power/status -m sleep";
};
systemd.services.resume_notify = {
description = "trailblazer wake notifier";
# Start once we're online.
wantedBy = [ "suspend.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" "suspend.target" ];
script = "${pkgs.mosquitto}/bin/mosquitto_pub -h ${mqttServer} -t trailblazer/power/status -m on";
};
systemd.services.poweroff_notify = {
description = "trailblazer shutdown notifier";
# Start once we're online.
wantedBy = [ "shutdown.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
before = [ "shutdown.target" ];
script = "${pkgs.mosquitto}/bin/mosquitto_pub -h ${mqttServer} -t trailblazer/power/status -m shutdown";
};
systemd.services.poweron_notify = {
description = "trailblazer wake notifier";
# Start once we're online.
wantedBy = [ "suspend.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
script = "${pkgs.mosquitto}/bin/mosquitto_pub -h ${mqttServer} -t trailblazer/power/status -m on";
};
#
# Let trailblazer share its GPS with the house devices.
#
systemd.services.gps-share = {
description = "share our GPS with our other devices on the LAN";
# Start once we're online.
wantedBy = [ "default.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
script = "${deprekages.gps-share}/bin/gps-share /dev/ttyACM0";
};
#
# Hardware config.
#
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"ahci"
"usbhid"
"usb_storage"
"sd_mod"
"dm-raid"
];
boot.initrd.kernelModules = [ ];
boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
boot.kernelModules = [
"kvm-amd"
"v4l2loopback"
];
fileSystems."/" = {
device = "/dev/disk/by-label/nix";
fsType = "xfs";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/boot";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
];
};
fileSystems."/home" = {
device = "/dev/disk/by-label/home";
fsType = "xfs";
};
swapDevices = [ ];
# Support bluetooth.
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
# Support A2DP.
Enable = "Source,Sink,Media,Socket";
# Enable experimental featurees, like reading device battery levels.
Experimental = true;
};
};
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp26s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp25s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
boot.swraid.enable = true;
boot.swraid.mdadmConf = ''
MAILADDR kate@deprekated.net
ARRAY /dev/md/nixos:0 level=raid0 num-devices=2 metadata=1.2 UUID=325ee7dc:7fcc6062:635e902f:af2552dc
devices=/dev/nvme0n1p1,/dev/nvme1n1p1
'';
}