Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d2379bb3e | ||
|
|
7a650dc7cc | ||
|
|
bb613ac803 | ||
|
|
47362090c3 | ||
|
|
8c5773447e | ||
|
|
ae44982c65 | ||
|
|
c82c1bef9c | ||
|
|
39b2b1d24b | ||
|
|
0022a152e3 | ||
|
|
d9db12c4a5 | ||
|
|
4ac9d1108b | ||
|
|
0c151943de | ||
|
|
dcb8a5e66a | ||
|
|
bdb21a6d50 | ||
|
|
1da34d6232 | ||
|
|
19e0b7f13f |
@@ -8,11 +8,10 @@ single flake.
|
|||||||
Defined in the host table in [`flake.nix`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/flake.nix):
|
Defined in the host table in [`flake.nix`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/flake.nix):
|
||||||
|
|
||||||
| Configuration | System | Machine |
|
| Configuration | System | Machine |
|
||||||
| --------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `lyrathorpe-mbp` | `aarch64-linux` | MacBook Pro (Apple Silicon, Asahi) |
|
| `lyrathorpe-mbp` | `aarch64-linux` | MacBook Pro (Apple Silicon, Asahi) |
|
||||||
| `lyrathorpe-t400` | `x86_64-linux` | ThinkPad T400 — [install notes](https://docs.lyrapup.pet/nixfiles/hosts/t400/) |
|
| `lyrathorpe-t400` | `x86_64-linux` | ThinkPad T400 — [install notes](https://docs.lyrapup.pet/nixfiles/hosts/t400/) |
|
||||||
| `lyrathorpe-macpro31` | `x86_64-linux` | Mac Pro 3,1, desktop — [install notes](https://docs.lyrapup.pet/nixfiles/hosts/macpro31/) |
|
| `lyrathorpe-macpro31` | `x86_64-linux` | Mac Pro 3,1, desktop — [install notes](https://docs.lyrapup.pet/nixfiles/hosts/macpro31/) |
|
||||||
| `lyrathorpe-console` | `x86_64-linux` | Living-room games machine (Haswell i7 + GTX 1070) on a television — [install notes](https://docs.lyrapup.pet/nixfiles/hosts/console/) |
|
|
||||||
| `emmathorpe-edaas` | `x86_64-linux` | Work WSL box (NixOS-WSL) — [notes](https://docs.lyrapup.pet/nixfiles/hosts/edaas/) |
|
| `emmathorpe-edaas` | `x86_64-linux` | Work WSL box (NixOS-WSL) — [notes](https://docs.lyrapup.pet/nixfiles/hosts/edaas/) |
|
||||||
| `lyrathorpe-rpi5` | `aarch64-linux` | Raspberry Pi 5 headless server: Docker host + nginx reverse proxy — [install notes](https://docs.lyrapup.pet/nixfiles/hosts/rpi5/) |
|
| `lyrathorpe-rpi5` | `aarch64-linux` | Raspberry Pi 5 headless server: Docker host + nginx reverse proxy — [install notes](https://docs.lyrapup.pet/nixfiles/hosts/rpi5/) |
|
||||||
| `lyrathorpe-mac` | `aarch64-darwin` | macOS (nix-darwin) — [notes](https://docs.lyrapup.pet/nixfiles/hosts/darwin/) |
|
| `lyrathorpe-mac` | `aarch64-darwin` | macOS (nix-darwin) — [notes](https://docs.lyrapup.pet/nixfiles/hosts/darwin/) |
|
||||||
|
|||||||
@@ -1,340 +0,0 @@
|
|||||||
# Console — living-room games machine
|
|
||||||
|
|
||||||
Flake host: `lyrathorpe-console`. Desktop (`portable = false`, imports
|
|
||||||
`../../modules/desktop.nix`). Files: `configuration.nix`, `nvidia.nix`,
|
|
||||||
`gaming.nix`, `hardware-configuration.nix`.
|
|
||||||
|
|
||||||
A 4th-generation Core i7 (Haswell) on a UEFI board with an NVIDIA GeForce GTX
|
|
||||||
1070 8 GB, wired to a television. It boots straight into Steam Big Picture and
|
|
||||||
is driven from the sofa with a Bluetooth controller; keyboard and mouse are
|
|
||||||
supported but secondary.
|
|
||||||
|
|
||||||
## Not installed yet
|
|
||||||
|
|
||||||
`hardware-configuration.nix` in this host directory is a **placeholder**, not a
|
|
||||||
hardware scan. It exists so the flake evaluates in CI and assumes the install
|
|
||||||
labels its partitions `nixos` (root, ext4) and `BOOT` (ESP, vfat). Replace the
|
|
||||||
whole file with the output of `nixos-generate-config` run on the machine and
|
|
||||||
commit that. If the labels do not match, the boot fails on a missing device
|
|
||||||
rather than touching the wrong disk.
|
|
||||||
|
|
||||||
Partition the disk GPT with an ESP (vfat, 512 MB is comfortable). Nothing else
|
|
||||||
in the host config depends on the disk layout.
|
|
||||||
|
|
||||||
## Bootloader
|
|
||||||
|
|
||||||
Ordinary PC UEFI firmware, so **systemd-boot** with
|
|
||||||
`canTouchEfiVariables = true` — unlike the Mac Pro, this board is trusted with
|
|
||||||
`efibootmgr` NVRAM writes.
|
|
||||||
|
|
||||||
`boot.loader.timeout = 0`: the boot menu is unreadable from a sofa and unusable
|
|
||||||
without a keyboard, so the default entry boots immediately. **Hold space at
|
|
||||||
power-on** to get the menu back and pick an older generation.
|
|
||||||
`configurationLimit = 10` stops the ESP filling up.
|
|
||||||
|
|
||||||
## Graphics — GTX 1070
|
|
||||||
|
|
||||||
Everything driver-related is in [`nvidia.nix`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/hosts/Console/nvidia.nix).
|
|
||||||
The GTX 1070 is Pascal (GP104), so it is under the same driver constraint as the
|
|
||||||
Mac Pro's Quadro P400:
|
|
||||||
|
|
||||||
- **Driver branch 580** (`nvidiaPackages.legacy_580`), _not_ the nixpkgs default
|
|
||||||
(`production`, currently 595.x). 580 is the last branch supporting
|
|
||||||
Maxwell/Pascal/Volta, maintained as an LTS branch until Aug 2028; a newer
|
|
||||||
branch does not drive this card at all.
|
|
||||||
- `modesetting.enable = true` — mandatory for Wayland. Without
|
|
||||||
`nvidia-drm.modeset=1` neither gamescope nor wlroots gets a usable GBM device,
|
|
||||||
and both the Steam session and Sway fail to start.
|
|
||||||
- `open = false` — the open kernel modules require Turing or later.
|
|
||||||
- Sway runs with `--unsupported-gpu`; wlroots refuses the proprietary driver
|
|
||||||
otherwise. gamescope and cage/ReGreet need no such flag.
|
|
||||||
- `hardware.graphics.enable32Bit` pulls in the lib32 NVIDIA userspace that
|
|
||||||
32-bit Steam titles and Proton's 32-bit prefixes link against.
|
|
||||||
|
|
||||||
The driver is unfree, so it is **not in the binary cache**: the kernel module is
|
|
||||||
compiled on the machine. On a Haswell i7 that is a few minutes, not the Mac
|
|
||||||
Pro's ordeal, but it recurs on every kernel bump. The package names are
|
|
||||||
allowlisted in `unfreePackages` in [`flake.nix`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/flake.nix).
|
|
||||||
|
|
||||||
Verify after a rebuild:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
nvidia-smi
|
|
||||||
lsmod | grep nvidia # nvidia, nvidia_modeset, nvidia_drm
|
|
||||||
```
|
|
||||||
|
|
||||||
## Session model — autologin into Steam
|
|
||||||
|
|
||||||
[`gaming.nix`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/hosts/Console/gaming.nix)
|
|
||||||
sets `programs.steam.gamescopeSession.enable`, which registers a `steam.desktop`
|
|
||||||
Wayland session (gamescope wrapping Steam in tenfoot mode) and installs a
|
|
||||||
`steam-gamescope` launcher. greetd — already present on every Sway host for
|
|
||||||
ReGreet, see [`../../modules/sway.nix`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/modules/sway.nix)
|
|
||||||
— gets an `initial_session` pointing at that launcher:
|
|
||||||
|
|
||||||
```
|
|
||||||
boot
|
|
||||||
└─ greetd initial_session (autologin as lyrathorpe)
|
|
||||||
└─ gamescope --steam -- steam -tenfoot -pipewire-dmabuf
|
|
||||||
├─ Steam library / Proton titles
|
|
||||||
├─ [non-Steam] RetroArch
|
|
||||||
└─ [non-Steam] Clone Hero
|
|
||||||
|
|
||||||
quit Steam → greetd default_session → ReGreet → pick Sway (keyboard + mouse)
|
|
||||||
```
|
|
||||||
|
|
||||||
So there is no greeter at boot and no keyboard needed. Quitting Steam drops back
|
|
||||||
to ReGreet, where the ordinary Sway session is available for everything else.
|
|
||||||
`services.greetd.restart` defaults to `false` once `initial_session` is set,
|
|
||||||
which is what stops a logout looping straight back into autologin.
|
|
||||||
|
|
||||||
Two details worth knowing:
|
|
||||||
|
|
||||||
- The launcher is referenced as `/run/current-system/sw/bin/steam-gamescope`.
|
|
||||||
The steam module builds that script privately and only adds it to
|
|
||||||
`environment.systemPackages`, so there is no package attribute to point at.
|
|
||||||
- `programs.gamescope.capSysNice = true` installs gamescope as a setcap wrapper
|
|
||||||
in `/run/wrappers/bin` instead of the system profile. That path precedes the
|
|
||||||
system profile on `PATH`, so `steam-gamescope` still resolves it.
|
|
||||||
|
|
||||||
The greeter is **Dvorak**, like every other host here (`modules/sway.nix` forces
|
|
||||||
`XKB_DEFAULT_VARIANT=dvorak` on cage). Only relevant if someone else has to type
|
|
||||||
a password.
|
|
||||||
|
|
||||||
### Adding RetroArch and Clone Hero to Big Picture
|
|
||||||
|
|
||||||
Both are installed system-wide but are not Steam titles. Add each once, from a
|
|
||||||
Sway session, via Steam's **Games → Add a Non-Steam Game**; they then appear in
|
|
||||||
Big Picture and inherit Steam Input, so the controller works in them without
|
|
||||||
further configuration.
|
|
||||||
|
|
||||||
## Emulation — RetroArch
|
|
||||||
|
|
||||||
`gaming.nix` builds RetroArch through `pkgs.retroarch-bare.wrapper`, which wires
|
|
||||||
up the packaged assets, core info and joypad autoconfig profiles. Cores:
|
|
||||||
|
|
||||||
| System | Core |
|
|
||||||
| -------------------------------------- | ------------------------ |
|
|
||||||
| NES | `nestopia` |
|
|
||||||
| SNES | `snes9x` |
|
|
||||||
| Game Boy / Color | `gambatte` |
|
|
||||||
| Game Boy Advance | `mgba` |
|
|
||||||
| Nintendo 64 | `mupen64plus` |
|
|
||||||
| Nintendo DS | `melonds` |
|
|
||||||
| GameCube / Wii | `dolphin` |
|
|
||||||
| Master System / Game Gear / Mega Drive | `genesis-plus-gx` |
|
|
||||||
| 32X / Mega CD | `picodrive` |
|
|
||||||
| Saturn | `beetle-saturn` |
|
|
||||||
| Dreamcast / NAOMI | `flycast` |
|
|
||||||
| PlayStation | `beetle-psx-hw` |
|
|
||||||
| PlayStation 2 | `pcsx2` (LRPS2) |
|
|
||||||
| PSP | `ppsspp` |
|
|
||||||
| Arcade | `fbneo`, `mame2003-plus` |
|
|
||||||
| DOS | `dosbox-pure` |
|
|
||||||
|
|
||||||
A handful of settings are applied on every launch via `--appendconfig`, so they
|
|
||||||
are fixed policy rather than saved preferences — changing them in the UI will
|
|
||||||
not stick. Everything else stays user-editable as normal.
|
|
||||||
|
|
||||||
- `menu_driver = ozone` — the controller-navigable menu.
|
|
||||||
- `video_fullscreen = true`.
|
|
||||||
- `input_menu_toggle_gamepad_combo = 2` — **L3+R3 opens the RetroArch menu**
|
|
||||||
from inside a running core. Without a pad combo there is no way to exit a game
|
|
||||||
without a keyboard. No retro system emulated here has L3/R3 on its own
|
|
||||||
controller, so the binding cannot collide with a game.
|
|
||||||
- `system_directory`, `savefile_directory`, `savestate_directory`,
|
|
||||||
`playlist_directory`, `screenshot_directory`, `thumbnails_directory` and
|
|
||||||
`rgui_browser_directory` — all pointed at the shared library described below,
|
|
||||||
rather than scattered through `~/.config/retroarch`.
|
|
||||||
|
|
||||||
An unrecognised key in an appended config is ignored **silently**, so those key
|
|
||||||
names are worth keeping in step with upstream if RetroArch is ever bumped
|
|
||||||
across a major version.
|
|
||||||
|
|
||||||
### BIOS files and expectations
|
|
||||||
|
|
||||||
Several cores need BIOS or firmware images that are not redistributable and are
|
|
||||||
therefore not packaged. Drop them in `/srv/games/bios`, which is RetroArch's
|
|
||||||
system directory on this host:
|
|
||||||
|
|
||||||
- **PlayStation 2** (`pcsx2`) — a PS2 BIOS dump. The core will not boot anything
|
|
||||||
without one.
|
|
||||||
- **Saturn** (`beetle-saturn`) — region BIOS images.
|
|
||||||
- **Dreamcast** (`flycast`) — `dc_boot.bin` / `dc_flash.bin` for most titles.
|
|
||||||
- **Nintendo DS** (`melonds`) — optional, but DSi mode and some titles want the
|
|
||||||
real BIOS/firmware.
|
|
||||||
|
|
||||||
Be honest about the two heaviest cores. `dolphin` and `pcsx2` are libretro ports
|
|
||||||
of emulators whose upstream effort goes into their **standalone** builds; the
|
|
||||||
cores lag on compatibility and are the first place to look when a GameCube, Wii
|
|
||||||
or PS2 title misbehaves. If a game does not cooperate, add the standalone
|
|
||||||
emulators to `environment.systemPackages` in `gaming.nix`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
pkgs.dolphin-emu # GameCube / Wii
|
|
||||||
pkgs.pcsx2 # PlayStation 2
|
|
||||||
```
|
|
||||||
|
|
||||||
Both are controller-driven and can be added to Big Picture the same way as
|
|
||||||
RetroArch. The hardware is not the limit here — a GTX 1070 and a Haswell i7 run
|
|
||||||
PS2 and Wii comfortably.
|
|
||||||
|
|
||||||
Five cores (`snes9x`, `genesis-plus-gx`, `picodrive`, `fbneo`,
|
|
||||||
`mame2003-plus`) carry upstream licences with non-commercial or
|
|
||||||
no-redistribution-for-profit clauses, so their derivation names are in
|
|
||||||
`unfreePackages` in `flake.nix`. Nothing else in the core set needs it.
|
|
||||||
|
|
||||||
## Games library layout
|
|
||||||
|
|
||||||
Content lives under `/srv/games`, deliberately outside any home directory: it is
|
|
||||||
bulky, it is the thing most likely to move to its own disk, and it is shared
|
|
||||||
between Steam, RetroArch and Clone Hero rather than owned by one of them.
|
|
||||||
Mounting a second drive at `/srv/games` is the only change that move needs.
|
|
||||||
|
|
||||||
`gaming.nix` creates the tree with `systemd.tmpfiles.rules` at every boot:
|
|
||||||
|
|
||||||
```
|
|
||||||
/srv/games/
|
|
||||||
├── roms/ # RetroArch content browser opens here
|
|
||||||
│ ├── nes/ snes/ gb/ gbc/ gba/ n64/ nds/ gc/ wii/
|
|
||||||
│ ├── mastersystem/ gamegear/ megadrive/ sega32x/ segacd/
|
|
||||||
│ ├── saturn/ dreamcast/
|
|
||||||
│ ├── psx/ ps2/ psp/
|
|
||||||
│ └── arcade/ dos/
|
|
||||||
├── bios/ # RetroArch system dir: BIOS and firmware
|
|
||||||
├── saves/ # in-game saves
|
|
||||||
├── states/ # save states
|
|
||||||
├── playlists/
|
|
||||||
├── screenshots/
|
|
||||||
├── thumbnails/
|
|
||||||
├── steam/ # second Steam library folder
|
|
||||||
└── clonehero/
|
|
||||||
├── songs/
|
|
||||||
└── backgrounds/
|
|
||||||
```
|
|
||||||
|
|
||||||
Directory names under `roms/` follow the libretro/ES-DE convention, so a scraper
|
|
||||||
or a second frontend recognises them without anything being renamed.
|
|
||||||
|
|
||||||
Everything is `lyrathorpe:users` mode **2775**. The setgid bit matters: the
|
|
||||||
owning group is carried onto anything created inside, so a second account — or
|
|
||||||
an `rsync` from another machine — does not leave behind files the TV user cannot
|
|
||||||
write. The rules create directories if missing and otherwise leave them alone;
|
|
||||||
nothing here removes or rewrites content.
|
|
||||||
|
|
||||||
RetroArch is pointed at these paths declaratively. The other two have to be told
|
|
||||||
once, in their own UIs:
|
|
||||||
|
|
||||||
- **Steam** — Settings → Storage → the `+` control → add `/srv/games/steam` as a
|
|
||||||
library folder. Games installed there survive a reinstall of the OS.
|
|
||||||
- **Clone Hero** — set the song library path to `/srv/games/clonehero/songs` from
|
|
||||||
its settings screen. Clone Hero keeps its own config in `~/.clonehero`.
|
|
||||||
|
|
||||||
## Steam and Proton
|
|
||||||
|
|
||||||
`programs.steam.enable` already arranges most of what Proton needs, and it is
|
|
||||||
worth recording so it is not re-litigated:
|
|
||||||
|
|
||||||
- `hardware.graphics` with `enable32Bit` — the 32-bit GL/Vulkan userspace
|
|
||||||
Proton's 32-bit prefixes link against.
|
|
||||||
- Steam's udev rules (`hardware.steam-hardware.enable`) — controller and
|
|
||||||
hidraw access, which is also what lets `dualsensectl` talk to a DualSense.
|
|
||||||
- 32-bit PipeWire ALSA (`services.pipewire.alsa.support32Bit`), derived from
|
|
||||||
`alsa.enable`, which `gaming.nix` turns on for the older native titles that
|
|
||||||
talk to ALSA directly rather than through the Pulse shim.
|
|
||||||
- Wine's fonts — Liberation, DejaVu, FreeFont and the Noto set arrive with
|
|
||||||
`fonts.enableDefaultPackages` plus `modules/common-nixos.nix`. Liberation is
|
|
||||||
metric-compatible with the Microsoft core fonts, so text lays out correctly
|
|
||||||
without shipping unfree `corefonts`.
|
|
||||||
- `vm.max_map_count` is **1048576** in the nixpkgs default sysctls, above what
|
|
||||||
DX12 and Unreal titles need. No override required — this is the one people
|
|
||||||
usually copy from Arch wiki posts and it is already handled.
|
|
||||||
|
|
||||||
What is **not** covered by default, and is set explicitly in `gaming.nix`:
|
|
||||||
|
|
||||||
- `systemd.settings.Manager.DefaultLimitNOFILE = "1024:1048576"`. esync opens
|
|
||||||
one eventfd per Wine synchronisation object and runs out against systemd's
|
|
||||||
default 524288 hard limit in the heaviest titles. Only the hard limit is
|
|
||||||
raised; the soft limit stays at 1024, because lifting that breaks
|
|
||||||
`select()`-based programs elsewhere on the system.
|
|
||||||
- `extraCompatPackages = [ pkgs.proton-ge-bin ]`. The module puts its
|
|
||||||
`steamcompattool` output on `STEAM_EXTRA_COMPAT_TOOLS_PATHS`, which is what
|
|
||||||
makes **GE-Proton** appear in the client's compatibility list.
|
|
||||||
- `protontricks.enable` — winetricks against a Proton prefix, the standard
|
|
||||||
repair when a title needs a runtime (dotnet, vcrun, Media Foundation) Proton
|
|
||||||
does not ship.
|
|
||||||
- `programs.gamemode.enable` — applies the performance CPU governor around games
|
|
||||||
that request it.
|
|
||||||
|
|
||||||
One thing is **not declarative**: Steam Play must be switched on in the client,
|
|
||||||
once, per account — **Settings → Compatibility → Enable Steam Play for all other
|
|
||||||
titles**. Nix cannot set this; it lives in Steam's own config.
|
|
||||||
|
|
||||||
Verify the Proton side after installing:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
vulkaninfo --summary # 64-bit ICD
|
|
||||||
nvidia-smi # driver up
|
|
||||||
ulimit -Hn # expect 1048576
|
|
||||||
# in a game's launch options, to confirm esync/fsync are active:
|
|
||||||
# PROTON_LOG=1 %command% → ~/steam-<appid>.log
|
|
||||||
```
|
|
||||||
|
|
||||||
## Controllers
|
|
||||||
|
|
||||||
- **Xbox One / Series over Bluetooth** — `hardware.xpadneo.enable`. The
|
|
||||||
out-of-tree driver; the in-kernel `xpad` handles these badly over Bluetooth
|
|
||||||
(wrong button mapping, no rumble). The module enables bluez itself.
|
|
||||||
- **Xbox 360, wired** — in-kernel `xpad`, autoloaded by udev on plug-in.
|
|
||||||
Nothing to configure. The kernel is built with `CONFIG_JOYSTICK_XPAD=m`,
|
|
||||||
`CONFIG_JOYSTICK_XPAD_FF=y` (rumble) and `CONFIG_JOYSTICK_XPAD_LEDS=y`. The
|
|
||||||
360 wireless PC receiver uses the same driver and works the same way.
|
|
||||||
- **DualSense / DualShock 4** — in-kernel `hid-playstation`, over both USB and
|
|
||||||
Bluetooth. No driver config. `dualsensectl` is installed for LED, battery and
|
|
||||||
microphone control; it works because Steam's udev rules grant hidraw access.
|
|
||||||
- **Clone Hero guitars** — plain USB HID gamepads, handled in-kernel. Nothing to
|
|
||||||
configure.
|
|
||||||
|
|
||||||
`hardware.bluetooth.powerOnBoot` is set so the adapter is up before the Steam
|
|
||||||
session starts and a pad can reconnect unattended.
|
|
||||||
`settings.General.Experimental = true` is what enables battery level reporting
|
|
||||||
for Bluetooth gamepads — it is still behind bluez's experimental flag.
|
|
||||||
|
|
||||||
Pair a new controller from Big Picture (**Settings → Controller**), or from a
|
|
||||||
Sway session with `bluetoothctl`. If a pad connects but no input arrives, check
|
|
||||||
`journalctl -b -u bluetooth` and confirm `hid_xpadneo` is loaded
|
|
||||||
(`lsmod | grep xpadneo`).
|
|
||||||
|
|
||||||
The Xbox One / Series USB **wireless dongle** is deliberately not configured. It
|
|
||||||
needs `hardware.xone.enable`, which **blacklists `xpad`** — that would break the
|
|
||||||
wired 360 pads — as well as `mt76x2u`, and pulls in proprietary dongle firmware.
|
|
||||||
Not worth the side effects unless that dongle is actually in use, and if it ever
|
|
||||||
is, the 360 pads have to be re-tested.
|
|
||||||
|
|
||||||
## Untested claims
|
|
||||||
|
|
||||||
This host has not been built or booted yet. Two things are worth watching on
|
|
||||||
first boot:
|
|
||||||
|
|
||||||
- **gamescope on the proprietary NVIDIA driver.** `gaming.nix` sets
|
|
||||||
`GBM_BACKEND=nvidia-drm` and `__GLX_VENDOR_LIBRARY_NAME=nvidia` for the
|
|
||||||
session, which is the standard fix, but the combination has a history of
|
|
||||||
needing tweaks. If the session dies at startup, switch the greeter back to
|
|
||||||
interactive by commenting out `services.greetd.settings.initial_session`, log
|
|
||||||
into Sway, and read `journalctl --user -b`.
|
|
||||||
- **Television resolution and refresh.** gamescope takes the output's native
|
|
||||||
mode by default. Add `gamescopeSession.args = [ "-W" "3840" "-H" "2160" "-r"
|
|
||||||
"60" ]` if a specific mode is wanted.
|
|
||||||
|
|
||||||
There is no HDMI-CEC configuration here, so the TV remote will not drive the
|
|
||||||
box; that needs a Pulse-Eight adapter or a working CEC bridge on the board.
|
|
||||||
Nothing boots to a splash screen either — Plymouth was left out deliberately, as
|
|
||||||
early KMS with the proprietary driver makes it unreliable.
|
|
||||||
|
|
||||||
## Networking
|
|
||||||
|
|
||||||
Wired NetworkManager from `../../modules/desktop.nix`; `modules/ssh.nix` adds
|
|
||||||
key-only sshd, which is the practical way to administer a machine with no
|
|
||||||
keyboard attached. The firewall is default-deny (`modules/workstation.nix`);
|
|
||||||
Steam Remote Play and local network game transfers open their own ports through
|
|
||||||
`programs.steam`.
|
|
||||||
+10
-2
@@ -186,6 +186,14 @@ fleet's stock "wheel, with a password" policy. What it does **not** implement:
|
|||||||
host aliases, LDAP/SSSD sudoers, `sudoreplay`, and most `Defaults` settings.
|
host aliases, LDAP/SSSD sudoers, `sudoreplay`, and most `Defaults` settings.
|
||||||
Needing any of those means reverting to `security.sudo`.
|
Needing any of those means reverting to `security.sudo`.
|
||||||
|
|
||||||
|
One exception to the password: the EDaaS box sets
|
||||||
|
`security.sudo-rs.wheelNeedsPassword = false`. NixOS-WSL ships that default for
|
||||||
|
`security.sudo` — WSL has no console login, so the trust boundary is the Windows
|
||||||
|
session and the Linux account password is never one the user chose — and the
|
||||||
|
option does not carry across to the `security.sudo-rs` module, which defaults to
|
||||||
|
requiring one. Without the explicit setting, `sudo` on that host prompts for a
|
||||||
|
password nobody knows.
|
||||||
|
|
||||||
If a host ever refuses to escalate, get a root shell that does not go through
|
If a host ever refuses to escalate, get a root shell that does not go through
|
||||||
sudo (`wsl -u root -d NixOS` on the work box; the console or a serial/HDMI login
|
sudo (`wsl -u root -d NixOS` on the work box; the console or a serial/HDMI login
|
||||||
elsewhere) and roll back with `nixos-rebuild switch --rollback`, or pick the
|
elsewhere) and roll back with `nixos-rebuild switch --rollback`, or pick the
|
||||||
@@ -350,10 +358,10 @@ Claude to route new memories there.
|
|||||||
## Per-host differences
|
## Per-host differences
|
||||||
|
|
||||||
| | Personal Linux (sway) | macOS | Work WSL (EDaaS) |
|
| | Personal Linux (sway) | macOS | Work WSL (EDaaS) |
|
||||||
| --------------------------- | --------------------- | --------------------- | --------------------------- |
|
| --------------------------- | --------------------- | --------------------- | ---------------------------- |
|
||||||
| Auto-tmux | yes (foot/TTY) | yes (iTerm2) | yes (WSL shell) |
|
| Auto-tmux | yes (foot/TTY) | yes (iTerm2) | yes (WSL shell) |
|
||||||
| `kubectl` → kubecolor | no (no kubectl) | no | yes (work module) |
|
| `kubectl` → kubecolor | no (no kubectl) | no | yes (work module) |
|
||||||
| `sudo` implementation | sudo-rs | Apple sudo + Touch ID | sudo-rs |
|
| `sudo` implementation | sudo-rs (password) | Apple sudo + Touch ID | sudo-rs (passwordless wheel) |
|
||||||
| git email | `iam@emmathe.dev` | `iam@emmathe.dev` | `…@citrix.com` (work) |
|
| git email | `iam@emmathe.dev` | `iam@emmathe.dev` | `…@citrix.com` (work) |
|
||||||
| ssh config managed | yes | yes | no (keeps corporate config) |
|
| ssh config managed | yes | yes | no (keeps corporate config) |
|
||||||
| ssh-agent | yes | launchd | yes (work module) |
|
| ssh-agent | yes | launchd | yes (work module) |
|
||||||
|
|||||||
Generated
+31
-31
@@ -3,16 +3,16 @@
|
|||||||
"brew-src": {
|
"brew-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786348930,
|
"lastModified": 1786945682,
|
||||||
"narHash": "sha256-bCQJkbgsAMDp5HQystZLCq11UHiyEuoWbxKulAPYrh8=",
|
"narHash": "sha256-VBESSoJccikdhxh3vp3SQeG7cZXTOulMvVkoSqNDEhs=",
|
||||||
"owner": "Homebrew",
|
"owner": "Homebrew",
|
||||||
"repo": "brew",
|
"repo": "brew",
|
||||||
"rev": "3ecc9eff23feebf1bc73846d74e14a122c93b66f",
|
"rev": "5b90e281d4e0c8fbd6ca4d8358276fb305b8d0bd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "Homebrew",
|
"owner": "Homebrew",
|
||||||
"ref": "6.0.16",
|
"ref": "6.0.18",
|
||||||
"repo": "brew",
|
"repo": "brew",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -25,11 +25,11 @@
|
|||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "pkgs/firefox-addons",
|
"dir": "pkgs/firefox-addons",
|
||||||
"lastModified": 1786853140,
|
"lastModified": 1787457768,
|
||||||
"narHash": "sha256-O880FlUav75Q5aNlg9znyg/avf1X/W7o/cAtZFLtpWc=",
|
"narHash": "sha256-cbgeu5NTb6DtB+tNs4E6z6K/1XKKM90gVmlkWMJe+gY=",
|
||||||
"owner": "rycee",
|
"owner": "rycee",
|
||||||
"repo": "nur-expressions",
|
"repo": "nur-expressions",
|
||||||
"rev": "ba9568c9c0df6290dc2f34b032ab4cb575e73788",
|
"rev": "25cfc8fdc413d73b3a47e3e86dafcad51cf5c9f9",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -135,11 +135,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784288435,
|
"lastModified": 1787424939,
|
||||||
"narHash": "sha256-ReRHaLgr/uVqdD8afFSn+myXIfpHeOhP0yYe0TJqAA8=",
|
"narHash": "sha256-O2tBn84NNuHrnqNVxx/XqsXwfYvS1YwBh+7CBnbCYsk=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "git-hooks.nix",
|
"repo": "git-hooks.nix",
|
||||||
"rev": "43b3c1ab9d40fb1dbb008f451988a91e375825e9",
|
"rev": "809414f0cdadf82cf11b06c2b29ba9b3168b3297",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -155,11 +155,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786924861,
|
"lastModified": 1787377438,
|
||||||
"narHash": "sha256-hftabkb+73OcGzvwFAjCiQorAhprs9TnU1+FkGO5CIw=",
|
"narHash": "sha256-Sxu1NLTD/Ern6hFGLlZmtKCSct3YQXZI/lls8RE1XeM=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "09ae1b85a6db412d841d60f924b23f881f0d0a38",
|
"rev": "65258d5c65a250189fde2e35f490d15e064c4c62",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -211,11 +211,11 @@
|
|||||||
"brew-src": "brew-src"
|
"brew-src": "brew-src"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786686423,
|
"lastModified": 1787330919,
|
||||||
"narHash": "sha256-8q3WdB8o3VUI7rOz1OXfioXIaaWbFTAxRJAkWLlfc0s=",
|
"narHash": "sha256-LslMncqN7uOOH5S88WZtO/EVt2HwD8ltUnfyANk+mC0=",
|
||||||
"owner": "zhaofengli",
|
"owner": "zhaofengli",
|
||||||
"repo": "nix-homebrew",
|
"repo": "nix-homebrew",
|
||||||
"rev": "ccabf79a6b9845eb72b51ea1d9c7ce3446350df3",
|
"rev": "b00218e4aec0e5bf07d61a0bb13f842faa582d7b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -231,11 +231,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786852476,
|
"lastModified": 1787457452,
|
||||||
"narHash": "sha256-IM5CYtf86W4w8eUPpKcY/LpdHElmVBtJhaKnoTKxZEA=",
|
"narHash": "sha256-FJh4esFS3zqNNuKwvN3t6wrJGewqp1AUF9DAEvoKPD8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nix-index-database",
|
"repo": "nix-index-database",
|
||||||
"rev": "c7962dc97b45129df8d751bedaf37beb5a17706e",
|
"rev": "c51d5c2ba69c907a34e90c9b6b80cd2b93811745",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -272,11 +272,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786867632,
|
"lastModified": 1787144466,
|
||||||
"narHash": "sha256-ez+ubZlA1RtdjCB18a6zJ9M4u8qoPDy08EcnsW5M3Xw=",
|
"narHash": "sha256-HHfv2/HkNSKbbSyU9iD/g8lbP6r4tl33sSw1W4rXCk0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "ff17823245ab9ff7bcae6acf950bd89cba82c38c",
|
"rev": "0471accf8d0a8210b31d947497d179ecc99e0021",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -308,11 +308,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786711500,
|
"lastModified": 1787414105,
|
||||||
"narHash": "sha256-QvnceIGTBeDvDd9oCn+GvdsnkquliuwbVgpiRH68qaQ=",
|
"narHash": "sha256-WncT27+3BOkgTaJZLnCsf3LcYf9RXMuR9ONSN4rzQ7s=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "02e08985a27c65ffd33d434eeb2e660a2e4dc84d",
|
"rev": "a9e6d84f9c2f9012f5fe7d964a7851352300e61a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -324,11 +324,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786862985,
|
"lastModified": 1787360063,
|
||||||
"narHash": "sha256-FBJRXmbGXiSUDvYEbfLYRkckayyZ6SK1UEqhCrIZ2Cs=",
|
"narHash": "sha256-dt4WdcvsA8/RCe+VZZwqU0X+XMM3wBbGCWA0/sFWzGo=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e5bdc4a41d4c072fe1e3787eaa0320a384741d44",
|
"rev": "2c423e03bbafcff28bfadc6781a4a8257f205cb5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -347,11 +347,11 @@
|
|||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786873773,
|
"lastModified": 1787536726,
|
||||||
"narHash": "sha256-Hj/nkhKDv0aJly1PAUstrhrgEYn1mVSkLIYMh90r/Pc=",
|
"narHash": "sha256-aBh5Yk9tX8ZV4k10BJr2fvTq0/+iWGegaCMUOU7YKas=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixvim",
|
"repo": "nixvim",
|
||||||
"rev": "b397fb9f6950d57355d62bb92457d223464e0115",
|
"rev": "e2c3f9f36326d07340626847543c557e2b95fb50",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -112,27 +112,13 @@
|
|||||||
|
|
||||||
# Unfree packages permitted to be built (replaces blanket allowUnfree).
|
# Unfree packages permitted to be built (replaces blanket allowUnfree).
|
||||||
# The NVIDIA entries are for the Mac Pro's Quadro P400 (hosts/MacPro31/
|
# The NVIDIA entries are for the Mac Pro's Quadro P400 (hosts/MacPro31/
|
||||||
# nvidia.nix) and the Console host's GTX 1070 (hosts/Console/nvidia.nix);
|
# nvidia.nix); unfree packages are not in the binary cache, so the
|
||||||
# unfree packages are not in the binary cache, so the kernel module is
|
# kernel module is compiled on the host.
|
||||||
# compiled on the host. The steam/clonehero entries are the Console
|
|
||||||
# host's games stack (hosts/Console/gaming.nix).
|
|
||||||
unfreePackages = [
|
unfreePackages = [
|
||||||
"claude-code"
|
"claude-code"
|
||||||
"nvidia-x11"
|
"nvidia-x11"
|
||||||
"nvidia-kernel-modules"
|
"nvidia-kernel-modules"
|
||||||
"nvidia-settings"
|
"nvidia-settings"
|
||||||
"steam"
|
|
||||||
"steam-unwrapped"
|
|
||||||
"steam-run"
|
|
||||||
"clonehero"
|
|
||||||
# RetroArch cores whose upstream licences carry a non-commercial or
|
|
||||||
# no-redistribution-for-profit clause. Everything else in the core set
|
|
||||||
# is plain free software.
|
|
||||||
"libretro-snes9x"
|
|
||||||
"libretro-genesis-plus-gx"
|
|
||||||
"libretro-picodrive"
|
|
||||||
"libretro-fbneo"
|
|
||||||
"libretro-mame2003-plus"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Per-user identity, keyed by username. See README "Users".
|
# Per-user identity, keyed by username. See README "Users".
|
||||||
@@ -307,28 +293,6 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
lyrathorpe-console = {
|
|
||||||
system = "x86_64-linux";
|
|
||||||
portable = false;
|
|
||||||
# Living-room games machine on a television: autologins into the
|
|
||||||
# gamescope Steam session (hosts/Console/gaming.nix). sway.nix is
|
|
||||||
# still imported -- greetd/ReGreet is what the Steam session falls
|
|
||||||
# back to, and Sway is the keyboard-and-mouse session behind it.
|
|
||||||
modules = [
|
|
||||||
./hosts/Console/configuration.nix
|
|
||||||
./modules/desktop.nix
|
|
||||||
./modules/ssh.nix
|
|
||||||
inputs.nixos-hardware.nixosModules.common-pc-ssd
|
|
||||||
inputs.nixos-hardware.nixosModules.common-cpu-intel
|
|
||||||
./modules/sway.nix
|
|
||||||
];
|
|
||||||
users.lyrathorpe.homeModules = [
|
|
||||||
./home
|
|
||||||
./users/lyrathorpe/home.nix
|
|
||||||
./home/desktop.nix
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
emmathorpe-edaas = {
|
emmathorpe-edaas = {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = [
|
modules = [
|
||||||
|
|||||||
@@ -15,3 +15,4 @@
|
|||||||
- [Dev clusters disposable](dev_clusters_disposable.md) — Lyra's dev clusters are recreatable; mutate/break freely, no confirmation needed
|
- [Dev clusters disposable](dev_clusters_disposable.md) — Lyra's dev clusters are recreatable; mutate/break freely, no confirmation needed
|
||||||
- [Nix shell tooling](nix_shell_tooling.md) — any nixpkgs tool runs ad hoc via `nix run`/`nix shell nixpkgs#<pkg>`; a missing command is never a dead end
|
- [Nix shell tooling](nix_shell_tooling.md) — any nixpkgs tool runs ad hoc via `nix run`/`nix shell nixpkgs#<pkg>`; a missing command is never a dead end
|
||||||
- [WSP local build and test](wsp_local_build_and_test.md) — core-services-cloud on this box: dotnet via nix, artifactory creds from `~/.artifactoryenv` sourced per command, how to tell auth failure from a code failure
|
- [WSP local build and test](wsp_local_build_and_test.md) — core-services-cloud on this box: dotnet via nix, artifactory creds from `~/.artifactoryenv` sourced per command, how to tell auth failure from a code failure
|
||||||
|
- [WSP-32957 PIM migration](wsp_32957_pim_migration.md) — AKS RBAC to PIM + AutoPerm decommission; prod is in the Technical Preview subscription, three tenants; resume via `~/code/WSP-32957-CONTINUATION.md`
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ Field map for the **WSP (Workspace Platform)** Jira project, to create tickets w
|
|||||||
|
|
||||||
**Issue-type IDs:** Epic `10000`, Story `10004`, Task `10008`, Bug `10123`, Sub-task `10009`.
|
**Issue-type IDs:** Epic `10000`, Story `10004`, Task `10008`, Bug `10123`, Sub-task `10009`.
|
||||||
|
|
||||||
**Fast path — use Task, not Bug.** A `Task` requires only `summary` (project/issuetype auto, reporter defaults to caller). A `Bug` requires six extra fields (below), so only pick Bug when it must be a Bug. The sibling infra/remediation tickets in WSP are Tasks.
|
**Fast path — use Task, not Bug.** A `Task` requires `summary` plus **Task Type** `customfield_15622` (added since this note was first written; the create validator enforces it even though `createmeta` omits it, same trap as Bug's `versions`). Options value=id: Dev Task=34065, CQE Task=34066, Investigation=34067, Security=34068, Maintenance=34069, Release=34070 — use `Maintenance` for refactors and tidy-ups, `Dev Task` for feature work. A `Bug` requires six extra fields (below), so only pick Bug when it must be a Bug. The sibling infra/remediation tickets in WSP are Tasks.
|
||||||
|
|
||||||
|
Example Task `additional_fields`: `{"customfield_15622":{"id":"34069"},"components":[{"name":"Multicluster Platform"}]}`
|
||||||
|
|
||||||
**Bug required fields** (enforced by the create validator; note `createmeta` omits `versions` but the API rejects without it):
|
**Bug required fields** (enforced by the create validator; note `createmeta` omits `versions` but the API rejects without it):
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
name: wsp-32957-pim-migration
|
||||||
|
description: State of the WSP AKS-RBAC-to-PIM migration and AutoPerm decommission, and how to resume it
|
||||||
|
metadata:
|
||||||
|
node_type: memory
|
||||||
|
type: project
|
||||||
|
---
|
||||||
|
|
||||||
|
Long-running epic (August 2026) moving WSP's AKS cluster RBAC off **AutoPerm
|
||||||
|
Manager**-maintained `wsp-*` groups onto the per-subscription **`CEO-*` Azure PIM**
|
||||||
|
groups, then retiring AutoPerm. Epic **WSP-32957**; on the critical path for Zensar
|
||||||
|
L1 on-call (WSP-32193). Work happens in **`~/code/multicluster`**
|
||||||
|
(`terraform/cluster`, `terraform/cluster-k8s-resources`, `products/*/environments/*`).
|
||||||
|
|
||||||
|
**Resume from `~/code/WSP-32957-CONTINUATION.md`** — full state, branch list,
|
||||||
|
verified object IDs, findings and next steps. Jira is the durable record; that file
|
||||||
|
is the index. Keep it updated as work lands ([[docs-keep-updated]]).
|
||||||
|
|
||||||
|
**Landed:** WSP-33141 (multicluster PR #1808, merged `b047163c`) added object-ID
|
||||||
|
inputs — `admin_group_oids` on `cluster`, and `cluster_user_group_oids` /
|
||||||
|
`cluster_viewer_group_oids` / `cluster_superuser_group_oids` on
|
||||||
|
`cluster-k8s-resources`. Supplying IDs _replaces_ the display-name lookup and leaves
|
||||||
|
the `data "azuread_group"` unread, which is what will let the legacy groups be
|
||||||
|
deleted. Nothing sets them yet, so behaviour is unchanged. Repoint branches for test
|
||||||
|
(WSP-33067) and staging (WSP-33068) are pushed but have **no PR** — both gated on
|
||||||
|
decisions, not code.
|
||||||
|
|
||||||
|
**Facts that cost real effort to establish, do not re-derive:**
|
||||||
|
|
||||||
|
- **Production runs in `fc7af6ae-…` (_Workspace Platform Technical Preview_), not
|
||||||
|
`d6d75d07-…` (_Workspace Platform Production_)**, which holds no clusters. The
|
||||||
|
epic was wrong about this for its whole life and every production `CEO-*` group
|
||||||
|
name and object ID had to change. Because `CEO-*` names embed the subscription
|
||||||
|
name, **always re-verify object IDs against live Entra rather than trusting the
|
||||||
|
epic table.**
|
||||||
|
- **Three tenants**, not two: `6f4fe054` (prod, prod JP), `335836de` (staging,
|
||||||
|
staging JP, test), `3eae2746` (dev). Each `wsp-*` name is a distinct object in
|
||||||
|
each tenant.
|
||||||
|
- `wsp-staging-cluster-admins` and `wsp-test-cluster-admins` are **empty**, so
|
||||||
|
`wsp-owner` is the _only_ path to `cluster-admin` in staging. Never drop it before
|
||||||
|
`SuperAdmin-*` is proven — hence the staging branch is split into an additive
|
||||||
|
commit and a cutover commit.
|
||||||
|
- **No break-glass exists**: `disableLocalAccounts = True` on every cluster; only the
|
||||||
|
deployment SPNs authenticate non-interactively.
|
||||||
|
- Graph **PIM-for-Groups is unreadable via `az`** (the CLI's first-party client lacks
|
||||||
|
`PrivilegedAccess.Read.AzureADGroup`, on both `v1.0` and `beta`). Use the portal or
|
||||||
|
`Connect-MgGraph -Scopes PrivilegedAccess.Read.AzureADGroup`.
|
||||||
|
|
||||||
|
**Watch for:** the epic gets rewritten by James Weldrake between sessions — re-read
|
||||||
|
the description before acting, and check which child tickets are still live
|
||||||
|
(WSP-33062/33063/33064/33066 were cancelled 2026-08-24, and dev was put out of
|
||||||
|
scope). Verified findings have repeatedly contradicted the epic text
|
||||||
|
([[copilot-review-false-positives]] is the same instinct: check against reality
|
||||||
|
first).
|
||||||
|
|
||||||
|
Queued Slack messages and the leaver report live as `~/code/*.txt` alongside the
|
||||||
|
continuation file; see the table in it for what has and has not been sent
|
||||||
|
([[workflow-review-and-comments]] — show them before they go out).
|
||||||
+16
-1
@@ -287,7 +287,22 @@ in
|
|||||||
plugins = with pkgs.tmuxPlugins; [
|
plugins = with pkgs.tmuxPlugins; [
|
||||||
sensible
|
sensible
|
||||||
vim-tmux-navigator # Ctrl-h/j/k/l across vim splits and tmux panes
|
vim-tmux-navigator # Ctrl-h/j/k/l across vim splits and tmux panes
|
||||||
yank
|
{
|
||||||
|
# On WSL, tmux-yank pipes the selection to clip.exe, which decodes its
|
||||||
|
# stdin as the OEM codepage instead of UTF-8 -- an em dash reaches the
|
||||||
|
# Windows clipboard as three characters. Route through tmux's own
|
||||||
|
# buffer instead: with set-clipboard on, tmux emits OSC 52 and the
|
||||||
|
# terminal takes the text as UTF-8. Windows Terminal honours OSC 52;
|
||||||
|
# iTerm2 does not by default, hence the runtime guard rather than
|
||||||
|
# overriding pbcopy/xsel on every host. yank.tmux bakes the command
|
||||||
|
# into its key bindings when it loads, so this must be set first, which
|
||||||
|
# is what plugin extraConfig gives us.
|
||||||
|
plugin = yank;
|
||||||
|
extraConfig = ''
|
||||||
|
if-shell 'grep -qi microsoft /proc/version 2>/dev/null' \
|
||||||
|
"set -g @override_copy_command 'tmux load-buffer -w -'"
|
||||||
|
'';
|
||||||
|
}
|
||||||
extrakto # prefix+Tab: fzf-grab paths/URLs/text from the pane into the prompt
|
extrakto # prefix+Tab: fzf-grab paths/URLs/text from the pane into the prompt
|
||||||
{
|
{
|
||||||
# Catppuccin Mocha statusline (v2 API: flavour + window options must be
|
# Catppuccin Mocha statusline (v2 API: flavour + window options must be
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
# Living-room games machine: 4th-gen Core i7 (Haswell) on a UEFI board, wired to
|
|
||||||
# a television and driven from the sofa with a Bluetooth controller. Desktop host
|
|
||||||
# -- shared graphical/wired options live in ../../modules/desktop.nix; only
|
|
||||||
# host-specific settings are here. The games stack (Steam session, RetroArch,
|
|
||||||
# controllers) is in ./gaming.nix and the GPU in ./nvidia.nix. Install notes:
|
|
||||||
# see ../../docs/hosts/console.md.
|
|
||||||
{ ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./nvidia.nix
|
|
||||||
./gaming.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
# Haswell: AVX2/FMA/BMI2, i.e. x86-64-v3. Above the fleet default (2), so this
|
|
||||||
# only records the fact -- no feature flag currently keys off level 3.
|
|
||||||
features.cpu.microarchLevel = 3;
|
|
||||||
|
|
||||||
# Ordinary PC UEFI firmware: systemd-boot, and NVRAM writes are safe here
|
|
||||||
# (unlike the Mac Pro's Apple EFI, which cannot be trusted with efibootmgr).
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
|
||||||
# The boot menu is unreadable from a sofa and unusable without a keyboard.
|
|
||||||
# Boot the default immediately; hold space at power-on to get the menu back.
|
|
||||||
boot.loader.timeout = 0;
|
|
||||||
# Bound the entry list so the ESP does not fill up with old generations.
|
|
||||||
boot.loader.systemd-boot.configurationLimit = 10;
|
|
||||||
|
|
||||||
networking.hostName = "Console-NixOS";
|
|
||||||
|
|
||||||
hardware.cpu.intel.updateMicrocode = true;
|
|
||||||
|
|
||||||
# See `man configuration.nix` / the stateVersion docs before changing.
|
|
||||||
system.stateVersion = "26.05";
|
|
||||||
}
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
# The games stack for the living-room machine: the Steam session that the TV
|
|
||||||
# boots into, RetroArch with its cores, Clone Hero, and the controller plumbing.
|
|
||||||
#
|
|
||||||
# Session model. greetd (from ../../modules/sway.nix, which enables it for
|
|
||||||
# ReGreet) gets an `initial_session`, so the machine autologins into the
|
|
||||||
# gamescope Steam session at boot -- no keyboard, no greeter, straight to Big
|
|
||||||
# Picture. Quitting Steam drops back to greetd's `default_session`, i.e. ReGreet,
|
|
||||||
# where the ordinary Sway session can be picked for keyboard-and-mouse work.
|
|
||||||
{ pkgs, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
# The account the television autologins as. Must match the user declared for
|
|
||||||
# this host in the flake host table.
|
|
||||||
tvUser = "lyrathorpe";
|
|
||||||
|
|
||||||
# Games library root. Deliberately outside any home directory: content is
|
|
||||||
# bulky, is the thing most likely to move to its own disk, and is shared
|
|
||||||
# between Steam, RetroArch and Clone Hero rather than owned by one of them.
|
|
||||||
# Mounting a second drive at this path is the only change that needs.
|
|
||||||
gamesRoot = "/srv/games";
|
|
||||||
|
|
||||||
# One ROM directory per emulated system. Names follow the libretro/ES-DE
|
|
||||||
# convention so a scraper or a second frontend recognises them without
|
|
||||||
# renaming anything.
|
|
||||||
romSystems = [
|
|
||||||
"nes"
|
|
||||||
"snes"
|
|
||||||
"gb"
|
|
||||||
"gbc"
|
|
||||||
"gba"
|
|
||||||
"n64"
|
|
||||||
"nds"
|
|
||||||
"gc"
|
|
||||||
"wii"
|
|
||||||
"mastersystem"
|
|
||||||
"gamegear"
|
|
||||||
"megadrive"
|
|
||||||
"sega32x"
|
|
||||||
"segacd"
|
|
||||||
"saturn"
|
|
||||||
"dreamcast"
|
|
||||||
"psx"
|
|
||||||
"ps2"
|
|
||||||
"psp"
|
|
||||||
"arcade"
|
|
||||||
"dos"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Everything under the root that is not a ROM directory. RetroArch is pointed
|
|
||||||
# at these below; Steam and Clone Hero have to be told about theirs in their
|
|
||||||
# own UIs (see docs/hosts/console.md).
|
|
||||||
libraryDirs = [
|
|
||||||
"bios" # RetroArch system directory: BIOS and firmware images
|
|
||||||
"saves" # in-game saves
|
|
||||||
"states" # save states
|
|
||||||
"playlists"
|
|
||||||
"screenshots"
|
|
||||||
"thumbnails"
|
|
||||||
"steam" # add as a Steam library folder from the client
|
|
||||||
"clonehero/songs"
|
|
||||||
"clonehero/backgrounds"
|
|
||||||
];
|
|
||||||
|
|
||||||
# RetroArch and the cores this machine is expected to run. The wrapper already
|
|
||||||
# points RetroArch at the packaged assets, core info and joypad autoconfig
|
|
||||||
# profiles; `settings` here is merged on top of those.
|
|
||||||
retroarch = pkgs.retroarch-bare.wrapper {
|
|
||||||
cores = with pkgs.libretro; [
|
|
||||||
# Nintendo
|
|
||||||
nestopia # NES
|
|
||||||
snes9x # SNES
|
|
||||||
gambatte # Game Boy / Color
|
|
||||||
mgba # Game Boy Advance
|
|
||||||
mupen64plus # Nintendo 64
|
|
||||||
melonds # Nintendo DS
|
|
||||||
dolphin # GameCube / Wii
|
|
||||||
# Sega
|
|
||||||
genesis-plus-gx # Master System / Game Gear / Mega Drive
|
|
||||||
picodrive # 32X / Mega CD
|
|
||||||
beetle-saturn # Saturn
|
|
||||||
flycast # Dreamcast / NAOMI
|
|
||||||
# Sony
|
|
||||||
beetle-psx-hw # PlayStation, hardware renderer
|
|
||||||
pcsx2 # PlayStation 2 (LRPS2); needs a PS2 BIOS in RetroArch's system dir
|
|
||||||
ppsspp # PSP
|
|
||||||
# Arcade and PC
|
|
||||||
fbneo
|
|
||||||
mame2003-plus
|
|
||||||
dosbox-pure
|
|
||||||
];
|
|
||||||
settings = {
|
|
||||||
# Applied on every launch via --appendconfig, so these three are fixed
|
|
||||||
# policy rather than saved preferences: changing them in the UI will not
|
|
||||||
# stick. Everything else stays user-editable as usual.
|
|
||||||
#
|
|
||||||
# Ozone is the controller-navigable menu; the TV has no keyboard.
|
|
||||||
menu_driver = "ozone";
|
|
||||||
video_fullscreen = "true";
|
|
||||||
# L3+R3 opens the RetroArch menu from inside a running core
|
|
||||||
# (INPUT_COMBO_L3_R3). Without a pad combo there is no way to exit a game
|
|
||||||
# without a keyboard, and no retro system this box emulates has L3/R3 on
|
|
||||||
# its own controller, so the binding cannot collide with a game.
|
|
||||||
input_menu_toggle_gamepad_combo = "2";
|
|
||||||
|
|
||||||
# Point RetroArch at the shared library instead of scattering content and
|
|
||||||
# state through ~/.config/retroarch. Key names are RetroArch's own; an
|
|
||||||
# unrecognised key in an appended config is ignored silently, so they are
|
|
||||||
# worth keeping in step with upstream.
|
|
||||||
system_directory = "${gamesRoot}/bios";
|
|
||||||
savefile_directory = "${gamesRoot}/saves";
|
|
||||||
savestate_directory = "${gamesRoot}/states";
|
|
||||||
playlist_directory = "${gamesRoot}/playlists";
|
|
||||||
screenshot_directory = "${gamesRoot}/screenshots";
|
|
||||||
thumbnails_directory = "${gamesRoot}/thumbnails";
|
|
||||||
# Where the content browser opens, so loading a game is a couple of
|
|
||||||
# D-pad presses rather than a walk up from the filesystem root.
|
|
||||||
rgui_browser_directory = "${gamesRoot}/roms";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
programs.steam = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
# Registers the "Steam" wayland session (gamescope wrapping Steam in tenfoot
|
|
||||||
# mode) with the display manager and installs the steam-gamescope launcher.
|
|
||||||
gamescopeSession.enable = true;
|
|
||||||
gamescopeSession.env = {
|
|
||||||
# gamescope has to be pointed at NVIDIA's GBM implementation and GLX
|
|
||||||
# vendor explicitly; on the proprietary driver it otherwise fails to get a
|
|
||||||
# usable device and the session dies at startup.
|
|
||||||
GBM_BACKEND = "nvidia-drm";
|
|
||||||
__GLX_VENDOR_LIBRARY_NAME = "nvidia";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Remote Play and local network game transfers are the point of a TV box on
|
|
||||||
# the same LAN as a desktop; both need their ports open.
|
|
||||||
remotePlay.openFirewall = true;
|
|
||||||
localNetworkGameTransfers.openFirewall = true;
|
|
||||||
|
|
||||||
# Proton-GE, selectable per title in Steam's compatibility settings. Covers
|
|
||||||
# the titles where Valve's Proton lags on codecs and anti-cheat shims. The
|
|
||||||
# module puts its steamcompattool output on STEAM_EXTRA_COMPAT_TOOLS_PATHS,
|
|
||||||
# which is what makes it appear in the client's Proton version list.
|
|
||||||
extraCompatPackages = [ pkgs.proton-ge-bin ];
|
|
||||||
|
|
||||||
# Winetricks against a Proton prefix: the standard repair tool when a title
|
|
||||||
# needs a runtime (dotnet, vcrun, Media Foundation) that Proton does not ship.
|
|
||||||
protontricks.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Proton prerequisites beyond what programs.steam already arranges.
|
|
||||||
#
|
|
||||||
# Already covered by the steam module, recorded here so it is not re-litigated:
|
|
||||||
# hardware.graphics 32-bit (the lib32 NVIDIA userspace Proton's 32-bit prefixes
|
|
||||||
# need), Steam's udev rules, 32-bit PipeWire, and the system fonts Wine renders
|
|
||||||
# with (Liberation and DejaVu arrive with fonts.enableDefaultPackages).
|
|
||||||
# vm.max_map_count is 1048576 in the nixpkgs default sysctls, which is above
|
|
||||||
# what DX12/Unreal titles need -- no override required.
|
|
||||||
#
|
|
||||||
# What is not covered: esync opens one eventfd per Wine sync object and runs
|
|
||||||
# out against systemd's default 524288 hard limit in the heaviest titles.
|
|
||||||
# Raise the hard limit only; the soft limit stays at the default, because
|
|
||||||
# lifting that breaks select()-based programs elsewhere on the system.
|
|
||||||
systemd.settings.Manager.DefaultLimitNOFILE = "1024:1048576";
|
|
||||||
|
|
||||||
# capSysNice lets gamescope raise its own scheduling priority, which is what
|
|
||||||
# keeps the compositor smooth while a game saturates the GPU. It installs
|
|
||||||
# gamescope as a setcap wrapper instead of a plain systemPackages entry;
|
|
||||||
# /run/wrappers/bin precedes the system profile on PATH, so steam-gamescope
|
|
||||||
# still resolves it.
|
|
||||||
programs.gamescope = {
|
|
||||||
enable = true;
|
|
||||||
capSysNice = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Applies the performance CPU governor (and drops it again) around games that
|
|
||||||
# ask for it; Steam's Proton builds and most native titles do.
|
|
||||||
programs.gamemode.enable = true;
|
|
||||||
|
|
||||||
# Autologin into the Steam session. The launcher is not exposed as a package
|
|
||||||
# by the steam module -- it is built inside it and added to
|
|
||||||
# environment.systemPackages -- so reference it through the system profile.
|
|
||||||
# greetd's `restart` option defaults to false once initial_session is set,
|
|
||||||
# which is what stops a logout from looping straight back into autologin.
|
|
||||||
services.greetd.settings.initial_session = {
|
|
||||||
command = "/run/current-system/sw/bin/steam-gamescope";
|
|
||||||
user = tvUser;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Controllers.
|
|
||||||
#
|
|
||||||
# Xbox One/Series pads over Bluetooth need xpadneo: the in-kernel xpad driver
|
|
||||||
# does not handle them well over BT (wrong button mapping, no rumble). The
|
|
||||||
# module turns on bluez itself; powerOnBoot is set below so the adapter is up
|
|
||||||
# before the Steam session starts and a pad can reconnect unattended.
|
|
||||||
#
|
|
||||||
# Everything else is in-kernel and needs no configuration: wired Xbox 360 pads
|
|
||||||
# (and the 360 wireless receiver) via xpad, DualSense/DualShock 4 via
|
|
||||||
# hid-playstation over USB and Bluetooth, and Clone Hero guitars as plain USB
|
|
||||||
# HID gamepads. xpadneo does not contend with xpad -- it binds Bluetooth HID
|
|
||||||
# devices, and the 360 pad is not HID-compliant. hardware.xone is deliberately
|
|
||||||
# left off: it blacklists xpad, which would break the 360 pads.
|
|
||||||
#
|
|
||||||
# hidraw access for the PlayStation pads (LED, battery, dualsensectl) comes
|
|
||||||
# from Steam's udev rules, which programs.steam enables via
|
|
||||||
# hardware.steam-hardware.
|
|
||||||
hardware.xpadneo.enable = true;
|
|
||||||
hardware.bluetooth = {
|
|
||||||
enable = true;
|
|
||||||
powerOnBoot = true;
|
|
||||||
# Battery level reporting for Bluetooth gamepads is still behind bluez's
|
|
||||||
# experimental flag.
|
|
||||||
settings.General.Experimental = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# The games library, created at boot so the directories exist before anything
|
|
||||||
# tries to write into them. Mode 2775 is setgid: the owning group is carried
|
|
||||||
# onto anything created inside, so a second account (or an rsync from another
|
|
||||||
# machine) does not end up with files the TV user cannot write. Directories
|
|
||||||
# are created if missing and otherwise left alone -- nothing here removes or
|
|
||||||
# rewrites content.
|
|
||||||
systemd.tmpfiles.rules =
|
|
||||||
let
|
|
||||||
dir = path: "d ${path} 2775 ${tvUser} users -";
|
|
||||||
in
|
|
||||||
[
|
|
||||||
(dir gamesRoot)
|
|
||||||
(dir "${gamesRoot}/roms")
|
|
||||||
]
|
|
||||||
++ map (system: dir "${gamesRoot}/roms/${system}") romSystems
|
|
||||||
++ map (sub: dir "${gamesRoot}/${sub}") libraryDirs;
|
|
||||||
|
|
||||||
# 32-bit ALSA for the older native titles that talk to ALSA directly rather
|
|
||||||
# than through the PulseAudio shim; programs.steam derives
|
|
||||||
# pipewire.alsa.support32Bit from this. PipeWire itself and the Pulse shim
|
|
||||||
# come from ../../modules/workstation.nix.
|
|
||||||
services.pipewire.alsa.enable = true;
|
|
||||||
|
|
||||||
environment.systemPackages = [
|
|
||||||
retroarch
|
|
||||||
pkgs.clonehero
|
|
||||||
pkgs.dualsensectl # DualSense LED/battery/mic control from the shell
|
|
||||||
pkgs.mangohud # FPS/frametime overlay; use `mangohud %command%` in Steam
|
|
||||||
pkgs.vulkan-tools # vulkaninfo, for checking the 32/64-bit ICDs Proton needs
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
# PLACEHOLDER -- not generated by nixos-generate-config.
|
|
||||||
#
|
|
||||||
# This host has not been installed yet, so there is no real hardware scan to
|
|
||||||
# commit. The values below are the conventional defaults for a Haswell UEFI
|
|
||||||
# desktop and assume the install labels its partitions `nixos` (root, ext4) and
|
|
||||||
# `BOOT` (ESP, vfat) -- see docs/hosts/console.md. They exist so the flake
|
|
||||||
# evaluates in CI; they are not a description of the actual machine.
|
|
||||||
#
|
|
||||||
# Replace this whole file with the output of `nixos-generate-config` run on the
|
|
||||||
# machine, and commit that. If the labels do not match, the boot fails loudly on
|
|
||||||
# a missing device rather than touching the wrong disk.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"xhci_pci"
|
|
||||||
"ehci_pci"
|
|
||||||
"ahci"
|
|
||||||
"nvme"
|
|
||||||
"usb_storage"
|
|
||||||
"usbhid"
|
|
||||||
"sd_mod"
|
|
||||||
"sr_mod"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
|
||||||
device = "/dev/disk/by-label/nixos";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
|
||||||
device = "/dev/disk/by-label/BOOT";
|
|
||||||
fsType = "vfat";
|
|
||||||
options = [
|
|
||||||
"fmask=0022"
|
|
||||||
"dmask=0022"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [ ];
|
|
||||||
|
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
|
||||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
# NVIDIA GeForce GTX 1070 8 GB (Pascal, GP104): proprietary driver for the
|
|
||||||
# gamescope Steam session and the Sway desktop.
|
|
||||||
#
|
|
||||||
# Driver branch: 580 (nvidiaPackages.legacy_580), NOT the nixpkgs default
|
|
||||||
# (`production`, currently 595.x). 580 is the last branch that supports
|
|
||||||
# Maxwell/Pascal/Volta -- NVIDIA keeps it as an LTS branch to Aug 2028 -- and a
|
|
||||||
# newer branch simply will not drive this card. Same constraint as the Mac Pro's
|
|
||||||
# Quadro P400; see hosts/MacPro31/nvidia.nix.
|
|
||||||
#
|
|
||||||
# The driver is unfree, so it is not in the binary cache: the kernel module is
|
|
||||||
# compiled locally on every kernel bump.
|
|
||||||
{ config, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
# Selects the proprietary driver; the module blacklists nouveau/nvidiafb and
|
|
||||||
# loads nvidia-uvm via a modprobe softdep. Naming is historical -- this option
|
|
||||||
# drives the kernel/driver choice on Wayland hosts too, which is why it is set
|
|
||||||
# on a machine that runs no X server.
|
|
||||||
services.xserver.videoDrivers = [ "nvidia" ];
|
|
||||||
|
|
||||||
hardware.nvidia = {
|
|
||||||
package = config.boot.kernelPackages.nvidiaPackages.legacy_580;
|
|
||||||
# Required for Wayland: sets nvidia-drm.modeset=1 (and fbdev=1), without
|
|
||||||
# which neither gamescope nor wlroots gets a usable GBM device and both the
|
|
||||||
# Steam session and Sway fail to start.
|
|
||||||
modesetting.enable = true;
|
|
||||||
# The open kernel modules need Turing or later; Pascal must use the closed
|
|
||||||
# ones. Explicit because the option has no default on driver >= 560.
|
|
||||||
open = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# The NVIDIA module only puts these in boot.kernelModules when
|
|
||||||
# services.xserver.enable is true, which is false on this Wayland-only host --
|
|
||||||
# so load them explicitly rather than relying on udev modalias autoloading.
|
|
||||||
# nvidia_uvm is deliberately absent: the module's modprobe softdep pulls it in
|
|
||||||
# after the GPU device exists, which is the supported ordering.
|
|
||||||
boot.kernelModules = [
|
|
||||||
"nvidia"
|
|
||||||
"nvidia_modeset"
|
|
||||||
"nvidia_drm"
|
|
||||||
];
|
|
||||||
|
|
||||||
# wlroots refuses the proprietary NVIDIA driver unless told to proceed. The
|
|
||||||
# greeter's compositor (cage) and gamescope have no such check; only Sway
|
|
||||||
# needs the flag, which the module bakes into the wrapper the session's
|
|
||||||
# .desktop file runs.
|
|
||||||
programs.sway.extraOptions = [ "--unsupported-gpu" ];
|
|
||||||
|
|
||||||
# 32-bit driver libraries for 32-bit Steam titles and Proton's 32-bit
|
|
||||||
# prefixes: hardware.graphics.enable32Bit pulls in the matching lib32 NVIDIA
|
|
||||||
# userspace. programs.steam (./gaming.nix) sets it too; stated here as well so
|
|
||||||
# the GPU's 32-bit story lives with the rest of the GPU config.
|
|
||||||
hardware.graphics.enable32Bit = true;
|
|
||||||
}
|
|
||||||
@@ -60,6 +60,11 @@
|
|||||||
## patch the script
|
## patch the script
|
||||||
systemd.services.docker-desktop-proxy.script = lib.mkForce ''${config.wsl.wslConf.automount.root}/wsl/docker-desktop/docker-desktop-user-distro proxy --docker-desktop-root ${config.wsl.wslConf.automount.root}/wsl/docker-desktop "C:\Program Files\Docker\Docker\resources"'';
|
systemd.services.docker-desktop-proxy.script = lib.mkForce ''${config.wsl.wslConf.automount.root}/wsl/docker-desktop/docker-desktop-user-distro proxy --docker-desktop-root ${config.wsl.wslConf.automount.root}/wsl/docker-desktop "C:\Program Files\Docker\Docker\resources"'';
|
||||||
|
|
||||||
|
# NixOS-WSL's passwordless wheel default only covers `security.sudo`; the
|
||||||
|
# sudo-rs swap in common-nixos.nix needs it set again. No console login here,
|
||||||
|
# and no account password anyone knows.
|
||||||
|
security.sudo-rs.wheelNeedsPassword = false;
|
||||||
|
|
||||||
features.swayDesktop.enable = false;
|
features.swayDesktop.enable = false;
|
||||||
|
|
||||||
# NOTE: this user's systemd --user lingering -- so the home-manager renovate
|
# NOTE: this user's systemd --user lingering -- so the home-manager renovate
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
# Headless server: the Sway desktop is intentionally not set up. modules/sway.nix is
|
# Headless server: the Sway desktop is intentionally not set up. modules/sway.nix is
|
||||||
# not imported and features.swayDesktop.enable defaults to false (declared in
|
# not imported and features.swayDesktop.enable defaults to false (declared in
|
||||||
# system/modules/features.nix), so this host keeps plain TTY/SSH login.
|
# modules/features.nix), so this host keeps plain TTY/SSH login.
|
||||||
|
|
||||||
# Raspberry Pi boots via U-Boot + extlinux, not GRUB/systemd-boot. The
|
# Raspberry Pi boots via U-Boot + extlinux, not GRUB/systemd-boot. The
|
||||||
# raspberry-pi-5 nixos-hardware profile supplies the kernel, firmware and
|
# raspberry-pi-5 nixos-hardware profile supplies the kernel, firmware and
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
# The features.swayDesktop.enable option is declared in
|
# The features.swayDesktop.enable option is declared in
|
||||||
# system/modules/features.nix (so headless hosts can read/set it without
|
# modules/features.nix (so headless hosts can read/set it without
|
||||||
# importing this module). This module only provides its implementation.
|
# importing this module). This module only provides its implementation.
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
programs.sway = {
|
programs.sway = {
|
||||||
|
|||||||
+2
-2
@@ -29,10 +29,10 @@
|
|||||||
// lib.optionalAttrs (spec ? linger) { inherit (spec) linger; }
|
// lib.optionalAttrs (spec ? linger) { inherit (spec) linger; }
|
||||||
) hostUsers;
|
) hostUsers;
|
||||||
|
|
||||||
programs.firefox = lib.mkIf (config.features.swayDesktop.enable == true) {
|
programs.firefox = lib.mkIf config.features.swayDesktop.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
programs.thunderbird = lib.mkIf (config.features.swayDesktop.enable == true) {
|
programs.thunderbird = lib.mkIf config.features.swayDesktop.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user