diff --git a/ops/nixos/default.nix b/ops/nixos/default.nix index 6200810566..d94f7793f9 100644 --- a/ops/nixos/default.nix +++ b/ops/nixos/default.nix @@ -20,6 +20,7 @@ let systems = [ "porcorosso" "howl" + "nausicaa" "clouvider-fra01" "totoro" "swann" diff --git a/ops/nixos/installcd/default.nix b/ops/nixos/installcd/default.nix index 79821e2d88..2d4031bdde 100644 --- a/ops/nixos/installcd/default.nix +++ b/ops/nixos/installcd/default.nix @@ -13,10 +13,10 @@ in { isoImage.isoName = lib.mkForce "nixos-${depot.version}-${pkgs.stdenv.hostPlatform.system}.iso"; isoImage.storeContents = [ - depot.ops.nixos.systems.laputa + depot.ops.nixos.systems.nausicaa ]; system.disableInstallerTools = false; - system.stateVersion = "22.05"; + system.stateVersion = "24.05"; } diff --git a/ops/nixos/nausicaa/README.md b/ops/nixos/nausicaa/README.md new file mode 100644 index 0000000000..69603e7b8b --- /dev/null +++ b/ops/nixos/nausicaa/README.md @@ -0,0 +1,16 @@ + + +# nausicaa.roam.lukegb.net + +Dual-booted Windows/NixOS laptop. + +* Base: Framework Laptop 16 DIY Edition (Ryzen 7040 series) +* 64 GiB RAM (2x32GiB DDR5-5600 Framework FRANRMGW03) +* Ryzen 9 7940HS + Radeon 780M Graphics +* Radeon RX 7700S expansion bay +* Windows disk: WD Black SN850X 4TB SSD (M.2 2280) +* Linux disk: WD SN740 2TB SSD (M.2 2230) diff --git a/ops/nixos/nausicaa/default.nix b/ops/nixos/nausicaa/default.nix new file mode 100644 index 0000000000..64d7f26990 --- /dev/null +++ b/ops/nixos/nausicaa/default.nix @@ -0,0 +1,309 @@ +# SPDX-FileCopyrightText: 2024 Luke Granger-Brown +# +# SPDX-License-Identifier: Apache-2.0 + +{ depot, lib, pkgs, config, ... }: +let + inherit (depot.ops) secrets; +in { + imports = [ + ../lib/zfs.nix + ../lib/graphical-client-wayland.nix + ../lib/plasma.nix + ../lib/whitby-distributed.nix + ../lib/quadv-ca/default.nix + ((import ../../../third_party/lanzaboote.nix { }).nixosModules.lanzaboote) + ]; + + boot = lib.mkMerge [{ + initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + "rtsx_pci_sdmmc" + ]; + initrd.kernelModules = [ "amdgpu" ]; + kernelModules = [ "kvm-amd" ]; + supportedFilesystems = [ "ntfs" ]; + kernel.sysctl = { + "abi.vsyscall32" = "0"; + }; + + # We're using Lanzaboote, so no systemd-boot. + lanzaboote = { + enable = true; + pkiBundle = "/etc/secureboot"; + settings = { + reboot-for-bitlocker = true; + editor = false; + }; + }; + loader.efi.canTouchEfiVariables = true; + + initrd.systemd.enable = true; + + binfmt.emulatedSystems = [ "aarch64-linux" ]; + + kernelParams = [ "amd_pstate=active" ]; + } (lib.mkIf (lib.versionOlder config.boot.kernelPackages.kernel.version "6.8") { + kernelParams = [ + # Scatter/Gather causes display flickering + "amdgpu.sg_display=0" + + # SuspendThenHibernate workaround + "rtc_cmos.use_acpi_alarm=1" + ]; + })]; + + my.rundeck.expectedOnline = false; + + fileSystems = let + zfs = device: { + device = device; + fsType = "zfs"; + }; + in { + "/" = zfs "zpool/local/root"; + "/nix" = zfs "zpool/local/nix"; + "/tmp" = zfs "zpool/local/tmp"; + + "/var" = zfs "zpool/safe/var"; + "/home" = zfs "zpool/safe/home"; + "/persist" = zfs "zpool/safe/persist"; + + "/boot" = { + device = "/dev/disk/by-label/NIXBOOT"; + fsType = "vfat"; + }; + }; + + nix.settings.max-jobs = lib.mkDefault 12; + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + hardware.enableRedistributableFirmware = true; + + # Laptop, don't autodeploy. + my.deploy.enable = false; + + # ZFS! + services.zfs.rollbackOnBoot.enable = true; + + # Enable Podman + virtualisation.podman = { + enable = true; + dockerCompat = true; + }; + + # Enable LXD + virtualisation.lxd = { + enable = false; + zfsSupport = true; + recommendedSysctlSettings = true; + }; + systemd.services.lxd.serviceConfig.path = lib.mkAfter (with pkgs; [ + iptables + ebtables + ]); + + # Enable libvirtd. + virtualisation.libvirtd = { + enable = true; + qemu = { + swtpm.enable = true; + ovmf.packages = [ + pkgs.OVMFFull.fd + ]; + }; + }; + security.polkit.enable = true; + + networking.hostName = "nausicaa"; + networking.domain = "int.as205479.net"; + networking.hostId = "db370a50"; + + # Boot faster. + systemd.services.systemd-udev-settle.enable = false; + systemd.services.NetworkManager-wait-online.enable = false; + + networking.networkmanager = { + enable = true; + wifi.backend = "iwd"; + }; + #my.ip.tailscale = "100.125.26.108"; + #my.ip.tailscale6 = "fd7a:115c:a1e0:ab12:4843:cd96:627d:1a6c"; + + # Set your time zone. + time.timeZone = "Europe/London"; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + sbctl + pciutils + deluge + (writeShellScriptBin "windows" '' + set -ue + if [[ $EUID -ne 0 ]]; then + exec sudo "$0" "$@" + fi + + efibootmgr -n 0001 + systemctl reboot + '') + ]; + + # Enable CUPS to print documents. + services.printing.enable = true; + services.printing.drivers = with depot.pkgs; [ intermec-cups-driver ]; + + # Enable the X11 windowing system. + services.xserver = { + enable = true; + layout = "us"; + libinput.enable = true; + windowManager.i3.enable = true; + videoDrivers = [ "modesetting" ]; + }; + services.xserver.displayManager = { + sddm = { + enable = true; + settings = { + General.DisplayServer = "wayland"; + Users.HideUsers = "deployer"; + }; + }; + defaultSession = "plasmawayland"; + }; + + hardware.opengl.driSupport32Bit = true; + hardware.acpilight.enable = true; + hardware.bluetooth.enable = true; + hardware.sensor.iio.enable = true; + services.fprintd.enable = true; + + services.udev.extraRules = '' + # Ethernet expansion card support + ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0bda", ATTR{idProduct}=="8156", ATTR{power/autosuspend}="20" + ''; + + # Define a user account. + programs.adb.enable = true; + users.users.lukegb = { + extraGroups = [ "wheel" "networkmanager" "libvirtd" "lxd" "video" "dialout" "adbusers" ]; + }; + my.home-manager.system = {...}: { + home.packages = lib.mkAfter (with pkgs; [ + steam + (writeScriptBin "javaws" '' + #!/bin/sh + exec ${depot.nix.pkgs.javaws-env}/bin/javaws-env "$@" + '') + factorio-experimental + (depot.nix.pkgs.secretsync.configure { + workingDir = "/home/lukegb/depot"; + gitlabAccessToken = secrets.deployer.gitlabAccessToken; + manifestVariable = "SECRETS_MANIFEST"; + variablesToFile = { + "OPS_SECRETS_DEFAULT_NIX" = "ops/secrets/default.nix"; + }; + }) + efibootmgr + iw + obs-studio + vulkan-tools + ]); + }; + + # Things to persist. + services.openssh.hostKeys = [ + { + path = "/persist/etc/ssh/ssh_host_ed25519_key"; + type = "ed25519"; + } + { + path = "/persist/etc/ssh/ssh_host_rsa_key"; + type = "rsa"; + bits = 4096; + } + ]; + environment.etc = { + "nixos" = { source = "/persist/etc/nixos/"; }; + "secureboot" = { source = "/persist/etc/secureboot/"; }; + }; + systemd.tmpfiles.rules = [ + #"L /etc/nixos - - - - /persist/etc/nixos" + "d /var/lib/libvirt 0755 root - - -" + "d /persist/etc/nixos 0700 root - - -" + "d /persist/etc/secureboot 0700 root - - -" + ]; + systemd.mounts = let + bindMount' = dir: { + unitConfig.RequiresMountsFor = dir; + options = "bind"; + what = "/persist${dir}"; + where = dir; + }; + bindMountSvc = dir: svc: target: (bindMount' dir) // { + bindsTo = [svc]; + partOf = [svc]; + before = [svc]; + wantedBy = [target]; + }; + bindMount = dir: (bindMount' dir) // { + wantedBy = ["multi-user.target"]; + }; + in [ + (bindMountSvc "/var/lib/libvirt" "libvirtd.service" "multi-user.target") + (bindMountSvc "/etc/NetworkManager/system-connections" "NetworkManager.service" "network.target") + (bindMount "/root") + ]; + + # Enable Thunderbolt device management. + services.hardware.bolt.enable = true; + + services.redis.servers."".enable = true; + services.postgresql.enable = true; + services.postgresql.ensureDatabases = [ "lukegb" ]; + services.postgresql.ensureUsers = [{ + name = "lukegb"; + ensurePermissions = { + "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES"; + "DATABASE lukegb" = "ALL PRIVILEGES"; + }; + }]; + services.postgresql.authentication = '' + local all all trust + host all all 127.0.0.1/32 trust + host all all ::1/128 trust + ''; + + nix.buildMachines = [ { + hostName = "totoro"; + system = "x86_64-linux"; + maxJobs = 4; + speedFactor = 2; + supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; + mandatoryFeatures = [ ]; + }]; + + hardware.cpu.amd.updateMicrocode = true; + services.power-profiles-daemon.enable = true; + + my.scrapeJournal.enable = false; # Laptop, don't pull too much. + + services.avahi = { + enable = true; + openFirewall = true; + }; + services.lldpd = { + enable = true; + }; + + # This value determines the NixOS release with which your system is to be + # compatible, in order to avoid breaking some software such as database + # servers. You should change this only after NixOS release notes say you + # should. + system.stateVersion = "24.05"; # Did you read the comment? +} diff --git a/ops/vault/cfg/config.nix b/ops/vault/cfg/config.nix index 21489837b6..a95dbc72f4 100644 --- a/ops/vault/cfg/config.nix +++ b/ops/vault/cfg/config.nix @@ -76,6 +76,7 @@ my.servers.etheroute-lon01.apps = [ "pomerium" ]; my.servers.howl.apps = [ "nixbuild" ]; my.servers.porcorosso.apps = [ "quotesdb" "nixbuild" ]; + my.servers.nausicaa.apps = [ "quotesdb" "nixbuild" ]; my.servers.totoro.apps = [ "sslrenew-raritan" "deluge" "quotesdb" "authentik" "ads-b" "nixbuild" "tumblrandom" ]; my.servers.clouvider-fra01.apps = [ "deluge" ]; my.servers.clouvider-lon01.apps = [ "quotesdb" "gitlab-runner" "nixbuild" ]; diff --git a/third_party/default.nix b/third_party/default.nix index fa33d805e9..cc1c656e71 100644 --- a/third_party/default.nix +++ b/third_party/default.nix @@ -131,4 +131,6 @@ rec { crate2nix = import "${crate2nixSrc}" { pkgs = ch.depot.pkgs; }; poetry2nix = import "${poetry2nixSrc}" { pkgs = ch.depot.pkgs; }; + + lanzaboote = import ./lanzaboote.nix { pkgs = nixpkgs; }; } diff --git a/third_party/lanzaboote.nix b/third_party/lanzaboote.nix new file mode 100644 index 0000000000..72b4b50c26 --- /dev/null +++ b/third_party/lanzaboote.nix @@ -0,0 +1,77 @@ +{ pkgs ? import ./nixpkgs { } }: +let + flakify = f: src: f // { outPath = src; }; + + src = pkgs.fetchFromGitHub { + owner = "nix-community"; + repo = "lanzaboote"; + rev = "614b538f0fcd4eda423abc36819a57eb4b241b1b"; + hash = "sha256:0m94c82yqvfz7y3wv9r3qxqp4w68swhd0q35ni4r84r163cbah31"; + }; + + flake-parts-src = pkgs.fetchFromGitHub { + owner = "hercules-ci"; + repo = "flake-parts"; + rev = "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f"; + hash = "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg="; + }; + flake-parts-flake = import "${flake-parts-src}/flake.nix"; + flake-parts = flake-parts-flake.outputs { + nixpkgs-lib = pkgs; + }; + + nix-systems-src = pkgs.fetchFromGitHub { + owner = "nix-systems"; + repo = "default"; + rev = "da67096a3b9bf56a91d16901293e51ba5b49a27e"; + hash = "sha256:1bzg89hgcr2gvza35vqi4n1jbb2gz1yg4b8p7gry4ihsj2mnnbap"; + }; + + flake-utils-src = pkgs.fetchFromGitHub { + owner = "numtide"; + repo = "flake-utils"; + rev = "1ef2e671c3b0c19053962c07dbda38332dcebf26"; + hash = "sha256:0843cqkssadi6wm2xqrprln839cjh4ddacpz1f8j09x628sm3m5q"; + }; + flake-utils = (import "${flake-utils-src}/flake.nix").outputs { + self = flake-utils; + systems = nix-systems-src; + }; + + rust-overlay-src = pkgs.fetchFromGitHub { + owner = "oxalica"; + repo = "rust-overlay"; + rev = "e0626adabd5ea461f80b1b11390da2a6575adb30"; + hash = "sha256:0syfyblhbmbnrzbn9yblxj4jyf0cr7yq9lqjcjh8xqdljgm544x0"; + }; + rust-overlay-flake = import "${rust-overlay-src}/flake.nix"; + rust-overlay = rust-overlay-flake.outputs { + self = rust-overlay; + nixpkgs = pkgs; + flake-utils = flake-utils; + }; + + crane-src = pkgs.fetchFromGitHub { + owner = "ipetkov"; + repo = "crane"; + rev = "v0.12.0"; + hash = "sha256:0znn7rhg5141v9sdmsain4z02cky2xkp5yibm5790rsg0sdp0i50"; + }; + crane = (import "${crane-src}/flake.nix").outputs { + nixpkgs = flakify pkgs ./nixpkgs; + inherit flake-utils rust-overlay; + }; + + flakeInputs = { + self = flakeEval; + nixpkgs = ./nixpkgs; + crane = crane; + rust-overlay = rust-overlay; + inherit flake-parts; + pre-commit-hooks-nix = null; + }; + flakeEval = flake.outputs flakeInputs; + + flake = import "${src}/flake.nix"; +in + flakeEval