Files
nixos/modules/desktop-common.nix
Simon Gardling d00ff42e8e site-config: dedupe cross-host values, fix stale dark-reader urls, drop desktop 1g hugepages
new site-config.nix holds values previously duplicated across hosts:
  domain, old_domain, contact_email, timezone, binary_cache (url + pubkey),
  dns_servers, lan (cidr + gateway), hosts.{muffin,yarn} (ip/alias/ssh_host_key),
  ssh_keys.{laptop,desktop,ci_deploy}.

threaded through specialArgs on all three hosts + home-manager extraSpecialArgs +
homeConfigurations.primary + serverLib. service-configs.nix now takes
{ site_config } as a function arg and drops its https namespace; per-service
domains (gitea/matrix/ntfy/mollysocket/livekit/firefox-sync/grafana) are
derived from site_config.domain. ~15 service files and 6 vm tests migrated.

breakage fixes rolled in:
 - home/progs/zen/dark-reader.nix: 5 stale *.gardling.com entries in
   disabledFor rewritten to *.sigkill.computer (caddy 301s the old names so
   these never fired and the new sigkill urls were getting dark-reader applied)
 - modules/desktop-common.nix: drop unused hugepagesz=1G/hugepages=3
   kernelParams (no consumer on mreow or yarn; xmrig on muffin still reserves
   its own via services/monero/xmrig.nix)

verification: muffin toplevel is bit-identical to pre-refactor baseline.
mreow/yarn toplevels differ only in boot.json kernelParams + darkreader
storage.js (nix-diff verified). deployGuardTest and fail2banVaultwardenTest
(latter exercises site_config.domain via bitwarden.nix) pass.
2026-04-22 20:48:29 -04:00

467 lines
13 KiB
Nix

