diff --git a/README.md b/README.md index 3f41d8d..577f1e4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # NixOS Configuration -A full set of configuration files managed via NixOS. This project is an extension of the [Auxolotl system template](https://git.auxolotl.org/auxolotl/templates). +A full set of configuration files managed via NixOS. This project is an **unofficial** extension of the [Auxolotl system template](https://git.auxolotl.org/auxolotl/templates). > [!WARNING] > DO NOT DOWNLOAD AND RUN `nixos-rebuild` ON THIS REPOSITORY! These are my personal configuration files. I invite you to look through them, modify them, and take inspiration from them, but if you run `nixos-rebuild`, it _will completely overwrite your current system_! @@ -19,27 +19,37 @@ git submodule update --init --recursive ### First-time installation -To apply the config for the first time (e.g. on a fresh install), run these commands, replacing `Shura` with the name of the host: +When installing on a brand new system, use `bin/format-drives.sh` to format the main drive with an unencrypted boot partition and a LUKS-encrypted BTRFS partition. This also creates a `hardware-configuration.nix` file. + +```sh +./bin/format-drives.sh --boot /dev/nvme0n1p1 --luks /dev/nvme0n1p2 +``` + +Next, set up the host's config under in the `hosts` folder by copying `configuration.nix.template` and `hardware-configuration.nix.template` into a new folder. + +Then, add the host to `flake.nix` under the `nixosConfigurations` section. + +Finally, run `nixos-rebuild`, replacing `host` with the name of the host: ```sh nix flake update -sudo nixos-rebuild switch --flake .#Shura +sudo nixos-rebuild boot --flake .#host ``` `nix flake update` updates the `flake.lock` file, which pins repositories to specific versions. Nix will then pull down any derivations it needs to meet the version. -> [!NOTE] +> [!TIP] > This config installs a [Nix wrapper called nh](https://github.com/viperML/nh). Basic install/upgrade commands can be run using `nh`, but more advanced stuff should use `nixos-rebuild`. ### Running updates -All hosts are configured to run automatic daily updates (see `modules/system/system.nix`). You can disable this by adding `aux.system.services.autoUpgrade = false;` to a hosts config. +All hosts are configured to run automatic daily updates (see `modules/system/system.nix`). You can disable this by adding `aux.system.services.autoUpgrade = false;` to a host's config. -Automatic updates work by `git pull`ing the latest version of the Repo from Forgejo. This repo gets updated nightly by Haven, which updates the `flake.lock` file and pushes it back up to Forgejo. Only one host needs to do this, and you can enable this feature on a host using `aux.system.services.autoUpgrade.pushUpdates = true;`. +Automatic updates work by `git pull`ing the latest version of the repo from Forgejo. This repo gets updated nightly by [`Haven`](./hosts/Haven), which updates the `flake.lock` file and pushes it back up to Forgejo. Only one host needs to do this, and you can enable this feature on a host using `aux.system.services.autoUpgrade.pushUpdates = true;`. #### Manually updating -Run `nh` to update the system. Use the `--update` flag to update `flake.lock` as part of the process. Note that for subsequent builds, you can omit the hostname: +Run `nh` to update the system. Use the `--update` flag to update `flake.lock` as part of the process. After the first build, you can omit the hostname: ```sh nh os boot --update @@ -110,27 +120,16 @@ nixos-rebuild build-vm --flake . > [!NOTE] > Running the VM also creates a `.qcow2` file for data persistence. Remove this file after a while, otherwise data might persist between builds and muck things up. -### Adding a host - -To add a new host: - -1. Create a new folder in `hosts/`. -2. Copy `hosts/configuration.nix.template` into this folder and name it `default.nix`. -3. Run `nixos-hardware-configuration` on the host and copy its `hardware-configuration.nix` file here. You might also want to check the `configuration.nix` generated by this command to see if there's anything you should import into your host's `default.nix`. -4. Configure `/hosts//default.nix` however you'd like. -5. Add the new host to `flake.nix`. -5. Run `nix flake update` and `nixos-rebuild boot --flake .#`. - ## About this repository ### Layout -This config uses two main systems: Flakes, and Home-manager. - +This config uses a custom templating system built off of the [Auxolotl system templates](https://git.auxolotl.org/auxolotl/templates). - Flakes are the entrypoint, via `flake.nix`. This is where Flake inputs and Flake-specific options get defined. -- Home-manager configs live in the `users/` folders. -- Modules are stored in `modules`. All of these files are automatically imported (except home-manager modules); you simply enable the ones you want to use, and disable the ones you don't. For example, to install Flatpak, set `aux.system.ui.flatpak.enable = true;`. +- Hosts are defined in the `hosts` folder. +- Modules are defined in `modules`. All of these files are automatically imported (except home-manager modules). You simply enable the ones you want to use, and disable the ones you don't. For example, to install Flatpak support, set `aux.system.ui.flatpak.enable = true;`. - After adding a new module, make sure to `git add` it before running `nixos-rebuild`. +- Home-manager configs live in the `users/` folders. ### Features @@ -140,11 +139,10 @@ This Nix config features: - Home Manager - Automatic daily updates - AMD, Intel, and Raspberry Pi (ARM64) hardware configurations -- Workstation and server base system configurations -- GNOME desktop environment with KDE integrations +- Support for various GUIs and desktop environments including Gnome, KDE, XFCE, and Hyprland - Boot splash screens via Plymouth -- Secure Boot and TPM -- Disk encryption via LUKS +- Secure Boot support via Lanzaboote +- Disk encryption via LUKS with TPM auto-unlocking - Custom packages and systemd services - Flatpaks - Default ZSH shell using Oh My ZSH diff --git a/bin/format-drives.sh b/bin/format-drives.sh new file mode 100755 index 0000000..b96bd66 --- /dev/null +++ b/bin/format-drives.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# Script to setup a drive for a brand new NixOS installation. + +set -e + +# Configuration parameters +ask_root_password=false # Whether to prompt for a root user password +boot_partition="" # The drive to install the bootloader to +luks_partition="" # The drive partition to create the LUKS container on +root_partition="/dev/mapper/nixos-crypt" # The partition to install NixOS to + +function usage() { + echo "Usage: format-drives.sh [--boot boot-partition-path] [--luks luks-partition-path] [--ask-root-password]" + echo "Options:" + echo " -h | --help Show this help screen." + echo " -b | --boot The path to the boot drive (e.g. /dev/nvme0n1p1)." + echo " -l | --luks The path to the partition to create the LUKS container on (e.g. /dev/nvme0n1p2)." + echo " -a | --ask-root-password Sets a password for the root user account." + exit 2 +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --ask-root-password|-a) + ask_root_password=true + shift + ;; + --boot|-b) + boot_partition=$1 + shift + ;; + --luks|-l) + luks_partition=1 + shift + ;; + --help|-h) + usage + shift + ;; + *) + break + ;; + esac +done + +if [ "$(id -u)" != "0" ]; then + echo "This script must be run as root" 1>&2 + exit 1 +fi + +cryptsetup --label=nixos-crypt --type=luks2 luksFormat $luks_partition +cryptsetup luksOpen $luks_partition nixos-crypt +mkfs.btrfs -L nixos $root_partition +mount /dev/mapper/nixos-crypt /mnt +btrfs subvolume create /mnt/@ +btrfs subvolume create /mnt/@home +btrfs subvolume create /mnt/@log +btrfs subvolume create /mnt/@nix +btrfs subvolume create /mnt/@swap +umount /mnt + +mount -o subvol=@ $root_partition /mnt +mkdir -p /mnt/{boot,home,var/log,nix,swap} +mount $boot_partition /mnt/boot +mount -o subvol=@home $root_partition /mnt/home +mount -o subvol=@log $root_partition /mnt/var/log +mount -o subvol=@nix $root_partition /mnt/nix +mount -o subvol=@swap $root_partition /mnt/swap +echo "Disks partitioned and mounted to /mnt." + +# Generate hardware-configuration.nix +nixos-generate-config --no-filesystems --dir /home/nixos +echo "Configuration files generated and saved to /home/nixos." + +echo "Setup complete!" +echo "To install, set up your system's configuration files under ./hosts/yourHost and add it to flake.nix." +echo "Then, run the following command:" +echo "nixos-install --verbose --root /mnt --flake [path-to-flake.nix] $( (( ask_root_password == false )) && echo "--no-root-password" )" + +exit 0 + diff --git a/bin/install-nixos.sh b/bin/install-nixos.sh deleted file mode 100755 index f4b1d0c..0000000 --- a/bin/install-nixos.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# Script to install a brand new NixOS installation. -# Formats the drive provided, then runs nixos-install. - -set -e - -# Configuration parameters -ask_root_password=true # Prompt for a root user password -flakeDir="." # Where the flake.nix file is stored -boot_drive="/dev/disk/by-uuid/B2D7-96C3" # The drive to install the bootloader to -luks_drive="/dev/nvme0n1p2" -root_drive="/dev/mapper/nixos-crypt" # The partition to install NixOS to - -if [ "$(id -u)" != "0" ]; then - echo "This script must be run as root" 1>&2 - exit 1 -fi - -# FIXME: Need to get the UUID from the newly-created LUKS partition, then use it going forward. -cryptsetup --label=nixos-crypt --type=luks2 luksFormat $root_drive -cryptsetup luksOpen $root_drive nixos-crypt -mkfs.btrfs -L nixos $root_drive -mount /dev/mapper/nixos-crypt /mnt -btrfs subvolume create /mnt/@ -btrfs subvolume create /mnt/@home -btrfs subvolume create /mnt/@log -btrfs subvolume create /mnt/@nix -btrfs subvolume create /mnt/@swap -umount /mnt - -mount -o subvol=@ $root_drive /mnt -mkdir -p /mnt/{boot,home,var/log,nix,swap} -mount $boot_drive /mnt/boot -mount -o subvol=@home $root_drive /mnt/home -mount -o subvol=@log $root_drive /mnt/var/log -mount -o subvol=@nix $root_drive /mnt/nix -mount -o subvol=@swap $root_drive /mnt/swap -echo "Disks partitioned and mounted to /mnt." - -# Generate hardware-configuration.nix -nixos-generate-config --no-filesystems --dir /home/nixos -echo "Configuration files generated and saved to /home/nixos." - -echo "Setup complete!" -echo "To install, set up your system's configuration files under ./hosts/yourHost and add it to flake.nix." -echo "Then, run the following command:" -echo "nixos-install --verbose --root /mnt --flake $flakeDir#Khanda --max-jobs 1 --cores 10 $( (( ask_root_password == false )) && echo "--no-root-password" )" - -exit 0 - diff --git a/hosts/hardware-configuration.nix.template b/hosts/hardware-configuration.nix.template new file mode 100644 index 0000000..d8c2544 --- /dev/null +++ b/hosts/hardware-configuration.nix.template @@ -0,0 +1,67 @@ +# Template for setting a new host's hardware configuration +{ + config, + lib, + pkgs, + modulesPath, + ... +}: +let + hostName = "myHost"; + platform = "x86_64-linux"; + bootUUID = "ABCD-1234"; # The UUID of the boot partition. + luksUUID = "1408f9cf-68b8-4063-b919-48edde3329a5"; # The UUID of the encrypted LUKS partition. + rootUUID = "3eab3498-9597-454a-a790-43f4c99a87cd"; # The UUID of the unlocked filesystem partition. +in +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + + # Configure the kernel. + boot = { + # Run `nixos-generate-config --no-filesystems` to generate a baseline hardware configuration. + initrd = { + availableKernelModules = [ + "nvme" + "xhci_pci" + "usbhid" + "usb_storage" + "sd_mod" + ]; + }; + + kernelModules = [ ]; + }; + + # Configure the main filesystem. + aux.system.filesystem = { + btrfs = { + enable = true; + devices = { + boot = "/dev/disk/by-uuid/${bootUUID}"; + btrfs = "/dev/disk/by-uuid/${rootUUID}"; + }; + swapFile = { + enable = true; + size = 16384; # By default, this creates a 16GB swap file. Change this to whatever you'd like. + }; + }; + luks = { + enable = true; + uuid = luksUUID; + }; + }; + + networking = { + # 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`. + useDHCP = lib.mkDefault true; + # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; + + # Set the hostname. + hostName = hostName; + }; + + nixpkgs.hostPlatform = lib.mkDefault platform; +} diff --git a/modules/system/filesystem.nix b/modules/system/filesystem.nix index 75b3c13..220b571 100644 --- a/modules/system/filesystem.nix +++ b/modules/system/filesystem.nix @@ -48,12 +48,16 @@ in assertions = [ { assertion = cfg.btrfs.devices.btrfs != ""; - message = "Please specify a BTRFS partition to use as a filesystem."; + message = "Please specify the BTRFS partition UUID to use as the filesystem."; } { assertion = cfg.btrfs.devices.boot != ""; - message = "Please specify a boot partition to use as a filesystem."; + message = "Please specify the boot partition UUID."; } + (lib.mkIf cfg.luks.enable { + assertion = cfg.luks.uuid != ""; + message = "Please enter a valid UUID for the encrypted LUKS volume."; + }) ]; boot.initrd.luks.devices = lib.mkIf cfg.luks.enable { "luks-${cfg.luks.uuid}" = { diff --git a/modules/ui/desktops/common.nix b/modules/ui/desktops/common.nix index 812783b..dbcb1f8 100644 --- a/modules/ui/desktops/common.nix +++ b/modules/ui/desktops/common.nix @@ -88,12 +88,14 @@ in binfmt = true; }; - # Install full GStreamer capabilities. - # References: - # https://wiki.nixos.org/wiki/GStreamer - # https://github.com/NixOS/nixpkgs/issues/195936 - environment = { - sessionVariables.GST_PLUGIN_SYSTEM_PATH_1_0 = lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" ( + environment.sessionVariables = { + # Tell Electron apps that they can use Wayland + NIXOS_OZONE_WL = "1"; + # Install full GStreamer capabilities. + # References: + # https://wiki.nixos.org/wiki/GStreamer + # https://github.com/NixOS/nixpkgs/issues/195936 + GST_PLUGIN_SYSTEM_PATH_1_0 = lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" ( with pkgs.gst_all_1; [ gstreamer