Merge pull request #1 from theupriser/feat/visible-vm-runs

Feat/visible vm runs
This commit is contained in:
theupriser authored and GitHub committed 2026-09-24 13:09:16 +02:00
commit 10357b2d52
12 files changed
+338 -26

No files matched your search

+136 -17
View File
@@ -1,24 +1,58 @@
--- ---
name: cachyos-vm-testing name: cachyos-vm-testing
description: Use when testing cachyos-gamescope-boot (setup-gamescope-boot.sh) changes in the CachyOS QEMU test VM - starting/stopping the VM, restoring snapshots, running the wizard over SSH with scripted menu input, checking each component's state, reboot checks and screenshots. description: Use when testing Steamify CachyOS (repo steamify-cachyos, steamify.sh) changes in the CachyOS QEMU test VM - starting/stopping the VM, restoring snapshots, running the wizard over SSH with scripted menu input, checking each component's state, reboot checks and screenshots.
--- ---
# Testing cachyos-gamescope-boot in the CachyOS VM # Testing Steamify CachyOS in the CachyOS VM
The wizard (`setup-gamescope-boot.sh` + `lib/*.sh`) opens a menu that detects The wizard (`steamify.sh` + `lib/*.sh`) opens a menu that detects
which components are on and toggles them to match the user's choice. Menu order: which components are on and toggles them to match the user's choice. Menu order:
1. SteamOS conversion (boot into gaming mode via autologin, Return to Gaming Mode shortcut, Steam desktop autostart) 1. SteamOS conversion (boot into gaming mode via autologin, Return to Gaming Mode shortcut, Steam desktop autostart)
2. SteamOS theme (Vapor) 2. SteamOS theme (installs `cachyos-vapor` and applies the Vapor global theme with its desktop and window layout; needs a running Plasma session)
3. Steam Deck/Machine icons (`STEAM_GAMEPADUI_ARGS -steamos3`) 3. Steam Deck/Machine icons (`STEAM_GAMEPADUI_ARGS -steamos3`)
4. Single user mode (SDDM, no lock screen/user switching/log out; enabling it enables 1, disabling 1 disables it) 4. Single user mode (SDDM, no lock screen/user switching/log out; enabling it enables 1, disabling 1 disables it)
5. Steam Machine support (only on DMI Valve/Fremont: leds-valve-dkms-git, udev rule, steamos-manager) 5. Steamify shortcut (desktop icon + launcher entry that `curl | bash` the newest release; its gear icon is a release asset)
6. Steam Machine support (only on DMI Valve/Fremont: leds-valve-dkms-git built for every kernel via `/etc/dkms/leds-valve-dkms.conf`, `ensure-kernel-headers.service`, udev rule, steamos-manager, powerdevilrc)
7. Update BIOS (only on Fremont, an opt-in action, never pre-ticked; tickable only when Valve has a newer BIOS)
Without `--fremont` the menu has only 1-5.
Undo journals live in `~/.local/state/cachyos-gamescope-boot/` in the guest. Undo journals live in `~/.local/state/cachyos-gamescope-boot/` in the guest.
Run everything from the root of this repo on the host. Defaults: user Run everything from the root of this repo on the host. Defaults: user
`theupriser`, SSH port `2222` (the scripts take `VM_USER` / `VM_PORT` / `VM_HOST`). `theupriser`, SSH port `2222` (the scripts take `VM_USER` / `VM_PORT` / `VM_HOST`).
The VM's disk, `vars*.fd` and `run.sh` copy may live outside the repo
(`~/vms/cachyos-test` on the main dev machine). Find it with
`readlink /proc/$(pgrep -f '^qemu-system')/cwd` when the VM runs; the
snapshot commands below run in that directory. `scripts/vmreset.sh` takes
`VM_DIR` and defaults to the repo if it holds `disk.qcow2`, else `~/vms/cachyos-test`.
## Quick start (the usual loop)
```bash
scripts/vmreset.sh --fremont # restore ssh-ready, boot, mount repo, autologin, wait for Plasma
# (also skips the broken krfoss mirror, installs shellcheck)
scripts/cmp.sh save # baseline of the KDE configs
scripts/vmwatch.sh '1\n3\n\ny\n' "Theme only" # wizard in a visible Konsole in the VM
scripts/vmwatch.sh --release '\ny\nm\nq\n' "Full run" # the newest GitHub release instead of /mnt
scripts/vmstate.sh # component state
scripts/vmshot.sh --clean /path/shot.png # screenshot (--clean: close Steam/Hello/Konsole first)
```
**Always finish on a fresh `ssh-ready` snapshot**, ideally with `--release`
once published. Re-applying or toggling on an already set-up VM hides
first-install bugs: the DKMS override silently failed on a fresh system
(`/etc/dkms` doesn't exist before `dkms` is installed), which no re-apply
showed because `dkms` was there already.
Long runs (full install: packages, yay, DKMS) take 10+ minutes: run them
with `run_in_background` and wait with an until-loop, not chained sleeps.
Prefer `vmwatch.sh` over `vmrun.sh` when the user is watching the QEMU
window: `vmrun.sh` runs invisibly over SSH, so they see nothing happen.
## VM lifecycle ## VM lifecycle
Start in the background: Start in the background:
@@ -68,6 +102,10 @@ sudoers rule for the test user.
## Mounting the project repo ## Mounting the project repo
The mount is lost on every reboot (unless the fstab line below was added).
Without it the wizard fails with `/mnt/steamify.sh: No such file
or directory`, which is easy to miss in filtered output. Remount after each reboot.
The repo (`REPO`, default `~/projects/cachyos-gamescope-boot`) is shared The repo (`REPO`, default `~/projects/cachyos-gamescope-boot`) is shared
read-write as 9p tag `repo`. The `ssh-ready` snapshot does not mount it: read-write as 9p tag `repo`. The `ssh-ready` snapshot does not mount it:
@@ -111,22 +149,42 @@ guest). Manually, in the guest:
```bash ```bash
export XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus export XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
printf '\ny\nn\n' | /mnt/setup-gamescope-boot.sh printf '\ny\nm\nq\n' | /mnt/steamify.sh
``` ```
Menu input: a number toggles a component, an empty line continues, `a` Menu input: a number toggles a component, an empty line continues, `a`
re-applies what is on, `q` quits. Then `y` answers "Go ahead?" and `n` the re-applies what is on, `q` quits; then `y` answers "Go ahead?". The wizard
restart question. **loops**: after a run it asks for Enter (back to the menu), or `[m]`/`[r]`
(menu / restart now) when a restart is needed. On `q` with a restart pending
it asks "Restart now? [Y/n]" (default **yes**): `n` goes back to the menu and
the next `q` asks again. Input that runs out quits without restarting, so end
scripted input right after the last `q` (or with `n`), never with an empty
line at the restart question.
| Input | Meaning | | Input | Meaning |
|---|---| |---|---|
| `'\ny\nn\n'` | first run, accept all | | `'\ny\nm\nq\n'` | first run, accept all (not the BIOS item), back to the menu, quit |
| `'2\n\ny\nn\n'` | toggle the theme | | `'2\n\ny\n'` | toggle the theme |
| `'a\ny\nn\n'` | re-apply what is on | | `'a\ny\nm\nq\n'` | re-apply what is on (includes the conversion, so a restart is pending) |
| `'q\n'` | just show the menu | | `'q\n'` | just show the menu |
| `'1\n3\n5\n\ny\n'` | from all-off: theme only (with `--fremont` also add `6\n` to drop Steam Machine support) |
| `'1\n\ny\n'` | from a state where 1 is off: turn the conversion on |
**Know the starting ticks before choosing input.** When *everything* is off
(fresh snapshot, or after turning the last component off), the menu treats it
as a first run and pre-ticks **all** components, so `2` means "theme off,
rest on". Otherwise the ticks show what is on now. Unticking 1 also unticks 4,
and ticking 4 ticks 1 again, so `'1\n3\n4\n...'` ends with the conversion on.
When unsure, run `'q\n'` first and read the ticks.
`a` only re-applies components that are already on: it does not retry one that
failed. Re-applying the conversion also resets the autologin session to
gamescope, so set it back to plasma before the next reboot (below).
## Gamescope does not render in this VM ## Gamescope does not render in this VM
(Also after any re-apply that includes the conversion.)
No suitable Vulkan (venus is unstable with the host NVIDIA driver). After No suitable Vulkan (venus is unstable with the host NVIDIA driver). After
enabling the conversion, before rebooting: enabling the conversion, before rebooting:
@@ -157,6 +215,21 @@ DM, set the session, start it).
`scripts/cmp.sh save` stores a baseline of the KDE/GTK configs in the guest `scripts/cmp.sh save` stores a baseline of the KDE/GTK configs in the guest
(`~/.cache/vm-baseline`, not `/tmp`); `scripts/cmp.sh` diffs against it. (`~/.cache/vm-baseline`, not `/tmp`); `scripts/cmp.sh` diffs against it.
After changing the theme, `cmp.sh` should show only spectacle's
`kglobalshortcutsrc` entries (from screenshots) and keys whose value equals
`~/.config/kdedefaults` (e.g. `ColorScheme=BreezeDark`, `widgetStyle=Breeze`):
KDE drops or writes those on its own.
## Testing the newest release
`scripts/vmwatch.sh --release '<input>'` downloads
`releases/latest/download/steamify.sh` in the guest and runs it with the piped
input (`WIZARD_KEEP_STDIN=1`; the bundle otherwise reattaches the terminal).
Release assets only exist from the version that added them: before v0.9.0 was
published, `steamify.sh` and the shortcut's `steam-gaming-settings.svg` gave
404 and the shortcut fell back to Steam's icon. Check a release with
`curl -sIL -o /dev/null -w '%{http_code}' .../releases/latest/download/<asset>`.
## Reboot checks ## Reboot checks
- Single user mode on: SDDM autologin without greeter: `pgrep sddm-greeter` empty, `plasmashell` running. - Single user mode on: SDDM autologin without greeter: `pgrep sddm-greeter` empty, `plasmashell` running.
@@ -167,23 +240,57 @@ DM, set the session, start it).
Reset to `ssh-ready`, start with `--fremont`, mount the repo, enable test Reset to `ssh-ready`, start with `--fremont`, mount the repo, enable test
autologin, then (all passed last run; `scripts/vmstate.sh` after every step): autologin, then (all passed last run; `scripts/vmstate.sh` after every step):
1. Fresh run turning everything on (`'\ny\nn\n'`), set session to plasma, reboot. 1. Fresh run turning everything on (`'\ny\nm\nq\n'`), set session to plasma, reboot:
SDDM logs straight in, Vapor desktop, three desktop icons (Return to Gaming
Mode, Steam, Steamify CachyOS with the gear icon), LEDs loaded (17 nodes).
2. Rerun: all shown on, "Everything is already the way you want it". 2. Rerun: all shown on, "Everything is already the way you want it".
3. `a` re-apply: no duplicate journal entries. 3. `a` re-apply: no duplicate journal entries.
4. Theme off: look restored (CachyOS wallpaper, floating 30px panel, `org.cachyos.hello` launcher icon). 4. Theme on: Steam Deck wallpaper, full-width 46px panel, `distributor-logo-steamdeck` launcher icon, `dark-lnf=com.valve.vapor.desktop` (Brightness & Color's Dark Mode toggle is on, hint "Switch to Breeze"); with single user on, kickoff keeps `primaryActions=3`. Theme off: CachyOS wallpaper, floating 30px panel, CachyOS launcher icon, BreezeDark colors (not light), `cachyos-vapor` removed, `cmp.sh` clean.
5. Single user off: switches to plasmalogin + sync bridge + sudoers; shortcut Exec uses `sudo -n`. 5. Single user off: switches to plasmalogin + sync bridge + sudoers; shortcut Exec uses `sudo -n`.
6. Single user on: back to SDDM. 6. Single user on: back to SDDM.
7. Icons + Steam Machine support off: driver, udev rule, modules-load, steamos-manager removed; yay kept. 7. Icons + Steam Machine support off: driver, udev rule, modules-load, steamos-manager removed; yay kept.
7b. DKMS: `vmstate.sh` shows `installed` for every kernel. Headers at boot:
`sudo pacman -R --noconfirm linux-cachyos-lts-headers` (DKMS drops the LTS
build), set the session to plasma, reboot, then `journalctl -b -u
ensure-kernel-headers` shows the install and DKMS lists LTS again.
8. Conversion off: single user auto-unticked, plasmalogin `[Autologin]` back to CachyOS's `Session=plasma`, journals empty. 8. Conversion off: single user auto-unticked, plasmalogin `[Autologin]` back to CachyOS's `Session=plasma`, journals empty.
9. Remove the test autologin file, reboot: normal login screen. 9. Remove the test autologin file, reboot: normal login screen.
## BIOS update item
Only shown with `--fremont`, and only tickable when the guest's BIOS version
differs from Valve's newest. Fake an older one with
`BIOS_VERSION=F7F0107 ./run.sh --fremont` (SMBIOS type 0; `vmreset.sh` passes
the environment through). fwupd correctly refuses the firmware in the VM
("not for this machine's hardware"), so walk the whole flow with
`WIZARD_BIOS_DRY_RUN=1` (skips only that check, never flashes). Scripted:
`printf '7\n\ny\ny\nUPDATE\nm\nq\nn\n' | WIZARD_BIOS_DRY_RUN=1 /mnt/steamify.sh`
(BIOS is item 7 with `--fremont`; the final `n` answers the restart question).
A successful dry run counts as staged, so `[m]`/`[r]` and the restart question
on `q` show up too; in dry-run mode "restart" only prints.
## Steamify shortcut
Test a double-click with `systemd-run --user kioclient exec
~/Desktop/cachyos-gamescope-boot-wizard.desktop`. If Plasma opens the file in
Kate instead, it saw the file before it was executable. After the wizard the
window counts down 10 seconds and closes; after an error (e.g. 404) it waits
for Enter.
## Visual checks ## Visual checks
`scripts/vmshot.sh [--clean] <out.png>` does the below. After a reboot, Steam's
sign-in window and CachyOS Hello cover the desktop: `--clean` shuts Steam down
(closing only `steamwebhelper` leaves a black window) and closes Hello and the
wizard's Konsole. Steam comes back at the next login. Starting `spectacle` straight
from SSH core-dumps; it has to run as a user unit (`systemd-run --user --wait`).
```bash ```bash
ssh -p 2222 -o BatchMode=yes theupriser@localhost bash -s << 'EOF' ssh -p 2222 -o BatchMode=yes theupriser@localhost bash -s << 'EOF'
export XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus export XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
qdbus6 org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.activateLauncherMenu # optional, toggles qdbus6 org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.activateLauncherMenu # optional, toggles
sleep 1; spectacle -b -n -f -o /tmp/x.png sleep 1; systemd-run --user --wait -q spectacle -b -n -f -o /tmp/x.png
EOF EOF
scp -P 2222 theupriser@localhost:/tmp/x.png /tmp/x.png # then view it scp -P 2222 theupriser@localhost:/tmp/x.png /tmp/x.png # then view it
``` ```
@@ -194,11 +301,23 @@ them with `systemd-run --user <app>`.
## Pitfalls ## Pitfalls
- Broken mirror: `mirror5.krfoss.org` served a bad `.sig` ("Maximum file size
exceeded"), failing the conversion's package install. `vmreset.sh` comments
it out; by hand: `sudo sed -i '/krfoss/s/^Server/#Server/' /etc/pacman.d/*mirrorlist*`.
- The snapshot has no shellcheck; `vmreset.sh` installs it. Check the bundle
like CI: `.github/tools/bundle.sh` on the host, then in the guest
`cd /mnt && shellcheck -S warning -e SC2034,SC2154 dist/steamify.sh`.
- The host shell is zsh: `$var` holding several file names isn't split
(`sed -i ... $files` gets one "name"); use `xargs`.
- Windows open in the snapshot (System Settings, CachyOS Hello) show stale
data (e.g. a theme list from before `cachyos-vapor`) and cover screenshots;
`vmreset.sh` closes them.
- The guest's `/tmp` is cleared on reboot; keep baselines elsewhere. - The guest's `/tmp` is cleared on reboot; keep baselines elsewhere.
- The fake Fremont DMI makes leds-valve load 17 LED nodes, but there is no real hardware. - The fake Fremont DMI makes leds-valve load 17 LED nodes, but there is no real hardware.
- shellcheck: `sudo pacman -S shellcheck`, then in `/mnt`: - Per-file shellcheck (`shellcheck -S warning -x steamify.sh lib/*.sh` in
`shellcheck -S warning -x setup-gamescope-boot.sh lib/*.sh` `/mnt`) shows SC2154/SC2034 cross-file false positives; the bundle check
(SC2154/SC2034 cross-file warnings are false positives). above is the one CI runs.
- This repo's `.gitignore` is an allowlist: it ignores everything and - This repo's `.gitignore` is an allowlist: it ignores everything and
un-ignores only the tracked scripts/docs. Add any new tracked file to it un-ignores only the tracked scripts/docs. Add any new tracked file to it
explicitly, or git will silently ignore it. explicitly, or git will silently ignore it.
+1
View File
@@ -3,6 +3,7 @@
/* /*
!/.gitignore !/.gitignore
!/README.md !/README.md
!/CHANGELOG.md
!/run.sh !/run.sh
!/run.ps1 !/run.ps1
!/get-iso.sh !/get-iso.sh
+54
View File
@@ -0,0 +1,54 @@
# Changelog
All notable changes, per version and per commit. Versions follow
[Semantic Versioning](https://semver.org/) and were numbered from the start
of the history.
## 0.2.0 - 2026-09-24
Watchable test runs and the lessons from testing cachyos-gamescope-boot 0.7.0
(cachyos-vapor theme, LED driver on every kernel).
- `b4114a1` **feat: Visible wizard runs, one-step VM reset and screenshots; skill updates**
- `scripts/vmreset.sh [--fremont]`: restore `ssh-ready`, boot, mount the repo,
set up the test autologin and wait for Plasma.
- `scripts/vmwatch.sh '<input>' [label]`: run the wizard in a visible Konsole
in the VM, so someone at the QEMU window can follow along.
- `scripts/vmshot.sh <out.png>`: screenshot via a user unit (spectacle
crashes when started straight from SSH).
- `scripts/vmstate.sh`: DKMS status per kernel, the DKMS override, the kernel
headers service, the dark look-and-feel, the wallpaper and the theme's
layout backup.
- `scripts/cmp.sh`: also compares `kcminputrc` and `ksplashrc`.
- Skill: VM directory outside the repo, the menu's first-run pre-ticks and
the conversion/single-user coupling, the repo mount lost on reboot,
re-applying the conversion resets the session to gamescope, the new
theme and LED checks in the test matrix, and the broken mirror workaround.
- `3733f94` **docs: Changelog**
- `3cdf2e1` **feat: Fake BIOS version for testing the BIOS update item**
- `BIOS_VERSION=F7F0107 ./run.sh ...` makes the guest report that BIOS
version (SMBIOS type 0), so the wizard offers the update.
- Skill: testing the BIOS item with `WIZARD_BIOS_DRY_RUN=1`, and the
wizard's menu loop.
- `c6abfd2` **docs: Renamed to steamify-cachyos-dev, for Steamify CachyOS**
- README and skill point to `github.com/theupriser/steamify-cachyos`; the
local clone's default path (`REPO`) and the guest's state directory keep
their old names.
- `8c48858` **chore: The wizard's script is now steamify.sh**
- `vmrun.sh`, `vmwatch.sh`, the skill and the README run `/mnt/steamify.sh`.
- **feat: Release testing, cleaner resets and screenshots; skill updates**
- `vmwatch.sh --release` runs the newest GitHub release in the VM.
- `vmreset.sh` skips the broken krfoss mirror and installs shellcheck.
- `vmshot.sh --clean` closes Steam, CachyOS Hello and Konsole first.
- Skill: menu items 1-7 and the new menu loop/restart question, current
scripted inputs, always finishing on a fresh snapshot (the DKMS bug only
showed there), testing releases and their assets, the Steamify shortcut,
and the zsh word-splitting pitfall.
## 0.1.1 - 2026-09-23
- `d2cf240` **fix: Document how to add the host SSH key to the VM**
## 0.1.0 - 2026-09-23
- `97c5c56` **fix: Add CachyOS test VM dev environment and VM testing skill**
+10 -3
View File
@@ -1,7 +1,7 @@
# cachyos-gamescope-boot dev environment # Steamify CachyOS dev environment
A QEMU/KVM test VM running CachyOS (KDE Plasma 6) for developing and testing A QEMU/KVM test VM running CachyOS (KDE Plasma 6) for developing and testing
[cachyos-gamescope-boot](https://github.com/theupriser/cachyos-gamescope-boot), [Steamify CachyOS](https://github.com/theupriser/steamify-cachyos),
plus helper scripts and a Claude Code skill that documents the test workflow. plus helper scripts and a Claude Code skill that documents the test workflow.
Only scripts and docs live here. The ISO, disk image, UEFI variable stores, Only scripts and docs live here. The ISO, disk image, UEFI variable stores,
@@ -102,11 +102,18 @@ read-write as 9p tag `repo`; in the guest:
- `--nvidia`: render the guest's virtio-gpu (virgl) on the host NVIDIA dGPU - `--nvidia`: render the guest's virtio-gpu (virgl) on the host NVIDIA dGPU
- `--vulkan`: expose Vulkan to the guest (venus; unstable) - `--vulkan`: expose Vulkan to the guest (venus; unstable)
- `--fremont`: fake the Valve Steam Machine (Fremont) DMI data via `-smbios` - `--fremont`: fake the Valve Steam Machine (Fremont) DMI data via `-smbios`
- `REPO` defaults to `$HOME/projects/cachyos-gamescope-boot` - `REPO` defaults to `$HOME/projects/cachyos-gamescope-boot` (the local clone of
[steamify-cachyos](https://github.com/theupriser/steamify-cachyos))
## Helper scripts ## Helper scripts
- `scripts/vmreset.sh [--fremont]`: restore `ssh-ready`, boot, mount the repo, autologin into Plasma
(and skip the broken krfoss mirror, install shellcheck)
- `scripts/vmrun.sh '<menu input>'`: run the wizard in the guest's Plasma session with scripted input - `scripts/vmrun.sh '<menu input>'`: run the wizard in the guest's Plasma session with scripted input
- `scripts/vmwatch.sh [--release] '<menu input>' [label]`: same, but in a visible Konsole window
in the VM; `--release` runs the newest GitHub release instead of the mounted repo
- `scripts/vmshot.sh [--clean] <out.png>`: screenshot the guest's desktop (`--clean` closes
Steam, CachyOS Hello and Konsole first)
- `scripts/vmstate.sh`: print the state of every wizard component - `scripts/vmstate.sh`: print the state of every wizard component
- `scripts/cmp.sh [save]`: save / diff the guest's KDE configs against a baseline - `scripts/cmp.sh [save]`: save / diff the guest's KDE configs against a baseline
+1 -1
View File
@@ -1,4 +1,4 @@
# CachyOS test VM for setup-gamescope-boot.sh -- Windows version. # CachyOS test VM for steamify.sh -- Windows version.
# .\run.ps1 [-Install] # .\run.ps1 [-Install]
# Needs QEMU for Windows (https://qemu.weilnetz.de/w64/) and the Windows # Needs QEMU for Windows (https://qemu.weilnetz.de/w64/) and the Windows
# feature "Windows Hypervisor Platform" (for -accel whpx). # feature "Windows Hypervisor Platform" (for -accel whpx).
+5 -2
View File
@@ -1,11 +1,13 @@
#!/bin/bash #!/bin/bash
# CachyOS test VM for setup-gamescope-boot.sh. # CachyOS test VM for steamify.sh.
# [REPO=/path/to/cachyos-gamescope-boot] ./run.sh [install] [--nvidia] [--vulkan] [--fremont] # [REPO=/path/to/cachyos-gamescope-boot] ./run.sh [install] [--nvidia] [--vulkan] [--fremont]
# install boot the installer ISO # install boot the installer ISO
# --nvidia render the guest's virtio-gpu (virgl) on the host NVIDIA dGPU # --nvidia render the guest's virtio-gpu (virgl) on the host NVIDIA dGPU
# --vulkan expose Vulkan to the guest (venus; needed by gamescope, can be unstable) # --vulkan expose Vulkan to the guest (venus; needed by gamescope, can be unstable)
# --fremont report the Valve Steam Machine's DMI data (for testing the wizard) # --fremont report the Valve Steam Machine's DMI data (for testing the wizard)
# REPO defaults to $HOME/projects/cachyos-gamescope-boot. # REPO defaults to $HOME/projects/cachyos-gamescope-boot.
# BIOS_VERSION=F7F0107 makes the guest report that BIOS version (DMI), e.g.
# to test the wizard's BIOS update item; the firmware itself doesn't change.
# The repo is shared into the guest; mount it there with: # The repo is shared into the guest; mount it there with:
# sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt # sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt
# First-time SSH setup, inside the guest: # First-time SSH setup, inside the guest:
@@ -17,13 +19,14 @@ repo="${REPO:-$HOME/projects/cachyos-gamescope-boot}"
cdrom=() cdrom=()
smbios=() smbios=()
gpu=virtio-vga-gl,xres=1920,yres=1080 gpu=virtio-vga-gl,xres=1920,yres=1080
[[ -n "${BIOS_VERSION:-}" ]] && smbios+=(-smbios "type=0,version=$BIOS_VERSION")
for arg in "$@"; do for arg in "$@"; do
case "$arg" in case "$arg" in
install) cdrom=(-cdrom cachyos.iso -boot d) ;; install) cdrom=(-cdrom cachyos.iso -boot d) ;;
--nvidia) export __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia \ --nvidia) export __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia \
__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/10_nvidia.json ;; __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/10_nvidia.json ;;
--vulkan) gpu+=,hostmem=4G,blob=true,venus=true ;; --vulkan) gpu+=,hostmem=4G,blob=true,venus=true ;;
--fremont) smbios=(-smbios type=1,manufacturer=Valve,product=Fremont -smbios type=2,manufacturer=Valve,product=Fremont) ;; --fremont) smbios+=(-smbios type=1,manufacturer=Valve,product=Fremont -smbios type=2,manufacturer=Valve,product=Fremont) ;;
*) echo "unknown argument: $arg" >&2; exit 1 ;; *) echo "unknown argument: $arg" >&2; exit 1 ;;
esac esac
done done
+1 -1
View File
@@ -10,7 +10,7 @@ mode="${1:-diff}"
# The guest login shell is fish, so pass values in through the bash script itself. # The guest login shell is fish, so pass values in through the bash script itself.
{ printf 'mode=%q base=%q\n' "$mode" "${BASELINE:-}"; cat << 'REMOTE' { printf 'mode=%q base=%q\n' "$mode" "${BASELINE:-}"; cat << 'REMOTE'
base="${base:-$HOME/.cache/vm-baseline}" base="${base:-$HOME/.cache/vm-baseline}"
files="kdeglobals plasmarc plasmashellrc kwinrc kwinrulesrc konsolerc kscreenlockerrc kglobalshortcutsrc gtk-3.0/settings.ini gtk-4.0/settings.ini plasma-org.kde.plasma.desktop-appletsrc" files="kdeglobals kcminputrc ksplashrc plasmarc plasmashellrc kwinrc kwinrulesrc konsolerc kscreenlockerrc kglobalshortcutsrc gtk-3.0/settings.ini gtk-4.0/settings.ini plasma-org.kde.plasma.desktop-appletsrc"
if [ "$mode" = save ]; then if [ "$mode" = save ]; then
for f in $files; do mkdir -p "$(dirname "$base/config/$f")"; cp -f ~/.config/"$f" "$base/config/$f" 2>/dev/null || true; done for f in $files; do mkdir -p "$(dirname "$base/config/$f")"; cp -f ~/.config/"$f" "$base/config/$f" 2>/dev/null || true; done
echo "baseline saved to $base"; exit 0 echo "baseline saved to $base"; exit 0
+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash
# Reset the test VM to a snapshot and bring it up logged in to Plasma:
# power off, restore the snapshot (disk + vars.fd), start it, mount the repo
# on /mnt, set up the test autologin and wait for plasmashell; also skips
# the broken krfoss mirror and installs shellcheck.
# scripts/vmreset.sh [run.sh flags...] e.g. scripts/vmreset.sh --fremont
# Env: VM_USER / VM_PORT / VM_HOST, SNAPSHOT (ssh-ready),
# VM_DIR (where disk.qcow2 lives: this repo if it has one, else ~/vms/cachyos-test),
# VM_LOG (QEMU output, default $VM_DIR/vm.log).
set -euo pipefail
. "$(dirname "$0")/common.sh"
repo="$(cd "$(dirname "$0")/.." && pwd)"
if [[ -z "${VM_DIR:-}" ]]; then
if [[ -f "$repo/disk.qcow2" ]]; then VM_DIR="$repo"; else VM_DIR="$HOME/vms/cachyos-test"; fi
fi
SNAPSHOT="${SNAPSHOT:-ssh-ready}"
VM_LOG="${VM_LOG:-$VM_DIR/vm.log}"
if pgrep -f '^qemu-system' >/dev/null; then
echo "Powering off the running VM..."
vm_ssh sudo systemctl poweroff 2>/dev/null || true
for _ in $(seq 60); do pgrep -f '^qemu-system' >/dev/null || break; sleep 2; done
pgrep -f '^qemu-system' >/dev/null && { echo "VM didn't shut down; stop it first." >&2; exit 1; }
fi
echo "Restoring snapshot '$SNAPSHOT' in $VM_DIR..."
cd "$VM_DIR"
qemu-img snapshot -a "$SNAPSHOT" disk.qcow2
cp "vars.$SNAPSHOT.fd" vars.fd
echo "Starting the VM ($*)..."
nohup ./run.sh "$@" > "$VM_LOG" 2>&1 &
for _ in $(seq 100); do vm_ssh -o ConnectTimeout=3 true 2>/dev/null && break; sleep 3; done
vm_ssh true || { echo "No SSH after 5 minutes; see $VM_LOG" >&2; exit 1; }
vm_ssh bash -s << 'REMOTE'
sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt
sudo mkdir -p /etc/plasmalogin.conf.d
printf '[Autologin]\nUser=%s\nSession=plasma.desktop\n' "$USER" | sudo tee /etc/plasmalogin.conf.d/00-test-autologin.conf >/dev/null
sudo systemctl restart plasmalogin
for _ in $(seq 40); do pgrep -u "$USER" -x plasmashell >/dev/null && break; sleep 3; done
sleep 10
# Windows the snapshot opens at login would cover the screenshots.
pkill -u "$USER" systemsettings; pkill -u "$USER" cachyos-hello
# mirror5.krfoss.org served a broken .sig ("Maximum file size exceeded"),
# which fails the conversion's package install; skip it.
for f in /etc/pacman.d/*mirrorlist*; do sudo sed -i '/krfoss/s/^Server/#Server/' "$f"; done
# shellcheck, for checking the bundle like CI does (not in the snapshot).
sudo pacman -S --needed --noconfirm shellcheck >/dev/null 2>&1 || echo "Couldn't install shellcheck." >&2
pgrep -u "$USER" -x plasmashell >/dev/null && echo "Logged in to Plasma." || { echo "Plasma did not start." >&2; exit 1; }
REMOTE
+1 -1
View File
@@ -15,7 +15,7 @@ GUEST_UID="${GUEST_UID:-1000}"
export XDG_RUNTIME_DIR=/run/user/$uid WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus export XDG_RUNTIME_DIR=/run/user/$uid WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus
log=/tmp/wizard.log log=/tmp/wizard.log
# shellcheck disable=SC2059 # shellcheck disable=SC2059
printf "$input" | "$repo/setup-gamescope-boot.sh" > "$log" 2>&1; echo "exit=$?" >> "$log" printf "$input" | "$repo/steamify.sh" > "$log" 2>&1; echo "exit=$?" >> "$log"
cat "$log" cat "$log"
REMOTE REMOTE
} | vm_ssh bash -s 2>&1 | sed 's/\x1b\[[0-9;]*m//g' } | vm_ssh bash -s 2>&1 | sed 's/\x1b\[[0-9;]*m//g'
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
# Screenshot the guest's Plasma session to a file on the host.
# scripts/vmshot.sh [--clean] <out.png>
# --clean first close what starts with the session and covers the desktop
# (Steam, CachyOS Hello) and the wizard's Konsole.
# spectacle started straight from SSH crashes; run it as a user unit so it
# gets the session's environment.
# Env: VM_USER (theupriser), VM_PORT (2222), VM_HOST (localhost), GUEST_UID (1000).
set -euo pipefail
. "$(dirname "$0")/common.sh"
clean=""
[[ "${1:-}" == --clean ]] && { clean=1; shift; }
out="${1:?usage: $0 [--clean] <out.png>}"
{ printf 'uid=%q clean=%q\n' "${GUEST_UID:-1000}" "$clean"; cat << 'REMOTE'
export XDG_RUNTIME_DIR=/run/user/$uid DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus
rm -f /tmp/vmshot.png
if [ -n "$clean" ]; then
# Steam as a whole: closing only its web helper leaves a black window.
# It comes back at the next login (steam-desktop-autostart).
steam -shutdown >/dev/null 2>&1 & sleep 5; pkill -u "$USER" -x steam; pkill -u "$USER" -x steamwebhelper
pkill -u "$USER" cachyos-hello; pkill -u "$USER" -x konsole
sleep 2
fi
sleep 2
systemd-run --user --wait -q spectacle -b -n -f -o /tmp/vmshot.png
REMOTE
} | vm_ssh bash -s
scp -q -P "$VM_PORT" "$VM_USER@$VM_HOST:/tmp/vmshot.png" "$out"
echo "$out"
+4 -1
View File
@@ -9,11 +9,14 @@ echo "DM=$(systemctl show -p Id --value display-manager) sddm-autologin=$(yn /et
echo "plasmalogin [Autologin]: $(sed -n '/^\[Autologin\]/,/^\[/p' /etc/plasmalogin.conf | grep -v '^\[' | tr '\n' ' ')" echo "plasmalogin [Autologin]: $(sed -n '/^\[Autologin\]/,/^\[/p' /etc/plasmalogin.conf | grep -v '^\[' | tr '\n' ' ')"
echo "shortcut=$(grep -h Exec= ~/Desktop/*Gaming*.desktop 2>/dev/null || echo none)" echo "shortcut=$(grep -h Exec= ~/Desktop/*Gaming*.desktop 2>/dev/null || echo none)"
echo "steam-unit=$([ -f ~/.config/systemd/user/steam-desktop-autostart.service ] && systemctl --user is-enabled steam-desktop-autostart.service || echo none) glyphs=$(yn ~/.config/environment.d/99-gamescope-steam-glyphs.conf)" echo "steam-unit=$([ -f ~/.config/systemd/user/steam-desktop-autostart.service ] && systemctl --user is-enabled steam-desktop-autostart.service || echo none) glyphs=$(yn ~/.config/environment.d/99-gamescope-steam-glyphs.conf)"
echo "lnf=$(kreadconfig6 --file kdeglobals --group KDE --key LookAndFeelPackage) scheme=$(kreadconfig6 --file kdeglobals --group General --key ColorScheme) gtk=$(kreadconfig6 --file ~/.config/gtk-3.0/settings.ini --group Settings --key gtk-theme-name) font=$(kreadconfig6 --file kdeglobals --group General --key font)" echo "lnf=$(kreadconfig6 --file kdeglobals --group KDE --key LookAndFeelPackage) dark-lnf=$(kreadconfig6 --file kdeglobals --group KDE --key DefaultDarkLookAndFeel) scheme=$(kreadconfig6 --file kdeglobals --group General --key ColorScheme) cursor=$(kreadconfig6 --file kcminputrc --group Mouse --key cursorTheme) vapor-pkg=$(pacman -Q cachyos-vapor 2>/dev/null || echo none) layout-backup=$(yn ~/.local/state/cachyos-gamescope-boot/theme-layout)"
echo "wallpaper: $(grep -h '^Image=' ~/.config/plasma-org.kde.plasma.desktop-appletsrc | sort -u | tr '\n' ' ')"
echo "lock_screen=$(kreadconfig6 --file kdeglobals --group 'KDE Action Restrictions' --key action/lock_screen) autolock=$(kreadconfig6 --file kscreenlockerrc --group Daemon --key Autolock) metaL=$(kreadconfig6 --file kglobalshortcutsrc --group ksmserver --key 'Lock Session' | cut -c1-12)" echo "lock_screen=$(kreadconfig6 --file kdeglobals --group 'KDE Action Restrictions' --key action/lock_screen) autolock=$(kreadconfig6 --file kscreenlockerrc --group Daemon --key Autolock) metaL=$(kreadconfig6 --file kglobalshortcutsrc --group ksmserver --key 'Lock Session' | cut -c1-12)"
echo "panel: $(grep -A1 '^\[PlasmaViews\]\[Panel [0-9]*\]$' ~/.config/plasmashellrc | grep floating | tr '\n' ' ') $(grep -h 'thickness' ~/.config/plasmashellrc | tr '\n' ' ')" echo "panel: $(grep -A1 '^\[PlasmaViews\]\[Panel [0-9]*\]$' ~/.config/plasmashellrc | grep floating | tr '\n' ' ') $(grep -h 'thickness' ~/.config/plasmashellrc | tr '\n' ' ')"
echo "kickoff: $(grep -E '^(primaryActions|systemFavorites|icon)=' ~/.config/plasma-org.kde.plasma.desktop-appletsrc | tr '\n' ' ')" echo "kickoff: $(grep -E '^(primaryActions|systemFavorites|icon)=' ~/.config/plasma-org.kde.plasma.desktop-appletsrc | tr '\n' ' ')"
echo "leds-pkg=$(pacman -Q leds-valve-dkms-git 2>/dev/null || echo none) steamos-manager=$(pacman -Q steamos-manager 2>/dev/null || echo none)/$(systemctl is-active steamos-manager 2>/dev/null) udev=$(yn /etc/udev/rules.d/70-valve-leds-user.rules) module=$(lsmod | grep -c leds_valve) leds=$(ls /sys/class/leds | grep -c valve)" echo "leds-pkg=$(pacman -Q leds-valve-dkms-git 2>/dev/null || echo none) steamos-manager=$(pacman -Q steamos-manager 2>/dev/null || echo none)/$(systemctl is-active steamos-manager 2>/dev/null) udev=$(yn /etc/udev/rules.d/70-valve-leds-user.rules) module=$(lsmod | grep -c leds_valve) leds=$(ls /sys/class/leds | grep -c valve)"
echo "dkms: $(dkms status leds-valve-dkms 2>/dev/null | cut -d, -f2- | sed 's/, x86_64//' | tr '\n' ';') kernels: $(ls /usr/lib/modules | tr '\n' ' ')"
echo "dkms-override=$(yn /etc/dkms/leds-valve-dkms.conf) headers-check=$(systemctl is-enabled ensure-kernel-headers.service 2>/dev/null || echo none)"
echo "leds-owner=$(stat -c %U /sys/class/leds/valve-leds*/brightness 2>/dev/null | sort -u | tr '\n' ' ')" echo "leds-owner=$(stat -c %U /sys/class/leds/valve-leds*/brightness 2>/dev/null | sort -u | tr '\n' ' ')"
j=~/.local/state/cachyos-gamescope-boot j=~/.local/state/cachyos-gamescope-boot
echo "journals: $(ls "$j" 2>/dev/null | tr '\n' ' ')" echo "journals: $(ls "$j" 2>/dev/null | tr '\n' ' ')"
+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
# Like vmrun.sh, but run the wizard in a visible Konsole window inside the
# guest's Plasma session, so someone at the QEMU window can follow along.
# Waits for the wizard to finish, then prints its log. The window stays open.
# scripts/vmwatch.sh [--release] '<menu input>' ["label shown in the window"]
# --release run the newest release from GitHub instead of the mounted repo
# (downloaded; WIZARD_KEEP_STDIN=1 keeps the piped menu input).
# Env: VM_USER (theupriser), VM_PORT (2222), VM_HOST (localhost),
# GUEST_REPO (/mnt), GUEST_UID (1000), WAIT (seconds, default 1800).
set -euo pipefail
. "$(dirname "$0")/common.sh"
release=""
[[ "${1:-}" == --release ]] && { release=1; shift; }
input="${1:?usage: $0 [--release] '<menu input>' [label]}"
label="${2:-Running the wizard}"
# The guest login shell is fish, so pass values in through the bash script itself.
{ printf 'input=%q label=%q repo=%q uid=%q wait=%q release=%q\n' "$input" "$label" "${GUEST_REPO:-/mnt}" \
"${GUEST_UID:-1000}" "${WAIT:-1800}" "$release"; cat << 'REMOTE'
export XDG_RUNTIME_DIR=/run/user/$uid DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus
if [ -n "$release" ]; then
wizard=/tmp/steamify-release.sh
curl -fsSL https://github.com/theupriser/steamify-cachyos/releases/latest/download/steamify.sh -o "$wizard" ||
{ echo "Couldn't download the newest release." >&2; exit 1; }
run="WIZARD_KEEP_STDIN=1 bash $wizard"
label="$label ($(grep -m1 '^VERSION=' "$wizard") from GitHub)"
else
[ -x "$repo/steamify.sh" ] || { echo "$repo/steamify.sh missing: mount the repo (lost after a reboot)" >&2; exit 1; }
run="$repo/steamify.sh"
fi
rm -f /tmp/wizard.done
{
echo '#!/bin/bash'
printf 'echo %q; echo %q; sleep 3\n' ">>> $label" ">>> menu input: $input"
# shellcheck disable=SC2016
printf 'printf %q | %s 2>&1 | tee /tmp/wizard.log\n' "$input" "$run"
echo 'touch /tmp/wizard.done'
} > /tmp/vmwatch-run.sh
chmod +x /tmp/vmwatch-run.sh
pkill -u "$USER" -x konsole || true
systemd-run --user -q konsole --hold -e /tmp/vmwatch-run.sh
for _ in $(seq $((wait / 2))); do [ -f /tmp/wizard.done ] && break; sleep 2; done
[ -f /tmp/wizard.done ] || echo "(still running after ${wait}s)"
sed 's/\x1b\[[0-9;]*m//g' /tmp/wizard.log
REMOTE
} | vm_ssh bash -s 2>&1