From 28e8bc938a3644ce474ce17f650053f727827b8e Mon Sep 17 00:00:00 2001 From: Chris Wong Date: Tue, 6 Oct 2026 15:58:10 +0100 Subject: [PATCH] feat(nixos): consolidate hosts into a shared flake Manage T450s, X1EG2 and Framework 13 from pinned NixOS inputs while retaining machine-specific storage and hardware configuration. Changes: Shared Configuration: - Extract common, KDE, desktop, development and Steam modules - Share Emacs, VS Code, htop, DevOps tools and Docker across hosts - Remove obsolete apps and global project language runtimes Framework: - Import the 11th-generation Intel hardware profile - Enable Steam and ZFS with tookland/home mounted at /home - Document manual ext4 root and ZFS installation steps - Require installer-generated hardware configuration before installation Validation: - Evaluate both ThinkPads and Framework with test hardware - Check Nix syntax, formatting and whitespace --- .gitignore | 7 + README.md | 181 +++++++++++++++++++++ flake.lock | 65 ++++++++ flake.nix | 45 +++++ hosts/framework/README.md | 100 ++++++++++++ hosts/framework/configuration.nix | 39 +++++ hosts/framework/hardware-configuration.nix | 12 ++ hosts/t450s/configuration.nix | 71 ++++++++ hosts/t450s/hardware-configuration.nix | 42 +++++ hosts/x1eg2/configuration.nix | 172 ++++++++++++++++++++ hosts/x1eg2/hardware-configuration.nix | 46 ++++++ modules/common.nix | 43 +++++ modules/desktop-apps.nix | 19 +++ modules/development.nix | 48 ++++++ modules/gaming.nix | 9 + modules/kde.nix | 23 +++ 16 files changed, 922 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 hosts/framework/README.md create mode 100644 hosts/framework/configuration.nix create mode 100644 hosts/framework/hardware-configuration.nix create mode 100644 hosts/t450s/configuration.nix create mode 100644 hosts/t450s/hardware-configuration.nix create mode 100644 hosts/x1eg2/configuration.nix create mode 100644 hosts/x1eg2/hardware-configuration.nix create mode 100644 modules/common.nix create mode 100644 modules/desktop-apps.nix create mode 100644 modules/development.nix create mode 100644 modules/gaming.nix create mode 100644 modules/kde.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f6a2377 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*~ +result +result-* +.env +.env.* +crypto_keyfile.bin +*.key diff --git a/README.md b/README.md new file mode 100644 index 0000000..73b0f81 --- /dev/null +++ b/README.md @@ -0,0 +1,181 @@ +# NixOS configurations + +One flake manages three x86_64 machines. NixOS uses stable `nixos-26.05`; +`nixos-unstable` supplies only packages the older configs already selected +from unstable. `nixos-hardware` provides the Framework 11th-gen Intel profile. +All inputs are pinned in `flake.lock`. + +| Flake host | Network hostname | Hardware | +| --- | --- | --- | +| `t450s` | `samwise` | ThinkPad T450s, original encrypted ext4 layout | +| `x1eg2` | `bilbo` | ThinkPad X1 Extreme Gen 2, original ZFS/NVIDIA layout | +| `framework` | `framework` | Framework 13, Intel i5-1135G7; generated hardware file required | + +## Organization + +Each `hosts//configuration.nix` explicitly imports its own generated +`hardware-configuration.nix` and selected shared modules: + +- `common.nix`: flakes, store maintenance, locale, NetworkManager, user `clw`, zsh. +- `kde.nix`: Plasma 6, SDDM, US keyboard, PipeWire, Bluetooth, printing, Flatpak. +- `development.nix`: Emacs, VS Code, htop, general CLI/DevOps tools, Docker, + direnv and nix-direnv on every host. +- `desktop-apps.nix`: selected shared desktop applications, imported by the two + ThinkPads only. +- `gaming.nix`: shared Steam setup on all three hosts. The ThinkPads' different + games, Wine variants and X1EG2 GameMode customization stay at host level. + +Storage, encryption, NVIDIA/PRIME, undervolting, backup datasets, virtualization, +SSH server and firewall policy live in the host configurations. There is no +shared laptop module because the older configurations did not have common +laptop tuning. Framework enables power-profiles-daemon and touchpad support +locally, and uses the upstream Framework 11th-gen Intel hardware profile. Its +generated hardware file supplies the actual disk UUIDs and detected devices. + +## Rebuild + +From this checkout on the relevant machine: + +```sh +sudo nixos-rebuild build --flake .#t450s +sudo nixos-rebuild switch --flake .#t450s +# Or use .#x1eg2 / .#framework +``` + +Flake names are independent of network hostnames. New files must be tracked +with `git add` for Git-backed flakes to include them. Review the release upgrade +before switching: the old machines were configured for Plasma 5, whereas the +current release uses Plasma 6. Keep the original `system.stateVersion` values +(`23.05` and `23.11`); changing inputs does not require changing stateVersion. + +The ThinkPads retain their disabled firewall. Only T450s enables the SSH server; +Framework keeps the firewall enabled, with the gaming module's Steam port +exceptions, and does not enable the SSH server. +T450s still requires `/crypto_keyfile.bin` on that machine for its initrd. Never +put that key in this repository. Its existing ZFS support is also preserved even +though the generated root filesystem is ext4. + +## Install Framework + +Framework uses a GPT layout with a FAT32 EFI partition at `/boot`, ext4 at `/`, +and the remaining drive space in ZFS pool `tookland`. Dataset `tookland/home` +is mounted at `/home`; other datasets can be created later. + +The NixOS configuration enables ZFS, imports the existing pool, mounts home, +and schedules scrubs. It does **not** partition disks or create pools/datasets. +Follow the [Framework installation guide](hosts/framework/README.md) to create +and mount them before generating hardware configuration and running: + +```sh +sudo nixos-install --flake /mnt/etc/nixos-config#framework +``` + +Replace the deliberate failing `hosts/framework/hardware-configuration.nix` +placeholder with the file generated by `nixos-generate-config --root /mnt`. +No disk UUIDs are copied from another machine. Keep Framework's initial +`system.stateVersion = "26.05"` after installation. + +## Add a host + +1. Generate its hardware configuration on that machine or mounted installation. +2. Create `hosts//configuration.nix`, import its hardware file and the + shared modules you need, and set hostname, bootloader and initial stateVersion. +3. Add an explicit `nixpkgs.lib.nixosSystem` entry under `nixosConfigurations` + in `flake.nix`, pointing to the new host configuration. +4. Track the files, evaluate/build, then install or rebuild with `.#`. + +## Development + +General workstation tools belong here. Each project should provide its own +`devShell`, container, or equivalent for languages, SDKs and dependencies: + +```sh +nix develop +# For a project using direnv, review .envrc then: +direnv allow +``` + +An `.envrc` containing `use flake` integrates a project's devShell with direnv. +No existing development projects were changed. Docker and Compose are available +on every host, with `clw` in the Docker group. Ansible and AWS CLI are shared +DevOps tools. The module includes JSON/YAML tools (`jq`, `yq`), file/search +utilities, tmux, and network troubleshooting tools. It does not add project +language runtimes or Kubernetes/Terraform tooling. Android +Studio remains on the ThinkPads as an existing IDE/workflow choice, but its +bundled SDK is worth reviewing if moving fully to project-local tooling. + +## Migration and package review + +The original repositories are left untouched. No credentials were found in the +tracked configurations or a pattern scan of their Git history. UUIDs, host IDs, +and references to local encryption keys are not the keys themselves. +Do not add passwords, Wi-Fi PSKs, private keys, tokens or API credentials to Nix +files. No secrets framework is added. + +Changes required for the current release include Plasma 6 and renamed graphics, +keyboard, display-manager and package options. `programs.adb` and its old +`adbusers` group are removed: systemd now grants device access automatically, +and `android-tools` still provides ADB. Libvirt now exposes QEMU's OVMF firmware +without the removed `qemu.ovmf` settings. NVIDIA containers use the current +toolkit/CDI integration (for example, `docker run --device nvidia.com/gpu=all …`). +`ffmpeg_6` becomes current `ffmpeg`, KCalc comes from `kdePackages`, Bitwarden +becomes `bitwarden-desktop`, `du-dust` becomes `dust`, Jellyfin becomes +`jellyfin-desktop`, and Proton VPN becomes `proton-vpn`. The Adwaita, nvtop, Noto +fonts and Wine attribute names are also updated; `noto-fonts-extra` is now +covered by `noto-fonts`. + +`whatsapp-for-linux` is removed because nixpkgs reports it was unmaintained +and archived upstream. No replacement is installed automatically. The obsolete insecure-package +exceptions for `mailspring-1.12.0` and `electron-24.8.6` are removed; do not restore +these old exceptions simply to force evaluation. + +Removed from global packages in both old hosts: Java (`jdk`), Node 20, Flutter, +Perl and Python. Put the versions each project needs in its development shell. +Applications can still bring their own runtime dependencies. + +The shared desktop app selection omits Calf, Cryptomator, Discord, gscan2pdf, +Minigalaxy, Proton VPN and Tilix. Tilix's VTE shell integration is removed too. +Brave, Signal and Rocket.Chat now use stable nixpkgs from this shared module, +instead of duplicate host entries (some previously used unstable). Emacs is +also shared across all hosts using stable nixpkgs, as is VS Code. + +Review these preserved choices before your first switch: + +- Android Studio, Postman and Android tools: retain only tools + you use across projects; SDKs are better project-local. +- Mailspring, Rocket.Chat, Threema wrappers: verify which messaging + clients you still use; availability may have changed since the old configs. +- Firefox plus Chrome plus Brave, VLC plus mpv plus Jellyfin, and + overlapping mail clients: remove whichever you no longer use. +- Wine, Lutris and VCMI: older ThinkPad gaming choices; Framework currently + gets Steam through the shared gaming module. +- HP/Canon printing drivers and scanner support on T450s: keep only if you still + own the relevant devices. +- T450s ZFS support and host ID: retained despite its ext4 root; check whether + you still attach ZFS pools. +- X1EG2's `-100` CPU undervolt, PRIME bus IDs, NVIDIA power management, root-run + QEMU, ZFS pools and Sanoid datasets are hardware/workflow-specific and retained. + Confirm they still describe the actual machine before activating the upgrade. + +## Update inputs and check + +```sh +nix flake update +# Or update one input: +nix flake update nixpkgs +nix eval --raw .#nixosConfigurations.t450s.config.system.build.toplevel.drvPath +nix eval --raw .#nixosConfigurations.x1eg2.config.system.build.toplevel.drvPath +# After replacing Framework's hardware file: +nix eval --raw .#nixosConfigurations.framework.config.system.build.toplevel.drvPath +sudo nixos-rebuild build --flake .#framework +``` + +Review and commit `flake.lock` after checking the hosts. `nix flake check` will +fail on the intentional Framework placeholder until its hardware file is supplied. + +Validation uses a temporary Nix Docker container because Nix is not installed +on this workstation. Both ThinkPads evaluate to complete system derivations; +Framework is evaluated with an external test-only ext4/EFI hardware fixture. +The checked-in placeholder remains an intentional evaluation failure until the +installer-generated hardware file is supplied. Full system builds, activation, +and physical disk operations are not performed here. diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..c06881b --- /dev/null +++ b/flake.lock @@ -0,0 +1,65 @@ +{ + "nodes": { + "nixos-hardware": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1791128201, + "narHash": "sha256-rlsYY/Dg/LhbIj51Aa6TLvRpZeb3KZgUTd7llQ5XcJE=", + "owner": "NixOS", + "repo": "nixos-hardware", + "rev": "31cc5f4d9b9ba601071e8b8504601b9b176e2756", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixos-hardware", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1791254437, + "narHash": "sha256-qMSsgG+9tIdx282dMqGuJAUK3t6F36clM6efd0rXfes=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b25309931cfda5f0b8805f462a29897eeae50168", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-26.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1791260994, + "narHash": "sha256-Miqqk/ammqnTUxaoCyvtwoPeLbI1ksFyLxi/CazZpWY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "151fa4e8ddfdd8dd25d945ad94ed54a13de9f6e4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixos-hardware": "nixos-hardware", + "nixpkgs": "nixpkgs", + "nixpkgs-unstable": "nixpkgs-unstable" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..0b400a9 --- /dev/null +++ b/flake.nix @@ -0,0 +1,45 @@ +{ + description = "Chris's NixOS machines"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05"; + # Only the existing hosts use this for apps previously taken from unstable. + nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; + nixos-hardware = { + url = "github:NixOS/nixos-hardware"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + { + nixpkgs, + nixpkgs-unstable, + nixos-hardware, + ... + }: + { + nixosConfigurations = { + t450s = nixpkgs.lib.nixosSystem { + specialArgs.unstable = import nixpkgs-unstable { + system = "x86_64-linux"; + config.allowUnfree = true; + }; + modules = [ ./hosts/t450s/configuration.nix ]; + }; + x1eg2 = nixpkgs.lib.nixosSystem { + specialArgs.unstable = import nixpkgs-unstable { + system = "x86_64-linux"; + config.allowUnfree = true; + }; + modules = [ ./hosts/x1eg2/configuration.nix ]; + }; + framework = nixpkgs.lib.nixosSystem { + modules = [ + nixos-hardware.nixosModules.framework-11th-gen-intel + ./hosts/framework/configuration.nix + ]; + }; + }; + }; +} diff --git a/hosts/framework/README.md b/hosts/framework/README.md new file mode 100644 index 0000000..eb908c2 --- /dev/null +++ b/hosts/framework/README.md @@ -0,0 +1,100 @@ +# Framework 13 installation + +Target: Intel 11th-generation Core i5-1135G7. The flake imports +`nixos-hardware.nixosModules.framework-11th-gen-intel` for model-specific tuning +and enables firmware updates, KDE, shared development tools and Steam. + +## Storage layout + +| Partition | Filesystem | Use | +| --- | --- | --- | +| EFI system partition | FAT32, suggested 1 GiB | `/boot` | +| Linux root partition | ext4, suggested 128–160 GiB | `/`, including `/nix` and `/var` | +| Remaining space | ZFS pool `tookland` | `tookland/home` at `/home`; later VM/ISO datasets | + +Adjust the root size for the drive capacity and your Nix store/container needs. +The ext4 and ZFS partitions have separate space budgets; unused ZFS space does +not automatically grow the ext4 partition. These instructions use unencrypted +filesystems; any disk-encryption setup must be chosen before formatting. + +NixOS manages support, imports and mounts once the pool exists. This repo does +not automate disk partitioning or pool/dataset creation. Use the installer disk +utility to create this GPT layout. Formatting and pool creation erase the +selected partitions: check the actual drive with `lsblk` and use its persistent +`/dev/disk/by-id/…-partN` names. No commands here operate on a guessed device. + +## Format and mount in the installer + +Boot a current NixOS installer with ZFS support and network access. Substitute +the three partition paths below with the partitions you just created. The +literal placeholders will not work as device names. + +```sh +sudo mkfs.fat -F 32 -n EFI "/dev/disk/by-id/REPLACE_WITH_EFI_PARTITION" +sudo mkfs.ext4 -L nixos-root "/dev/disk/by-id/REPLACE_WITH_ROOT_PARTITION" +sudo mount "/dev/disk/by-id/REPLACE_WITH_ROOT_PARTITION" /mnt +sudo mkdir -p /mnt/boot /mnt/home +sudo mount "/dev/disk/by-id/REPLACE_WITH_EFI_PARTITION" /mnt/boot + +sudo modprobe zfs +sudo zpool create -o ashift=12 -o autotrim=on \ + -O compression=lz4 -O acltype=posixacl -O xattr=sa -O relatime=on \ + -m none -R /mnt tookland "/dev/disk/by-id/REPLACE_WITH_ZFS_PARTITION" +sudo zfs create -o mountpoint=legacy tookland/home +sudo mount -t zfs tookland/home /mnt/home +sudo zpool status tookland +sudo zfs list -o name,mountpoint +``` + +Do not format the ZFS partition with `mkfs`. `zpool create` initializes it. +The pool's root dataset has no mountpoint; `tookland/home` uses a legacy +mountpoint so the NixOS `fileSystems."/home"` declaration manages its mount. +`-R /mnt` is an installer-only alternate root, not a permanent `/mnt` mountpoint. +Neither the pool nor its datasets are recreated during a rebuild. + +## Generate hardware configuration and install + +Generate configuration **after** all three filesystems, including `/mnt/home`, +are mounted. This records your real hardware and filesystem layout. + +```sh +sudo nixos-generate-config --root /mnt +# Obtain Git if it is not already available in the installer. +nix --extra-experimental-features 'nix-command flakes' shell nixpkgs#git +sudo git clone /mnt/etc/nixos-config +sudo cp /mnt/etc/nixos/hardware-configuration.nix \ + /mnt/etc/nixos-config/hosts/framework/hardware-configuration.nix +sudo git -C /mnt/etc/nixos-config add hosts/framework/hardware-configuration.nix +sudo nixos-install --flake /mnt/etc/nixos-config#framework +sudo nixos-enter --root /mnt -c 'passwd clw' +``` + +Review the generated hardware file: `/` must be `ext4`, `/boot` must be `vfat`, +and `/home` must refer to `tookland/home` with `fsType = "zfs"`. Identical `/home` +declarations in the generated file and host configuration merge normally. +The installer-generated `configuration.nix` is not used by this flake. + +Once installation and password setup are complete, leave any shell working +under `/mnt/home`, export the pool cleanly, and reboot: + +```sh +sudo zpool export tookland +sudo reboot +``` + +NixOS imports `tookland` and mounts home before user activation. Its fixed host +ID is `fdc3ff7d`; retain it across reinstalls using this pool. Scrubs are enabled. +Create other datasets yourself with explicit mountpoints, for example +`zfs create -o mountpoint=/srv/isos tookland/isos`. Datasets with native +mountpoints are mounted by ZFS; those with `mountpoint=legacy` also need a +NixOS `fileSystems` declaration. Snapshot/backup policies are not configured. + +References: [Framework hardware profile](https://github.com/NixOS/nixos-hardware/tree/master/framework/13-inch/11th-gen-intel), +[NixOS ZFS configuration](https://wiki.nixos.org/wiki/ZFS), +[OpenZFS pool creation](https://openzfs.github.io/openzfs-docs/man/master/8/zpool-create.8.html). + +Validation: this host evaluates to a complete system derivation with a temporary +installer-style ext4/EFI fixture and a duplicate generated `/home` declaration. +Intel microcode, graphics, Steam and ZFS are enabled. Both existing hosts still +evaluate. The actual disk layout and generated hardware file must be supplied +on the Framework; no full build or disk operation was performed during checks. diff --git a/hosts/framework/configuration.nix b/hosts/framework/configuration.nix new file mode 100644 index 0000000..f837e47 --- /dev/null +++ b/hosts/framework/configuration.nix @@ -0,0 +1,39 @@ +{ ... }: +{ + imports = [ + ./hardware-configuration.nix + ../../modules/common.nix + ../../modules/kde.nix + ../../modules/development.nix + ../../modules/gaming.nix + ]; + + nixpkgs.hostPlatform = "x86_64-linux"; + networking.hostName = "framework"; + # Stable, unique ID required by ZFS; keep it unchanged after pool creation. + networking.hostId = "fdc3ff7d"; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Framework 13, Intel Core i5-1135G7. Hardware tuning comes from nixos-hardware. + services.fwupd.enable = true; + + # Existing pool/dataset must be created in the installer; root stays ext4. + boot.supportedFilesystems = [ "zfs" ]; + boot.zfs.extraPools = [ "tookland" ]; + boot.zfs.forceImportRoot = false; + fileSystems."/home" = { + device = "tookland/home"; + fsType = "zfs"; + # Mount home before activation creates user directories. + neededForBoot = true; + }; + services.zfs.autoScrub.enable = true; + + # A simple laptop policy using Plasma's power management integration. + services.power-profiles-daemon.enable = true; + services.libinput.enable = true; + + # First installation release; keep this unchanged after installation. + system.stateVersion = "26.05"; +} diff --git a/hosts/framework/hardware-configuration.nix b/hosts/framework/hardware-configuration.nix new file mode 100644 index 0000000..e10ae98 --- /dev/null +++ b/hosts/framework/hardware-configuration.nix @@ -0,0 +1,12 @@ +# Replace this entire file with /mnt/etc/nixos/hardware-configuration.nix +# after running: sudo nixos-generate-config --root /mnt +# No disks, UUIDs, CPU vendor, or GPU model are guessed here. +{ ... }: +{ + assertions = [ + { + assertion = false; + message = "Framework hardware configuration is missing. Run nixos-generate-config --root /mnt and replace hosts/framework/hardware-configuration.nix with the generated file."; + } + ]; +} diff --git a/hosts/t450s/configuration.nix b/hosts/t450s/configuration.nix new file mode 100644 index 0000000..347cd48 --- /dev/null +++ b/hosts/t450s/configuration.nix @@ -0,0 +1,71 @@ +{ pkgs, unstable, ... }: + +{ + imports = [ + ./hardware-configuration.nix + ../../modules/common.nix + ../../modules/kde.nix + ../../modules/development.nix + ../../modules/desktop-apps.nix + ../../modules/gaming.nix + ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + boot.initrd.secrets = { + "/crypto_keyfile.bin" = null; + }; + + boot.initrd.luks.devices."luks-a9814d3c-ecfc-4aae-a5a9-976a55af4609".device = + "/dev/disk/by-uuid/a9814d3c-ecfc-4aae-a5a9-976a55af4609"; + boot.initrd.luks.devices."luks-a9814d3c-ecfc-4aae-a5a9-976a55af4609".keyFile = + "/crypto_keyfile.bin"; + + boot.supportedFilesystems = [ "zfs" ]; + boot.zfs.forceImportRoot = false; + networking.hostId = "561bd410"; + + boot.binfmt.registrations.appimage = { + wrapInterpreterInShell = false; + interpreter = "${pkgs.appimage-run}/bin/appimage-run"; + recognitionType = "magic"; + offset = 0; + mask = ''\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff''; + magicOrExtension = ''\x7fELF....AI\x02''; + }; + + networking.hostName = "samwise"; + + services.printing.drivers = [ + pkgs.hplipWithPlugin + pkgs.cnijfilter2 + ]; + + services.tailscale.enable = true; + + hardware.sane.enable = true; + + environment.systemPackages = with pkgs; [ + unstable.android-studio + unstable.anytype + unstable.easyeffects + unstable.element-desktop + ffmpeg + kdePackages.kcalc + mailspring + unstable.nextcloud-client + unstable.onedrive + postman + unstable.threema-desktop + unstable.vcmi + wine + unstable.zoom-us + ]; + + services.openssh.enable = true; + + networking.firewall.enable = false; + + system.stateVersion = "23.05"; +} diff --git a/hosts/t450s/hardware-configuration.nix b/hosts/t450s/hardware-configuration.nix new file mode 100644 index 0000000..8469fff --- /dev/null +++ b/hosts/t450s/hardware-configuration.nix @@ -0,0 +1,42 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/aaa3f4d7-a3fe-42a0-ad9c-becd3bca2531"; + fsType = "ext4"; + }; + + boot.initrd.luks.devices."luks-7e29288b-0c13-4aa6-827c-7acd692f7f91".device = "/dev/disk/by-uuid/7e29288b-0c13-4aa6-827c-7acd692f7f91"; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/1353-1FB4"; + fsType = "vfat"; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/4dfd4a6e-118d-4138-9c65-be32bbf37092"; } + ]; + + # 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..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp0s25.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp3s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/x1eg2/configuration.nix b/hosts/x1eg2/configuration.nix new file mode 100644 index 0000000..cd30acf --- /dev/null +++ b/hosts/x1eg2/configuration.nix @@ -0,0 +1,172 @@ +{ + config, + lib, + pkgs, + unstable, + ... +}: + +{ + imports = [ + ./hardware-configuration.nix + ../../modules/common.nix + ../../modules/kde.nix + ../../modules/development.nix + ../../modules/desktop-apps.nix + ../../modules/gaming.nix + ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + boot.initrd.luks.devices = { + "luks-rpool-nvme-WDS500G3X0C-00SJG0_2017B0802813-part2".device = + "/dev/disk/by-id/nvme-WDS500G3X0C-00SJG0_2017B0802813-part2"; + }; + + boot.zfs.extraPools = [ "shire" ]; + # Preserve the original root-pool import policy across the release upgrade. + boot.zfs.forceImportRoot = true; + + services.zfs.autoScrub.enable = true; + + networking.hostName = "bilbo"; + + hardware.graphics = { + enable = true; + enable32Bit = true; + extraPackages = with pkgs; [ + intel-media-driver # LIBVA_DRIVER_NAME=iHD + intel-vaapi-driver # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium) + libvdpau-va-gl + ]; + }; + environment.sessionVariables = { + LIBVA_DRIVER_NAME = "iHD"; + }; # Force intel-media-driver + + services.xserver.videoDrivers = [ "nvidia" ]; + + hardware.nvidia = { + modesetting.enable = true; + powerManagement.enable = false; + powerManagement.finegrained = true; + open = false; + nvidiaSettings = true; + package = config.boot.kernelPackages.nvidiaPackages.stable; + }; + + hardware.nvidia.prime = { + offload = { + enable = true; + enableOffloadCmd = true; + }; + intelBusId = "PCI:0:2:0"; + nvidiaBusId = "PCI:1:0:0"; + }; + + services.tailscale.enable = true; + + services.undervolt = { + enable = true; + coreOffset = -100; + }; + + virtualisation.libvirtd = { + enable = true; + qemu = { + package = pkgs.qemu_kvm; + runAsRoot = true; + swtpm.enable = true; + }; + }; + + hardware.nvidia-container-toolkit = { + enable = true; + package = unstable.nvidia-container-toolkit; + }; + + environment.systemPackages = with pkgs; [ + unstable.android-studio + android-tools + ffmpeg + gimp + adwaita-icon-theme + kdePackages.kcalc + lutris + unstable.mailspring + nextcloud-client + unstable.nvidia-container-toolkit + nvtopPackages.full + pinentry-qt + syncthing + thunderbird + unstable.threema-desktop + wineWow64Packages.waylandFull + zoom-us + ]; + + fonts.packages = with pkgs; [ + noto-fonts + noto-fonts-cjk-sans + noto-fonts-cjk-serif + ]; + + services.sanoid = { + enable = true; + templates = { + production = { + autoprune = true; + autosnap = true; + hourly = 36; + daily = 30; + monthly = 3; + }; + }; + datasets = { + "rpool/home" = { + use_template = [ "production" ]; + }; + "shire/clw/projects" = { + use_template = [ "production" ]; + }; + "shire/clw/Documents" = { + use_template = [ "production" ]; + }; + }; + }; + + services.syncthing = { + enable = true; + user = "clw"; + dataDir = "/home/clw/Sync"; + configDir = "/home/clw/.config/syncthing"; + }; + + programs.steam = { + package = pkgs.steam.override { + extraPkgs = ( + pkgs: with pkgs; [ + gamemode + ] + ); + extraProfile = + let + gmLib = "${lib.getLib (pkgs.gamemode)}/lib"; + in + '' + export LD_LIBRARY_PATH="${gmLib}:$LD_LIBRARY_PATH" + ''; + }; + }; + programs.gamemode.enable = true; + + networking.firewall.enable = false; + + system.stateVersion = "23.11"; + + users.users.clw.extraGroups = [ + "libvirtd" + "kvm" + ]; +} diff --git a/hosts/x1eg2/hardware-configuration.nix b/hosts/x1eg2/hardware-configuration.nix new file mode 100644 index 0000000..4f31ad7 --- /dev/null +++ b/hosts/x1eg2/hardware-configuration.nix @@ -0,0 +1,46 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "sdhci_pci" "battery" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "rpool/root"; + fsType = "zfs"; + }; + + fileSystems."/home" = + { device = "rpool/home"; + fsType = "zfs"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/BF51-953A"; + fsType = "vfat"; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/a468fc29-ad58-474b-ac91-abc40d3567b3"; } + ]; + + # 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..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp82s0.useDHCP = lib.mkDefault true; + networking.hostId = "7330cb06"; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/modules/common.nix b/modules/common.nix new file mode 100644 index 0000000..127a1ec --- /dev/null +++ b/modules/common.nix @@ -0,0 +1,43 @@ +{ pkgs, ... }: +{ + nix.settings.experimental-features = [ + "nix-command" + "flakes" + ]; + nix.settings.auto-optimise-store = true; + nix.gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + nixpkgs.config.allowUnfree = true; + + networking.networkmanager.enable = true; + time.timeZone = "Africa/Tunis"; + i18n.defaultLocale = "en_US.UTF-8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; + + users.users.clw = { + isNormalUser = true; + description = "Chris Wong"; + shell = pkgs.zsh; + extraGroups = [ + "networkmanager" + "wheel" + "scanner" + "lp" + ]; + packages = [ pkgs.firefox ]; + }; + programs.zsh.enable = true; +} diff --git a/modules/desktop-apps.nix b/modules/desktop-apps.nix new file mode 100644 index 0000000..0b92bdc --- /dev/null +++ b/modules/desktop-apps.nix @@ -0,0 +1,19 @@ +{ pkgs, ... }: +{ + # Shared desktop applications; imported by the two ThinkPads. + environment.systemPackages = with pkgs; [ + bitwarden-desktop + brave + flatpak + google-chrome + jellyfin-desktop + libreoffice-qt + mpv + remmina + rocketchat-desktop + signal-desktop + tailscale + virt-manager + vlc + ]; +} diff --git a/modules/development.nix b/modules/development.nix new file mode 100644 index 0000000..98fd045 --- /dev/null +++ b/modules/development.nix @@ -0,0 +1,48 @@ +{ pkgs, ... }: +{ + # Workstation tools only; language runtimes and SDKs belong in projects. + environment.systemPackages = with pkgs; [ + # Editors and shell utilities. + emacs + vscode + git + htop + tmux + ripgrep + fd + duf + dust + killall + lsof + rsync + unzip + zip + + # Infrastructure, containers, and structured data. + ansible + awscli2 + docker-compose + jq + yq-go + + # Networking and security tools. + openssh + gnupg + openssl + curl + dig + mosh + tcpdump + wget + whois + wireguard-tools + ]; + + virtualisation.docker.enable = true; + users.users.clw.extraGroups = [ "docker" ]; + + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; +} diff --git a/modules/gaming.nix b/modules/gaming.nix new file mode 100644 index 0000000..ba18642 --- /dev/null +++ b/modules/gaming.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + # Import on machines where Steam is wanted. + programs.steam = { + enable = true; + remotePlay.openFirewall = true; + dedicatedServer.openFirewall = true; + }; +} diff --git a/modules/kde.nix b/modules/kde.nix new file mode 100644 index 0000000..f647e59 --- /dev/null +++ b/modules/kde.nix @@ -0,0 +1,23 @@ +{ ... }: +{ + services.xserver.enable = true; + services.xserver.xkb = { + layout = "us"; + variant = ""; + }; + services.displayManager.sddm.enable = true; + services.desktopManager.plasma6.enable = true; + programs.dconf.enable = true; + services.printing.enable = true; + services.flatpak.enable = true; + hardware.bluetooth.enable = true; + + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + }; +}