This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

machines.atlas: init stateless sway machine with iso and netboot images

+194
+79
machines/atlas/config.nix
··· 1 + { 2 + self, 3 + config, 4 + pkgs, 5 + lib, 6 + ... 7 + }: 8 + { 9 + imports = [ 10 + ../../2configs 11 + ../../2configs/desktops/sway/default.nix 12 + ../../2configs/pipewire.nix 13 + ../../2configs/network-manager.nix 14 + self.wrapperModules.workspace-manager 15 + ]; 16 + 17 + krebs.build.host.name = "atlas"; 18 + system.stateVersion = "25.05"; 19 + 20 + lass.workspace-manager.enable = true; 21 + 22 + nix.settings.trusted-users = [ 23 + "root" 24 + "lass" 25 + ]; 26 + 27 + # Autostart straight into sway: greetd logs the main user in on boot with no 28 + # prompt and execs sway (a login shell so the wrapped sway + session env from 29 + # programs.sway are on PATH). default_session with a real user means every 30 + # (re)start goes directly into the session — there is no greeter. 31 + services.greetd = { 32 + enable = true; 33 + settings.default_session = { 34 + command = "${lib.getExe pkgs.bash} --login -c sway"; 35 + user = config.users.users.mainUser.name; 36 + }; 37 + }; 38 + 39 + # Stateless box: no password/credential is baked into the image, so a screen 40 + # lock could never be unlocked (swaylock PAM has nothing to accept). Disable 41 + # the desktop's idle auto-lock (swayidle: lock after 120s, suspend-then- 42 + # hibernate after 300s) and the lock service itself. The $mod+l / $mod+F11 43 + # lock keybinds then start an empty lock.target and harmlessly do nothing. 44 + systemd.user.services.swayidle.enable = lib.mkForce false; 45 + systemd.user.services.swaylock.enable = lib.mkForce false; 46 + 47 + # Noctalia pops a one-time "Privacy Update" telemetry wizard whenever its 48 + # cache (~/.cache/noctalia/shell-state.json) has an empty 49 + # changelogState.lastSeenVersion (UpdateService.shouldShowTelemetryWizard, 50 + # gated only on that cache — not on any setting). This box is stateless, so 51 + # the cache is wiped every boot and the wizard returned on every start. 52 + # Seed the cache before noctalia launches with the current version, so it 53 + # treats the changelog/telemetry notice as already seen (and, since 54 + # lastSeen == currentVersion, the changelog stays closed too). 55 + systemd.user.services.noctalia-seed-state = { 56 + description = "Seed noctalia changelog cache (suppress telemetry wizard on stateless boots)"; 57 + partOf = [ "sway-session.target" ]; 58 + wantedBy = [ "noctalia-shell.service" ]; 59 + before = [ "noctalia-shell.service" ]; 60 + serviceConfig = { 61 + Type = "oneshot"; 62 + RemainAfterExit = true; 63 + ExecStart = pkgs.writeShellScript "noctalia-seed-state" '' 64 + set -eu 65 + dir="''${XDG_CACHE_HOME:-$HOME/.cache}/noctalia" 66 + f="$dir/shell-state.json" 67 + ver="v${pkgs.noctalia-shell.version}" 68 + mkdir -p "$dir" 69 + if [ -s "$f" ]; then 70 + ${pkgs.jq}/bin/jq --arg v "$ver" \ 71 + '.changelogState.lastSeenVersion = (if (.changelogState.lastSeenVersion // "") == "" then $v else .changelogState.lastSeenVersion end)' \ 72 + "$f" > "$f.tmp" && mv "$f.tmp" "$f" 73 + else 74 + ${pkgs.jq}/bin/jq -n --arg v "$ver" '{changelogState:{lastSeenVersion:$v}}' > "$f" 75 + fi 76 + ''; 77 + }; 78 + }; 79 + }
+115
machines/atlas/physical.nix
··· 1 + { 2 + modulesPath, 3 + pkgs, 4 + lib, 5 + ... 6 + }: 7 + { 8 + imports = [ 9 + ./config.nix 10 + (modulesPath + "/installer/scan/not-detected.nix") 11 + # Two boot media from one config. Every entry in image.modules is applied 12 + # to this config through its own extendModules, so the iso and netboot 13 + # variants never see each other's fileSystems / bootloader definitions — 14 + # no disabledModules or mkForce juggling needed. 15 + # 16 + # nixos-rebuild build-image --flake .#atlas --image-variant iso 17 + # nix build .#nixosConfigurations.atlas.config.system.build.images.iso 18 + # nix build .#atlas-netboot-root (kernel+initrd+ipxe for PXE) 19 + (modulesPath + "/image/images.nix") 20 + ]; 21 + 22 + # Deliberately no image module at the toplevel: nixpkgs warns that doing so 23 + # defines system.build.image and leaks the medium into every variant. That 24 + # leaves the base config without a real boot medium, so these two 25 + # placeholders exist only to let it evaluate; both image variants override 26 + # the root with mkImageMediaOverride (priority 60), which wins over these. 27 + # The base toplevel itself is never booted or deployed. 28 + fileSystems."/" = { 29 + device = "tmpfs"; 30 + fsType = "tmpfs"; 31 + }; 32 + boot.loader.grub.enable = lib.mkDefault false; 33 + 34 + # Live USB stick: store is a squashfs on the stick, root a tmpfs overlay on 35 + # top. Stateless, nothing installed — dd it and boot. 36 + # 37 + # The built-in `iso` variant is iso-image.nix (not installation-cd-base): 38 + # no nixos channel, no installer profile, no `nixos` autologin to fight 39 + # greetd or clash with 2configs/pinned-registry.nix. Settings here merge 40 + # into it, since image.modules is an attrsOf deferredModule. 41 + image.modules.iso = { 42 + # zstd keeps the squashfs small without a slow xz build. 43 + isoImage.squashfsCompression = "zstd -Xcompression-level 6"; 44 + isoImage.makeEfiBootable = true; 45 + isoImage.makeUsbBootable = true; 46 + image.baseName = lib.mkForce "atlas"; 47 + image.fileName = lib.mkForce "atlas.iso"; 48 + }; 49 + 50 + # PXE/netboot: iPXE pulls bzImage + initrd, so nothing has to be flashed to 51 + # iterate. The whole store rides inside the initrd (~3.8 GB), which is why 52 + # it has to be served over HTTP rather than TFTP — see nat-share --pxe/--http. 53 + image.modules.netboot = { 54 + imports = [ (modulesPath + "/installer/netboot/netboot.nix") ]; 55 + netboot.squashfsCompression = "zstd -Xcompression-level 6"; 56 + }; 57 + 58 + nixpkgs.hostPlatform = "x86_64-linux"; 59 + 60 + boot.kernelPackages = pkgs.linuxPackages_latest; 61 + 62 + # AMD Radeon (Navi 14 / RX 5500-class, PCI 1002:7340) -> amdgpu. 63 + # 64 + # amdgpu is deliberately NOT in boot.initrd.kernelModules: early-loading it 65 + # tears down efifb before the GPU firmware is available in stage-1, which 66 + # black-screens this card from the moment the kernel starts (measured: ~5min 67 + # to reach systemd). Let udev load amdgpu in stage-2, where the firmware is 68 + # present. hardware.amdgpu.initrd.enable is the same trap — it only adds the 69 + # module and handles no firmware. 70 + hardware.graphics.enable = true; 71 + hardware.graphics.enable32Bit = true; 72 + hardware.enableRedistributableFirmware = true; 73 + services.xserver.videoDrivers = [ "amdgpu" ]; 74 + boot.kernelModules = [ "kvm-intel" ]; 75 + 76 + # Boot the live image off a USB mass-storage device. (Inert for netboot, 77 + # where iPXE has already fetched kernel+initrd before the kernel starts.) 78 + boot.initrd.availableKernelModules = [ 79 + "xhci_pci" 80 + "ehci_pci" 81 + "ahci" 82 + "usb_storage" 83 + "uas" 84 + "usbhid" 85 + "sd_mod" 86 + ]; 87 + 88 + # Initrd size dominates boot for both media: GRUB reads it off USB at 89 + # roughly 1 MB/s (measured: 59s loader phase vs 6.5s kernel + 4.5s initrd + 90 + # 10s userspace), and for netboot it travels with the store image. 91 + # 92 + # It was 29 MB compressed / 83 MB unpacked, of which only 1.8 MB was kernel 93 + # modules — the rest was the systemd-initrd closure (openssl, lvm2, 94 + # cryptsetup, tpm2-tss, curl, krb5, bash-interactive). Stage 1 only has to 95 + # find the boot medium and mount squashfs+overlay: no LUKS, no LVM, no TPM, 96 + # no network. The scripted initrd drops that closure: 29 MB -> 11 MB. 97 + boot.initrd.systemd.enable = lib.mkForce false; 98 + boot.initrd.systemd.emergencyAccess = lib.mkForce false; 99 + boot.initrd.services.lvm.enable = lib.mkForce false; 100 + 101 + # Name the onboard Intel NIC deterministically. 102 + services.udev.extraRules = '' 103 + SUBSYSTEM=="net", ATTR{address}=="70:85:c2:0e:ea:3c", NAME="et0" 104 + ''; 105 + 106 + # Stateless box: no clan secrets are deployed, so don't try to load an 107 + # openssh host key from a vars path that will never exist on the live 108 + # system. Let sshd generate an ephemeral key at boot instead. 109 + services.openssh.hostKeys = lib.mkForce [ 110 + { 111 + path = "/etc/ssh/ssh_host_ed25519_key"; 112 + type = "ed25519"; 113 + } 114 + ]; 115 + }