terra: add Ryzen 9 5900X desktop (Hyprland, tailnet, dev tools)

Replaces CachyOS on the OS SSD (Kingston SA400, disko-managed). Dev-data
disks (sdc ext4 /mnt/hdd_01, LVM vg_ssd /mnt/ssd_01) stay out of disko and
are mounted as plain filesystems so they're never wiped. Desktop split into
services/desktop/desktop-hyprland.nix (session: compositor, greeter, audio,
portals) and desktop-apps.nix (things darman actually launches, including
claude-code — allowlisted alongside the other unfree desktop apps).
This commit is contained in:
2026-07-23 23:14:36 +02:00
parent c86e8a19c4
commit 67b12cb96b
10 changed files with 347 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
{ config, pkgs, lib, ... }:
# terra — Ryzen 9 5900X / Radeon RX 6800 XT desktop (MSI MS-7A32). Replaces
# CachyOS on the OS SSD (Kingston SA400, sdb). Dev-data disks (sdc ext4
# /mnt/hdd_01, LVM vg_ssd /mnt/ssd_01) are kept out of disko and mounted here
# as plain filesystems so they're never wiped. The leftover ntfs disks
# (sda, sdf, nvme0n1) are ignored entirely — not referenced anywhere.
{
imports = [
./hardware-configuration.nix
./disk-config.nix # disko: OS-disk (sdb) partitions + filesystems
./secrets.nix # sops-nix: darman password, tailscale key
../../common.nix # shared base: user / ssh / nix / firewall
../../services/vpn/tailscale.nix
../../services/desktop/desktop-hyprland.nix
../../services/desktop/desktop-apps.nix
];
networking.hostName = "terra";
# ---- home-manager (user-level config for darman) ----
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.backupFileExtension = "hm-bak";
home-manager.users.darman = import ./home.nix;
# ---- Boot (UEFI) ----
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
hardware.cpu.amd.updateMicrocode = true;
# ---- Dev-data disks — NOT in disko, mounted read-write, never wiped ----
# UUIDs captured from the running CachyOS box; verify after install
# (`lsblk -o NAME,UUID,MOUNTPOINT`) in case disko/kernel enumerates differently.
fileSystems."/mnt/hdd_01" = {
device = "/dev/disk/by-uuid/b8445126-ec6d-4f88-818a-d9e13031d9a4";
fsType = "ext4";
options = [ "nofail" ];
};
fileSystems."/mnt/ssd_01" = {
device = "/dev/disk/by-uuid/6ca18a9f-27bc-4e58-aea8-de43a0d0ed5d";
fsType = "ext4";
options = [ "nofail" ];
};
system.stateVersion = "26.05";
}
+42
View File
@@ -0,0 +1,42 @@
{ ... }:
# Declarative OS-disk layout (disko). UEFI: GPT with an ESP + ext4 root.
# disko both PARTITIONS/FORMATS this disk and generates the NixOS
# `fileSystems.*` entries, so hardware-configuration.nix must NOT define
# fileSystems for "/" or "/boot".
#
# ⚠️ This disk is WIPED on install. This is the Kingston SA400 SSD that
# currently holds CachyOS (btrfs root+subvols on sdb2, ESP on sdb1).
# The dev-data disks (sdc ext4 /mnt/hdd_01, LVM vg_ssd /mnt/ssd_01) and the
# leftover ntfs disks (sda, sdf, nvme0n1) are NOT listed here — they are
# mounted as plain fileSystems in configuration.nix (or, for the ntfs
# disks, ignored entirely) so they are never touched.
{
disko.devices.disk.os = {
type = "disk";
device = "/dev/disk/by-id/ata-KINGSTON_SA400S37480G_50026B738072F6C6";
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
}
+22
View File
@@ -0,0 +1,22 @@
# PLACEHOLDER — replaced on install.
#
# disko (disk-config.nix) owns "/" and "/boot", so this file only carries
# kernel modules + platform. nixos-anywhere regenerates it via:
# nixos-generate-config --no-filesystems
# Standard AMD desktop (SATA SSD, NVMe present but unused) — the generator
# should get ahci/nvme right on its own; these are a sane fallback so stage-1
# still mounts root if it doesn't.
{ config, lib, pkgs, modulesPath, ... }:
{
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "usb_storage" "usbhid" "sd_mod" "nvme" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# NO fileSystems here — disko defines "/" and "/boot".
swapDevices = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}
+101
View File
@@ -0,0 +1,101 @@
{ pkgs, ... }:
# home-manager profile for darman on terra. System-level Hyprland enable
# (session entry, portals) lives in ../../services/desktop/desktop-hyprland.nix; this
# manages the user's own hyprland.conf + session packages.
{
home.stateVersion = "26.05";
wayland.windowManager.hyprland = {
enable = true;
# Starter config — replace with your real dotfiles.
settings = {
monitor = [ ",preferred,auto,1" ];
"$mod" = "SUPER";
bind = [
"$mod, Return, exec, alacritty"
"$mod, Q, killactive"
"$mod, D, exec, wofi --show drun"
];
};
};
programs.git.enable = true;
programs.home-manager.enable = true;
# ---- Dracula theming (GTK + Qt) ----
gtk = {
enable = true;
theme = {
name = "Dracula";
package = pkgs.dracula-theme;
};
};
# dracula-qt5-theme ships only a qt5ct color scheme (no style plugin), so
# Qt has to go through qt(5|6)ct rather than a direct style/platformTheme
# name. "qtct" pulls in both qt5ct and qt6ct; qt6ct reads its own config
# but understands the same scheme file format, so both point at it.
qt = {
enable = true;
platformTheme.name = "qtct";
};
xdg.configFile."qt5ct/qt5ct.conf".text = ''
[Appearance]
color_scheme_path=${pkgs.dracula-qt5-theme}/share/qt5ct/colors/Dracula.conf
custom_palette=true
style=Fusion
'';
xdg.configFile."qt6ct/qt6ct.conf".text = ''
[Appearance]
color_scheme_path=${pkgs.dracula-qt5-theme}/share/qt5ct/colors/Dracula.conf
custom_palette=true
style=Fusion
'';
# Custom mime-info defs (sln/slnx). xdg.mime's update-mime-database only
# indexes share/mime/packages inside the hm profile itself, so this has to
# be a package in home.packages, not a plain xdg.dataFile.
xdg.mime.enable = true;
home.packages = [
(pkgs.writeTextDir "share/mime/packages/application-x-ms-sln.xml"
(builtins.readFile ../../dotfiles/mime/application-x-ms-sln.xml))
pkgs.claude-code
];
programs.alacritty = {
enable = true;
settings = {
env.SHELL = "/bin/zsh";
terminal.shell = {
program = "/bin/zsh";
args = [ "-l" ];
};
window = {
padding = { x = 10; y = 10; };
opacity = 0.8;
};
font.normal = {
family = "DepartureMono Nerd Font";
style = "Regular";
};
colors.primary = {
background = "#222831";
foreground = "#ffd369";
};
hints.enabled = [
{
hyperlinks = true;
regex = "(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)[^\\u0000-\\u001F\\u007F-\\u009F<>\"\\s{-}\\^`]+";
command = "xdg-open";
mouse.enabled = true;
}
];
keyboard.bindings = [
# ESC + CR: nix strings have no \u escape, so fromJSON (which
# supports \u001B) is used to get the literal control chars here.
{ key = "Return"; mods = "Shift"; chars = builtins.fromJSON ''"\u001B\r"''; }
];
};
};
}
+15
View File
@@ -0,0 +1,15 @@
{ config, ... }:
# sops-nix wiring for terra (desktop). Encrypted values in ../../secrets/terra.yaml,
# decrypted with terra's own SSH host key (recipient in ../../.sops.yaml).
# The host key is pre-generated on the laptop and shipped at install
# (nixos-anywhere --extra-files -> /etc/ssh/ssh_host_ed25519_key).
{
sops.defaultSopsFile = ../../secrets/terra.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.secrets.tailscale_authkey = { };
sops.secrets.darman_password.neededForUsers = true;
users.users.darman.hashedPasswordFile = config.sops.secrets.darman_password.path;
}