{ config, pkgs, lib, ... }: { # Stop nouveau from binding the NVIDIA GPU boot.blacklistedKernelModules = [ "nouveau" ]; boot.kernelParams = [ "nvidia.NVreg_PreserveVideoMemoryAllocations=1" "intel_iommu=off" "dev_mem_signed_off=1" "modprobe.blacklist=nouveau" "nouveau.modeset=0" ]; boot.extraModprobeConfig = '' options nvidia_modeset vblank_sem_control=0 ''; imports = [ ./hardware-configuration.nix ]; home-manager.backupFileExtension = "hm-bak"; # --- # Nix (enable flakes on the installed system) # --- nix.settings.experimental-features = [ "nix-command" "flakes" ]; # --- # Bootloader / kernel # --- boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; # Known-good baseline from niri-4screen.md # --- # Identity # --- networking.hostName = "sam-4screen-desktop"; time.timeZone = "Australia/Sydney"; # --- # Networking # --- networking.networkmanager.enable = true; # Static IP policy: # - Static IP must be on Wi-Fi SSID "Aussie Broadband 8729" # - Do NOT store Wi-Fi secrets (PSK) in git-tracked Nix files # # Approach: # - Connect to Wi-Fi normally via nmtui/nmcli/GUI (credentials stored locally by NM) # - On activation, this dispatcher script enforces the static IP/DNS/gateway # only for that SSID on interface wlp4s2. environment.etc."NetworkManager/dispatcher.d/10-wlp4s2-static-ip-aussie-broadband-8729".source = pkgs.writeShellScript "10-wlp4s2-static-ip-aussie-broadband-8729" '' set -euo pipefail IFACE="$1" STATUS="$2" TARGET_ID="Aussie Broadband 8729" NMCLI="${pkgs.networkmanager}/bin/nmcli" # Only touch the Wi-Fi interface you specified. if [[ "$IFACE" != "wlp4s2" ]]; then exit 0 fi # Apply on pre-up/up so settings are in place as early as possible. case "$STATUS" in pre-up|up) ;; *) exit 0 ;; esac # NetworkManager dispatcher provides these env vars. # If they are missing, we can't safely target the right connection. if [[ -z "''${CONNECTION_UUID:-}" ]]; then exit 0 fi # Ensure it is actually a Wi-Fi connection. TYPE="$("$NMCLI" -g connection.type connection show "$CONNECTION_UUID" 2>/dev/null || true)" if [[ "$TYPE" != "802-11-wireless" ]]; then exit 0 fi # Determine the connection "id" (name). This is typically the SSID, but not always. CONN_ID="$("$NMCLI" -g connection.id connection show "$CONNECTION_UUID" 2>/dev/null || true)" if [[ "$CONN_ID" != "$TARGET_ID" ]]; then exit 0 fi # Enforce your confirmed static IPv4 configuration. "$NMCLI" connection modify "$CONNECTION_UUID" \ ipv4.method manual \ ipv4.addresses "192.168.20.27/24" \ ipv4.gateway "192.168.20.1" \ ipv4.dns "192.168.20.35 192.168.20.13" \ ipv4.ignore-auto-dns yes \ ipv6.method auto # NOTE: # This modifies the connection profile. If the connection is already "up", # you may need to reconnect once for all settings to apply immediately: # nmcli connection down "$CONNECTION_UUID" # nmcli connection up "$CONNECTION_UUID" exit 0 ''; environment.etc."NetworkManager/dispatcher.d/10-wlp4s2-static-ip-aussie-broadband-8729".mode = "0755"; # --- # Users # --- programs.kdeconnect.enable = true; services.gvfs.enable = true; services.tumbler.enable = true; programs.zsh.enable = true; users.users.sam = { isNormalUser = true; description = "Sam"; extraGroups = [ "wheel" "networkmanager" "video" "render" "docker"]; shell = pkgs.zsh; }; # greetd runs the greeter session as this user; it must exist. users.groups.greeter = { }; users.users.greeter = { isSystemUser = true; group = "greeter"; home = "/var/lib/greeter"; createHome = true; }; # --- # SSH # --- services.openssh = { enable = true; openFirewall = true; settings = { PasswordAuthentication = true; KbdInteractiveAuthentication = true; PermitRootLogin = "no"; }; }; #services.openssh.enable = true; # services.openssh.openFirewall = true; # Defaulting to keys-only for safety. If you explicitly want password auth for the migration, # flip this to true. #services.openssh.settings.PasswordAuthentication = false; # Explicitly enable firewall (keep SSH as the only opened port via openFirewall above). networking.firewall.enable = true; # --- # dconf (helps portals/GTK apps) # --- programs.dconf.enable = true; # Polkit is commonly required for a smooth experience with portals and desktop actions, # especially in minimal Wayland sessions. security.polkit.enable = true; # --- # Firmware / microcode (stability) # --- hardware.enableRedistributableFirmware = true; hardware.cpu.intel.updateMicrocode = true; # --- # OpenGL (important for NVIDIA Wayland apps) # --- hardware.graphics = { enable = true; enable32Bit = true; }; # --- # Audio (PipeWire) # --- security.rtkit.enable = true; services.pipewire = { enable = true; pulse.enable = true; alsa.enable = true; alsa.support32Bit = true; wireplumber.enable = true; }; # --- # Swap (zram; no hibernation) # --- zramSwap.enable = true; # --- # Docker (DEFER for now) # --- virtualisation.docker.enable = true; # --- # Mounts # --- # fileSystems."/data" = { # device = "/dev/disk/by-uuid/27febd74-20aa-4a3a-92c1-6fdd1ad7e88e"; # fsType = "ext4"; # options = [ "nofail" "x-systemd.device-timeout=1s" ]; # }; fileSystems."/mnt/integral300" = { device = "/dev/disk/by-uuid/27febd74-20aa-4a3a-92c1-6fdd1ad7e88e"; fsType = "ext4"; options = [ "nofail" "noauto" "x-systemd.automount" "x-systemd.idle-timeout=60" "x-systemd.device-timeout=30s" ]; }; fileSystems."/mnt/backup" = { device = "/dev/disk/by-uuid/0806B92006B90FA4"; fsType = "ntfs3"; options = [ "ro" "nofail" "noauto" "x-systemd.automount" "x-systemd.idle-timeout=60" "x-systemd.device-timeout=30s" "uid=1000" "gid=100" "umask=022" ]; }; fileSystems."/mnt/tempbackup" = { device = "/dev/disk/by-uuid/4f9c4bd5-fea5-408f-9370-731fc095da3f"; fsType = "ext4"; options = [ "nofail" "noauto" "x-systemd.automount" "x-systemd.idle-timeout=60" "x-systemd.device-timeout=30s" ]; }; fileSystems."/mnt/xpsystemdrive" = { device = "/dev/disk/by-uuid/82c994f1-9adb-49e4-ba1e-5b6e5ccbd49b"; fsType = "ext4"; options = [ "nofail" "noauto" "x-systemd.automount" "x-systemd.idle-timeout=60" "x-systemd.device-timeout=30s" ]; }; fileSystems."/mnt/smartdrive" = { device = "/dev/disk/by-uuid/819c3228-c1af-4d8e-b507-2ad11b20cbef"; fsType = "ext4"; options = [ "nofail" "noauto" "x-systemd.automount" "x-systemd.idle-timeout=60" "x-systemd.device-timeout=30s" ]; }; systemd.tmpfiles.rules = lib.mkAfter [ "d /mnt/integral300 0755 root root -" "d /mnt/backup 0755 root root -" "d /mnt/tempbackup 0755 root root -" "d /mnt/xpsystemdrive 0755 root root -" "d /mnt/smartdrive 0755 root root -" ]; # --- # Niri + login (greetd) # --- services.greetd = { enable = true; settings = { default_session = { user = "greeter"; command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --remember --cmd ${ lib.escapeShellArg "${pkgs.bash}/bin/bash -lc 'mkdir -p ~/.local/state; exec ${pkgs.niri}/bin/niri --session 2>~/.local/state/niri.log'" }"; }; }; }; # Wayland portals (refine later if screencast needs a different backend) xdg.portal = { enable = true; extraPortals = [ pkgs.xdg-desktop-portal-gtk pkgs.xdg-desktop-portal-wlr ]; }; fonts.packages = with pkgs; [ nerd-fonts.symbols-only font-awesome nerd-fonts.jetbrains-mono ]; # Minimal system packages needed for the session and core usability environment.systemPackages = with pkgs; [ uv (pkgs.callPackage ../../pkgs/agentpipe.nix { }) (pkgs.callPackage ../../pkgs/sidecar-bin.nix { }) xfce.thunar xfce.tumbler ffmpegthumbnailer poppler-utils kdePackages.kdeconnect-kde tmux brave vorta borgbackup libreoffice-fresh filezilla nushell zed-editor brave swappy nerd-fonts.symbols-only font-awesome nerd-fonts.jetbrains-mono spotify vlc telegram-desktop flameshot waybar firefox google-chrome kitty fuzzel niri greetd.tuigreet xwayland wl-clipboard grim slurp ]; services.tailscale.enable = true; # --- # NVIDIA (simple, first-boot stable config; PRIME tuning later) # --- services.xserver.videoDrivers = [ "nvidia" ]; hardware.nvidia = { modesetting.enable = true; nvidiaSettings = true; nvidiaPersistenced = true; open = false; # Helps resume by preserving VRAM allocations: powerManagement.enable = true; }; # --- # NixOS release compatibility # --- system.stateVersion = "24.05"; }