{
config,
options,
pkgs,
lib,
username,
inputs,
site_config,
niri-package,
...
}:
{
imports = [
./common.nix
# desktop-only modules
./desktop-vm.nix
./desktop-steam.nix
./desktop-networkmanager.nix
inputs.disko.nixosModules.disko
inputs.lanzaboote.nixosModules.lanzaboote
inputs.nixos-hardware.nixosModules.common-cpu-amd-pstate
inputs.nixos-hardware.nixosModules.common-cpu-amd-zenpower
inputs.nixos-hardware.nixosModules.common-pc-ssd
];
# allow overclocking (I actually underclock but lol)
hardware.amdgpu.overdrive.ppfeaturemask = "0xFFFFFFFF";
# Add niri to display manager session packages
services.displayManager.sessionPackages = [ niri-package ];
programs = {
gamescope = {
enable = true;
capSysNice = true;
};
steam = {
enable = true;
gamescopeSession.enable = true;
};
};
system.activationScripts = {
# FIX: https://github.com/NixOS/nix/issues/2982
"profile-channel-dummy".text = ''
#!/bin/sh
mkdir -p /nix/var/nix/profiles/per-user/root/channels
'';
# extract all my secureboot keys
# TODO! proper secrets management
"secureboot-keys".text = ''
#!/usr/bin/env sh
rm -fr ${config.boot.lanzaboote.pkiBundle} || true
mkdir -p ${config.boot.lanzaboote.pkiBundle}
${lib.getExe pkgs.gnutar} xf ${../secrets/desktop/secureboot.tar} -C ${config.boot.lanzaboote.pkiBundle}
chown -R root:wheel ${config.boot.lanzaboote.pkiBundle}
chmod -R 500 ${config.boot.lanzaboote.pkiBundle}
'';
};
swapDevices = [ ];
# Desktop-specific Nix cache — muffin serves it, desktops consume.
# Base nix settings (optimise, gc, experimental-features) come from common.nix.
nix.settings = {
substituters = [ site_config.binary_cache.url ];
trusted-public-keys = [
site_config.binary_cache.public_key
];
netrc-file = "${../secrets/desktop/nix-cache-netrc}";
};
# cachyos kernel overlay
nixpkgs.overlays = [ inputs.nix-cachyos-kernel.overlays.default ];
# kernel options
boot = {
# cachyos kernel: bore scheduler, full lto, x86_64-v3 (common to zen 3 + zen 5)
kernelPackages =
let
helpers = pkgs.callPackage "${inputs.nix-cachyos-kernel}/helpers.nix" { };
kernel = pkgs.cachyosKernels.linux-cachyos-bore-lto.override {
lto = "full";
processorOpt = "x86_64-v3";
};
in
helpers.kernelModuleLLVMOverride (pkgs.linuxKernel.packagesFor kernel);
# disable legacy subsystems neither host will ever use
kernelPatches = [
{
name = "disable-legacy-subsystems";
patch = null;
structuredExtraConfig = with lib.kernel; {
# ancient bus/card standards
PCMCIA = lib.mkForce no;
PCCARD = lib.mkForce no;
PARPORT = lib.mkForce no;
GAMEPORT = lib.mkForce module;
FIREWIRE = lib.mkForce no;
AGP = lib.mkForce no;
# legacy networking
ATM = lib.mkForce no;
FDDI = lib.mkForce no;
ISDN = lib.mkForce no;
CAN = lib.mkForce no;
NFC = lib.mkForce no;
INFINIBAND = lib.mkForce no;
# amateur radio (HAMRADIO is the umbrella but these are separate symbols)
HAMRADIO = lib.mkForce no;
AX25 = lib.mkForce no;
NETROM = lib.mkForce no;
ROSE = lib.mkForce no;
# dead protocols
PHONET = lib.mkForce no;
IEEE802154 = lib.mkForce no;
"6LOWPAN" = lib.mkForce no;
NET_9P = lib.mkForce no;
BATMAN_ADV = lib.mkForce no;
CAIF = lib.mkForce no;
# tv tuners / digital video broadcasting
MEDIA_ANALOG_TV_SUPPORT = lib.mkForce no;
MEDIA_DIGITAL_TV_SUPPORT = lib.mkForce no;
DVB_CORE = lib.mkForce no;
# hypervisor guest support (bare metal only)
HYPERV = lib.mkForce no;
XEN = lib.mkForce no;
VMWARE_VMCI = lib.mkForce no;
VMWARE_BALLOON = lib.mkForce no;
VMWARE_PVSCSI = lib.mkForce no;
VMWARE_VMCI_VSOCKETS = lib.mkForce no;
VMXNET3 = lib.mkForce no;
DRM_VMWGFX = lib.mkForce no;
VBOXGUEST = lib.mkForce no;
VBOXSF_FS = lib.mkForce no;
# staging drivers (experimental/unmaintained)
STAGING = lib.mkForce no;
# SND_PCI stays — SND_HDA_INTEL (AMD HDA audio) lives under it
ACCESSIBILITY = lib.mkForce no;
MTD = lib.mkForce no;
MEDIA_RC_SUPPORT = lib.mkForce no;
# legacy storage (AHCI for modern SATA is independent)
ATA_SFF = lib.mkForce no;
SCSI_LOWLEVEL = lib.mkForce no;
FUSION = lib.mkForce no;
# misc legacy
MOST = lib.mkForce no;
PPDEV = lib.mkForce no;
PHANTOM = lib.mkForce no;
X86_ANDROID_TABLETS = lib.mkForce no;
# CHROME_PLATFORMS stays — Framework laptops use CrOS EC
SURFACE_PLATFORMS = lib.mkForce no;
MCTP = lib.mkForce no;
GPIB = lib.mkForce no;
SIOX = lib.mkForce no;
SLIMBUS = lib.mkForce no;
WWAN = lib.mkForce no;
QFMT_V1 = lib.mkForce no;
FIREWIRE_NOSY = lib.mkForce no;
# nvidia gpu
DRM_NOUVEAU = lib.mkForce no;
# other gpus not present
DRM_RADEON = lib.mkForce no;
DRM_GMA500 = lib.mkForce no;
DRM_AST = lib.mkForce no;
DRM_MGAG200 = lib.mkForce no;
DRM_HISI_HIBMC = lib.mkForce no;
DRM_APPLETBDRM = lib.mkForce no;
# intel gpu
DRM_I915 = lib.mkForce no;
DRM_XE = lib.mkForce no;
# early-boot framebuffer chain: drop every alternative to amdgpu so
# the console never transitions simpledrm -> dummy -> amdgpu (visible
# as a flash + scrolled dmesg). amdgpu owns the display from initrd
# onward; pre-amdgpu kernel output stays in the printk ring buffer.
DRM_SIMPLEDRM = lib.mkForce no;
FB_EFI = lib.mkForce no;
FB_VESA = lib.mkForce no;
# intel cpu / platform
INTEL_IOMMU = lib.mkForce no;
INTEL_IDLE = lib.mkForce no;
INTEL_HFI_THERMAL = lib.mkForce no;
INTEL_TCC_COOLING = lib.mkForce no;
INTEL_SOC_DTS_THERMAL = lib.mkForce no;
INTEL_PCH_THERMAL = lib.mkForce no;
INTEL_POWERCLAMP = lib.mkForce no;
X86_PKG_TEMP_THERMAL = lib.mkForce no;
X86_INTEL_LPSS = lib.mkForce no;
INTEL_MEI = lib.mkForce no;
INTEL_TH = lib.mkForce no;
INTEL_VSEC = lib.mkForce no;
INTEL_IDXD = lib.mkForce no;
INTEL_IOATDMA = lib.mkForce no;
EDAC_E752X = lib.mkForce no;
EDAC_I82975X = lib.mkForce no;
EDAC_I3000 = lib.mkForce no;
EDAC_I3200 = lib.mkForce no;
EDAC_IE31200 = lib.mkForce no;
EDAC_X38 = lib.mkForce no;
EDAC_I5400 = lib.mkForce no;
EDAC_I7CORE = lib.mkForce no;
EDAC_I5100 = lib.mkForce no;
EDAC_I7300 = lib.mkForce no;
EDAC_SBRIDGE = lib.mkForce no;
EDAC_SKX = lib.mkForce no;
EDAC_I10NM = lib.mkForce no;
EDAC_IMH = lib.mkForce no;
EDAC_PND2 = lib.mkForce no;
EDAC_IGEN6 = lib.mkForce no;
# intel audio
SND_SOC_SOF_INTEL_TOPLEVEL = lib.mkForce no;
SND_SOC_INTEL_SST_TOPLEVEL = lib.mkForce no;
# mellanox networking
MLX4_CORE = lib.mkForce no;
MLX5_CORE = lib.mkForce no;
MLXSW_CORE = lib.mkForce no;
MLX_PLATFORM = lib.mkForce no;
# fpga
FPGA = lib.mkForce no;
XILLYBUS = lib.mkForce no;
XILLYUSB = lib.mkForce no;
# old x86 cpufreq / platform (both systems are modern Zen)
AMD_NUMA = lib.mkForce no;
X86_POWERNOW_K8 = lib.mkForce no;
X86_P4_CLOCKMOD = lib.mkForce no;
X86_SPEEDSTEP_LIB = lib.mkForce no;
# cxl (datacenter memory expansion)
CXL_BUS = lib.mkForce no;
# embedded SoC peripherals (not present on desktop/laptop)
INPUT_TOUCHSCREEN = lib.mkForce no;
INPUT_TABLET = lib.mkForce no;
INPUT_JOYSTICK = lib.mkForce no;
MEDIA_PLATFORM_DRIVERS = lib.mkForce no;
MEDIA_TEST_SUPPORT = lib.mkForce no;
# deprecated userland compat
SGETMASK_SYSCALL = lib.mkForce no;
UID16 = lib.mkForce no;
X86_X32_ABI = lib.mkForce no;
# Disable EXT2
EXT2_FS = lib.mkForce no;
EXT4_USE_FOR_EXT2 = lib.mkForce yes;
# disable unused security stuff
SECURITY_TOMOYO = lib.mkForce no;
SECURITY_YAMA = lib.mkForce no;
SECURITY_SELINUX = lib.mkForce no;
SECURITY_APPARMOR = lib.mkForce no;
INTEGRITY = lib.mkForce no;
SECURITY_IPE = lib.mkForce no;
SECURITY_LANDLOCK = lib.mkForce no;
SECURITY_SMACK = lib.mkForce no;
# I am not a switch
NET_SWITCHDEV = lib.mkForce no;
# incorrect ARCH
XZ_DEC_POWERPC = lib.mkForce no;
XZ_DEC_ARM = lib.mkForce no;
XZ_DEC_ARMTHUMB = lib.mkForce no;
XZ_DEC_ARM64 = lib.mkForce no;
XZ_DEC_SPARC = lib.mkForce no;
XZ_DEC_RISCV = lib.mkForce no;
};
}
];
# aes_generic is built-in as of linux 7.0, no longer a loadable module
initrd.luks.cryptoModules = lib.mkForce (
lib.filter (m: m != "aes_generic") options.boot.initrd.luks.cryptoModules.default
);
# some default initrd modules (ata_piix etc) don't exist with ATA_SFF=n
initrd.allowMissingModules = true;
lanzaboote = {
enable = true;
# TODO: proper secrets management so this is not stored in nix store
pkiBundle = "/var/lib/sbctl";
};
# Bootloader.
loader = {
efi.canTouchEfiVariables = true;
timeout = 1;
/*
Lanzaboote currently replaces the systemd-boot module.
This setting is usually set to true in configuration.nix
generated at installation time. So we force it to false
for now.
*/
systemd-boot.enable = lib.mkForce false;
systemd-boot.configurationLimit = 10;
};
initrd = {
systemd.enable = true;
compressor = "zstd";
kernelModules = [ "amdgpu" ]; # own the display from initrd, no fbcon handoff
availableKernelModules = [
"xhci_pci"
"thunderbolt"
"nvme"
"usbhid"
];
};
kernelModules = [
"kvm-amd"
"ip_tables"
"iptable_nat"
"msr"
"btusb"
];
};
services = {
# auto detect network printers
avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
# Enable CUPS to print documents.
printing = {
enable = true;
drivers = with pkgs; [ hplip ];
};
# I don't want fingerprint login
fprintd.enable = false;
# Making sure mullvad works on boot
mullvad-vpn.enable = true;
# power statistics
upower.enable = true;
# power profiles for noctalia shell
power-profiles-daemon.enable = true;
# geolocation (uses beacondb.net by default)
geoclue2 = {
enable = true;
appConfig.zen-twilight = {
isAllowed = true;
isSystem = false;
};
};
};
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
# Enable Bluetooth
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
# Enable experimental features for battery % of bluetooth devices
settings.General.Experimental = true;
};
# Apply gtk themes by enabling dconf
programs.dconf.enable = true;
# Enable sound with pipewire.
services.pulseaudio.enable = false; # pipewire >>>>>>> pulseaudio
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
# Define my user account (the rest of the configuration if found in `~/.config/home-manager/...`)
users.users.${username} = {
isNormalUser = true;
extraGroups = [
"networkmanager"
"wheel"
"video"
"camera"
"adbusers"
];
# TODO! this is really bad :( I should really figure out how to do proper secrets management
hashedPasswordFile = "${../secrets/desktop/password-hash}";
};
services.gvfs.enable = true;
programs.gphoto2.enable = true;
# Enable thermal data
services.thermald.enable = true;
services.pcscd.enable = true;
programs.gnupg.agent = {
enable = true;
pinentryPackage = pkgs.pinentry-curses;
enableSSHSupport = false;
};
# System packages
environment.systemPackages = with pkgs; [
# mullvad-vpn is provided by services.mullvad-vpn.enable
#secureboot ctl
sbctl
dmidecode
glib
usbutils
libmtp
man-pages
man-pages-posix
# needed for home-manager
git
tmux
android-tools
];
# wayland with electron/chromium applications
environment.sessionVariables.NIXOS_OZONE_WL = "1";
# port 53317 for localsend
networking.firewall.allowedUDPPorts = [ 53317 ];
networking.firewall.allowedTCPPorts = [ 53317 ];
system.stateVersion = "25.05";
nixpkgs.hostPlatform = "x86_64-linux";
documentation.enable = true;
documentation.man.enable = true;
documentation.dev.enable = true;
}