diff --git a/nix/configuration/flake.nix b/nix/configuration/flake.nix index e2ecd21c..8be7c10b 100644 --- a/nix/configuration/flake.nix +++ b/nix/configuration/flake.nix @@ -60,6 +60,9 @@ hydra = { system = "x86_64-linux"; }; + family_disks = { + system = "x86_64-linux"; + }; }; nixosConfigs = builtins.mapAttrs ( hostname: nodeConfig: format: diff --git a/nix/configuration/hosts/family_disks/DEPLOY_BOOT b/nix/configuration/hosts/family_disks/DEPLOY_BOOT new file mode 100755 index 00000000..c9a277d8 --- /dev/null +++ b/nix/configuration/hosts/family_disks/DEPLOY_BOOT @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" + +TARGET=family_disks + +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done + +nixos-rebuild boot --flake "$DIR/../../#family_disks" --target-host "$TARGET" --build-host "$TARGET" --sudo --max-jobs "$JOBS" --log-format internal-json -v "${@}" |& nom --json diff --git a/nix/configuration/hosts/family_disks/DEPLOY_SWITCH b/nix/configuration/hosts/family_disks/DEPLOY_SWITCH new file mode 100755 index 00000000..1127ca93 --- /dev/null +++ b/nix/configuration/hosts/family_disks/DEPLOY_SWITCH @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" + +TARGET=family_disks + +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done + +nixos-rebuild switch --flake "$DIR/../../#family_disks" --target-host "$TARGET" --build-host "$TARGET" --sudo --max-jobs "$JOBS" --log-format internal-json -v "${@}" |& nom --json diff --git a/nix/configuration/hosts/family_disks/ISO b/nix/configuration/hosts/family_disks/ISO new file mode 100755 index 00000000..9b32e0ca --- /dev/null +++ b/nix/configuration/hosts/family_disks/ISO @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" + +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done +nix build --extra-experimental-features nix-command --extra-experimental-features flakes "$DIR/../..#family_disks.iso" --max-jobs "$JOBS" --log-format internal-json -v "${@}" |& nom --json diff --git a/nix/configuration/hosts/family_disks/SELF_BOOT b/nix/configuration/hosts/family_disks/SELF_BOOT new file mode 100755 index 00000000..e1213f7b --- /dev/null +++ b/nix/configuration/hosts/family_disks/SELF_BOOT @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" + +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done +nixos-rebuild boot --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#family_disks" --log-format internal-json -v "${@}" |& nom --json diff --git a/nix/configuration/hosts/family_disks/SELF_BUILD b/nix/configuration/hosts/family_disks/SELF_BUILD new file mode 100755 index 00000000..e7c691b7 --- /dev/null +++ b/nix/configuration/hosts/family_disks/SELF_BUILD @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" +: "${NOM:="true"}" + +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done + +nixos-rebuild build --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#family_disks" --log-format internal-json -v "${@}" |& nom --json diff --git a/nix/configuration/hosts/family_disks/SELF_SWITCH b/nix/configuration/hosts/family_disks/SELF_SWITCH new file mode 100755 index 00000000..ce665404 --- /dev/null +++ b/nix/configuration/hosts/family_disks/SELF_SWITCH @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" + +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done +nixos-rebuild switch --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#family_disks" --log-format internal-json -v "${@}" |& nom --json diff --git a/nix/configuration/hosts/family_disks/default.nix b/nix/configuration/hosts/family_disks/default.nix new file mode 100644 index 00000000..2651b37a --- /dev/null +++ b/nix/configuration/hosts/family_disks/default.nix @@ -0,0 +1,75 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + imports = [ + ./hardware-configuration.nix + ./wrapped-disk-config.nix + ./distributed_build.nix + ./power_management.nix + ]; + + config = { + # Generate with `head -c4 /dev/urandom | od -A none -t x4` + networking.hostId = "908cbf04"; + + networking.hostName = "family_disks"; # Define your hostname. + + time.timeZone = "America/New_York"; + i18n.defaultLocale = "en_US.UTF-8"; + + me.boot.enable = true; + me.boot.secure = false; + me.mountPersistence = true; + + # Toggle to start writing the extlinux config which will be used by zfsbootmenu + boot.loader.generic-extlinux-compatible.enable = true; + boot.loader.systemd-boot.enable = lib.mkForce false; + + me.rollback.dataset = [ + "zroot/linux/nix/root@blank" + "zroot/linux/nix/home@blank" + ]; + + me.optimizations = { + enable = true; + arch = "skylake"; + # build_arch = "x86-64-v3"; + system_features = [ + "gccarch-znver4" + "gccarch-skylake" + "gccarch-kabylake" + # "gccarch-alderlake" missing WAITPKG + "gccarch-x86-64-v3" + "gccarch-x86-64-v4" + "benchmark" + "big-parallel" + "kvm" + "nixos-test" + ]; + }; + + # Early KMS + # boot.initrd.kernelModules = [ "amdgpu" ]; + + # Mount tmpfs at /tmp + boot.tmp.useTmpfs = true; + + # Enable light sensor + # hardware.sensor.iio.enable = lib.mkDefault true; + + # Enable TRIM + # services.fstrim.enable = lib.mkDefault true; + + # Only run nix builders at idle priority for a more responsive system. Do not set on servers, just end-user devices. + nix.daemonCPUSchedPolicy = "idle"; + + me.build_in_ram.enable = true; + me.dont_use_substituters.enable = true; + me.minimal_base.enable = true; + me.recovery.enable = true; + }; +} diff --git a/nix/configuration/hosts/family_disks/disk-config.nix b/nix/configuration/hosts/family_disks/disk-config.nix new file mode 100644 index 00000000..0236f877 --- /dev/null +++ b/nix/configuration/hosts/family_disks/disk-config.nix @@ -0,0 +1,155 @@ +# Manual Step: +# Check if drive supports 4kn: nvme id-ns -H /dev/nvme0n1 +# Format the drive to 4kn: nvme format --lbaf=1 /dev/nvme0n1 + +{ + disko.devices = { + disk = { + main = { + type = "disk"; + device = "/dev/nvme0n1"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/efi"; + mountOptions = [ + "umask=0077" + "noatime" + "discard" + ]; + }; + }; + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; + }; + }; + zpool = { + zroot = { + type = "zpool"; + # mode = "mirror"; + # Workaround: cannot import 'zroot': I/O error in disko tests + options.cachefile = "none"; + options = { + ashift = "12"; + compatibility = "openzfs-2.2-freebsd"; + autotrim = "on"; + }; + rootFsOptions = { + acltype = "posixacl"; + atime = "off"; + relatime = "off"; + xattr = "sa"; + mountpoint = "none"; + compression = "lz4"; + canmount = "off"; + utf8only = "on"; + dnodesize = "auto"; + normalization = "formD"; + }; + + datasets = { + "linux/nix" = { + type = "zfs_fs"; + options.mountpoint = "none"; + options = { + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + # keylocation = "file:///tmp/secret.key"; + }; + }; + "linux/nix/root" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/root@blank$' || zfs snapshot zroot/linux/nix/root@blank"; + }; + "linux/nix/boot" = { + type = "zfs_fs"; + options = { + mountpoint = "legacy"; + "org.zfsbootmenu:active" = "on"; + }; + mountpoint = "/boot"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/boot@blank$' || zfs snapshot zroot/linux/nix/boot@blank"; + }; + "linux/nix/nix" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/nix"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/nix@blank$' || zfs snapshot zroot/linux/nix/nix@blank"; + options = { + recordsize = "16MiB"; + compression = "zstd-19"; + }; + }; + "linux/nix/home" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/home"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/home@blank$' || zfs snapshot zroot/linux/nix/home@blank"; + }; + "linux/nix/persist" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/persist"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/persist@blank$' || zfs snapshot zroot/linux/nix/persist@blank"; + }; + "linux/nix/state" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/state"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/state@blank$' || zfs snapshot zroot/linux/nix/state@blank"; + }; + }; + }; + }; + }; + + # Make sure all persistent volumes are marked as neededForBoot + # + # Also mounts /home so it is mounted before the user home directories are created. + fileSystems."/persist".neededForBoot = true; + fileSystems."/state".neededForBoot = true; + fileSystems."/home".neededForBoot = true; + + fileSystems."/".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/boot".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/nix".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/persist".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/state".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/home".options = [ + "noatime" + "norelatime" + ]; + + # Only attempt to decrypt the main pool. Otherwise it attempts to decrypt pools that aren't even used. + boot.zfs.requestEncryptionCredentials = [ "zroot/linux/nix" ]; +} diff --git a/nix/configuration/hosts/family_disks/distributed_build.nix b/nix/configuration/hosts/family_disks/distributed_build.nix new file mode 100644 index 00000000..723f54a0 --- /dev/null +++ b/nix/configuration/hosts/family_disks/distributed_build.nix @@ -0,0 +1,19 @@ +{ + imports = [ ]; + + config = { + me.distributed_build.enable = true; + me.distributed_build.machines.quark = { + enable = false; + additional_config = { + speedFactor = 2; + }; + }; + me.distributed_build.machines.hydra = { + enable = true; + additional_config = { + speedFactor = 2; + }; + }; + }; +} diff --git a/nix/configuration/hosts/family_disks/hardware-configuration.nix b/nix/configuration/hosts/family_disks/hardware-configuration.nix new file mode 100644 index 00000000..c87dfa52 --- /dev/null +++ b/nix/configuration/hosts/family_disks/hardware-configuration.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + modulesPath, + ... +}: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + config = { + boot.initrd.availableKernelModules = [ + "nvme" + "xhci_pci" + "thunderbolt" + ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + # 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.eno1.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp58s0.useDHCP = lib.mkDefault true; + + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + }; +} diff --git a/nix/configuration/hosts/family_disks/power_management.nix b/nix/configuration/hosts/family_disks/power_management.nix new file mode 100644 index 00000000..b6d3fefb --- /dev/null +++ b/nix/configuration/hosts/family_disks/power_management.nix @@ -0,0 +1,75 @@ +{ + pkgs, + ... +}: + +{ + imports = [ ]; + + config = { + environment.systemPackages = with pkgs; [ + powertop + ]; + + # amdgpu.abmlevel=3 :: Automatically reduce screen brightness but tweak colors to compensate for power reduction. + # pcie_aspm=force pcie_aspm.policy=powersupersave :: Enable PCIe active state power management for power reduction. + # nowatchdog :: Disable watchdog for power savings (related to disable_sp5100_watchdog above). + # amd_pstate=passive :: Fully automated hardware pstate control. + # amd_pstate=active :: Same as passive except we can set the energy performance preference (EPP) to suggest how much we prefer performance or energy efficiency. + # amd_pstate=guided :: Same as passive except we can set upper and lower frequency bounds. + # amdgpu.dcdebugmask=0x10 :: Allegedly disables Panel Replay from https://community.frame.work/t/tracking-freezing-arch-linux-amd/39495/32 + boot.kernelParams = [ + "amdgpu.abmlevel=2" + "pcie_aspm=force" + # "pcie_aspm.policy=powersupersave" + "nowatchdog" + # I don't see a measurable benefit from these two: + # "cpufreq.default_governor=powersave" + # "initcall_blacklist=cpufreq_gov_userspace_init" + ]; + + systemd.tmpfiles.rules = [ + "w- /sys/firmware/acpi/platform_profile - - - - low-power" + "w- /sys/devices/system/cpu/cpufreq/policy0/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy1/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy2/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy3/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy4/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy5/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy6/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy7/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy8/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy9/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy10/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy11/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy12/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy13/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy14/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpufreq/policy15/energy_performance_preference - - - - power" + "w- /sys/devices/system/cpu/cpu0/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu1/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu2/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu3/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu4/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu5/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu6/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu7/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu8/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu9/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu10/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu11/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu12/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu13/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu14/cpufreq/boost - - - - 0" + "w- /sys/devices/system/cpu/cpu15/cpufreq/boost - - - - 0" + ]; + + boot.extraModprobeConfig = '' + # Disable the hardware watchdog inside AMD 700 chipset series for power savings. + blacklist sp5100_tco + + # Sound power-saving was causing chat notifications to be inaudible. + # options snd_hda_intel power_save=1 + ''; + }; +} diff --git a/nix/configuration/hosts/family_disks/wrapped-disk-config.nix b/nix/configuration/hosts/family_disks/wrapped-disk-config.nix new file mode 100644 index 00000000..39e74f47 --- /dev/null +++ b/nix/configuration/hosts/family_disks/wrapped-disk-config.nix @@ -0,0 +1,7 @@ +{ + config, + lib, + ... +}: + +lib.mkIf (!config.me.buildingPortable) (import ./disk-config.nix) diff --git a/nix/configuration/hosts/odo/SELF_BUILD b/nix/configuration/hosts/odo/SELF_BUILD index 4dae4a98..21c8f048 100755 --- a/nix/configuration/hosts/odo/SELF_BUILD +++ b/nix/configuration/hosts/odo/SELF_BUILD @@ -9,8 +9,4 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done -if [ "$NOM" = "true" ]; then - nixos-rebuild build --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#odo" --log-format internal-json -v "${@}" |& nom --json -else - nixos-rebuild build --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#odo" -v "${@}" -fi +nixos-rebuild build --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#odo" --log-format internal-json -v "${@}" |& nom --json diff --git a/nix/configuration/roles/hydra/default.nix b/nix/configuration/roles/hydra/default.nix index 9713f739..6341c163 100644 --- a/nix/configuration/roles/hydra/default.nix +++ b/nix/configuration/roles/hydra/default.nix @@ -110,7 +110,7 @@ in IFS=$'\n\t' DIR="$( cd "$( dirname "''${BASH_SOURCE[0]}" )" && pwd )" - NIX_REMOTE='local?root=/home/nixworker/persist/root' RUST_BACKTRACE=1 RUST_LOG=nix_builder=DEBUG ${nix_builder}/bin/nix-builder build --config ${./files/nix_builder.toml} --target odo --target odo_update --target odowork --target odowork_update --target quark --target quark_update --target hydra --target hydra_update --target controller0 --target controller0_update --target controller1 --target controller1_update --target controller2 --target controller2_update --target worker0 --target worker0_update --target worker1 --target worker1_update --target worker2 --target worker2_update + NIX_REMOTE='local?root=/home/nixworker/persist/root' RUST_BACKTRACE=1 RUST_LOG=nix_builder=DEBUG ${nix_builder}/bin/nix-builder build --config ${./files/nix_builder.toml} --target odo --target odo_update --target odowork --target odowork_update --target quark --target quark_update --target hydra --target hydra_update --target controller0 --target controller0_update --target controller1 --target controller1_update --target controller2 --target controller2_update --target worker0 --target worker0_update --target worker1 --target worker1_update --target worker2 --target worker2_update --target family_disks --target family_disks_update ''; restartIfChanged = false; serviceConfig = { diff --git a/nix/configuration/roles/hydra/files/nix_builder.toml b/nix/configuration/roles/hydra/files/nix_builder.toml index abdf243c..da1e243f 100644 --- a/nix/configuration/roles/hydra/files/nix_builder.toml +++ b/nix/configuration/roles/hydra/files/nix_builder.toml @@ -161,3 +161,19 @@ output_directory = "/home/nixworker/persist/nix_builder" update_branch = "kubernetes_update" # TODO: Add steam deck + +[[targets]] + name = "family_disks" + repo = "https://code.fizz.buzz/talexander/machine_setup.git" + branch = "family_disks" + path = "nix/configuration" + attr = "nixosConfigurations.family_disks.config.system.build.toplevel" + +[[targets]] + name = "family_disks_update" + repo = "https://code.fizz.buzz/talexander/machine_setup.git" + branch = "family_disks" + path = "nix/configuration" + attr = "nixosConfigurations.family_disks.config.system.build.toplevel" + update = true + update_branch = "nix_update"