README and skill point to github.com/theupriser/steamify-cachyos; local paths keep their names.
12 KiB
name, description
| name | description |
|---|---|
| cachyos-vm-testing | Use when testing Steamify CachyOS (repo steamify-cachyos, 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. |
Testing Steamify CachyOS in the CachyOS VM
The wizard (setup-gamescope-boot.sh + lib/*.sh) opens a menu that detects
which components are on and toggles them to match the user's choice. Menu order:
- SteamOS conversion (boot into gaming mode via autologin, Return to Gaming Mode shortcut, Steam desktop autostart)
- SteamOS theme (installs
cachyos-vaporand applies the Vapor global theme with its desktop and window layout; needs a running Plasma session) - Steam Deck/Machine icons (
STEAM_GAMEPADUI_ARGS -steamos3) - Single user mode (SDDM, no lock screen/user switching/log out; enabling it enables 1, disabling 1 disables it)
- 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)
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
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)
scripts/vmreset.sh --fremont # restore ssh-ready, boot, mount repo, autologin, wait for Plasma
scripts/cmp.sh save # baseline of the KDE configs
scripts/vmwatch.sh '1\n3\n\ny\nn\n' "Theme only" # wizard in a visible Konsole in the VM
scripts/vmstate.sh # component state
scripts/vmshot.sh /path/shot.png # screenshot, then view it
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
Start in the background:
./run.sh --fremont > /tmp/vm.log 2>&1 & # flags: [install] [--fremont] [--nvidia] [--vulkan]
Wait for SSH:
until ssh -p 2222 -o BatchMode=yes -o ConnectTimeout=3 theupriser@localhost true 2>/dev/null; do sleep 3; done
Shut down and wait until QEMU is gone. Use '^qemu-system': a plain
pgrep -f qemu-system also matches the shell running it.
ssh -p 2222 -o BatchMode=yes theupriser@localhost sudo systemctl poweroff
while pgrep -f '^qemu-system' >/dev/null; do sleep 2; done
Snapshots
Only while the VM is off. Keep vars.fd together with the disk.
qemu-img snapshot -l disk.qcow2 # list
qemu-img snapshot -a ssh-ready disk.qcow2 && cp vars.ssh-ready.fd vars.fd # restore
qemu-img snapshot -c my-state disk.qcow2 && cp vars.fd vars.my-state.fd # create
Existing snapshots: clean (fresh install) and ssh-ready (sshd + host key +
passwordless sudo). Reset to ssh-ready before each full test run.
First-time guest setup
Only when building from clean. In the guest console:
sudo mount -t 9p -o trans=virtio,version=9p2000.L vmtools /media && /media/guest-ssh-setup.sh
This installs and enables sshd, opens the firewall (ufw/firewalld if active),
adds the host keys (share/host-keys.pub, written by run.sh) and a NOPASSWD
sudoers rule for the test user.
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/setup-gamescope-boot.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
read-write as 9p tag repo. The ssh-ready snapshot does not mount it:
ssh -p 2222 -o BatchMode=yes theupriser@localhost bash -s << 'EOF'
sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt
# optional, survives reboots:
grep -q ' /mnt 9p ' /etc/fstab || echo 'repo /mnt 9p trans=virtio,version=9p2000.L,nofail 0 0' | sudo tee -a /etc/fstab
EOF
Remote commands: the guest shell is fish
Pass remote commands as bash heredocs, never as inline strings containing $:
ssh -p 2222 -o BatchMode=yes theupriser@localhost bash -s << 'EOF'
echo "$HOME"
EOF
Getting a Plasma session
On a fresh snapshot the plasmalogin greeter is shown. Enable test autologin:
ssh -p 2222 -o BatchMode=yes theupriser@localhost bash -s << 'EOF'
sudo mkdir -p /etc/plasmalogin.conf.d
printf '[Autologin]\nUser=theupriser\nSession=plasma.desktop\n' | sudo tee /etc/plasmalogin.conf.d/00-test-autologin.conf
sudo systemctl restart plasmalogin
EOF
Remove /etc/plasmalogin.conf.d/00-test-autologin.conf before testing the
"normal login screen" case.
Running the wizard non-interactively
scripts/vmrun.sh '<input>' does this (log also at /tmp/wizard.log in the
guest). Manually, in the guest:
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
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
restart question.
| Input | Meaning |
|---|---|
'\ny\nn\n' |
first run, accept all |
'2\n\ny\nn\n' |
toggle the theme |
'a\ny\nn\n' |
re-apply what is on |
'q\n' |
just show the menu |
'1\n3\n\ny\nn\n' |
from all-off: theme only (Steam Machine too with --fremont; add 5\n to drop it) |
'1\n\ny\nn\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
(Also after any re-apply that includes the conversion.)
No suitable Vulkan (venus is unstable with the host NVIDIA driver). After enabling the conversion, before rebooting:
sudo /usr/lib/steamos/steam-set-session plasma.desktop
so autologin lands in Plasma. Stuck in a gamescope relogin loop: over SSH set
the session to plasma and sudo systemctl restart display-manager (or stop the
DM, set the session, start it).
Checking component state
scripts/vmstate.sh prints:
- display manager, SDDM autologin file, plasmalogin
[Autologin]section - session sync bridge units (
sync-steamos-session.path) and sudoers rule (gamescope-session-switch) - Return to Gaming Mode shortcut
Exec=line steam-desktop-autostartuser unit; glyphs env file (99-gamescope-steam-glyphs.conf)- LookAndFeelPackage, ColorScheme, GTK theme, font
- KDE Action Restrictions (
lock_screen), kscreenlockerrc Autolock, Lock Session shortcut - panel floating/thickness in plasmashellrc
- kickoff
primaryActions/systemFavorites/icon - leds-valve-dkms-git package, udev rule,
leds_valvemodule,/sys/class/leds/valve-leds*count and owner (user must be able to write) - steamos-manager package and whether it is active
- undo journals present, and duplicate keys (
cut -f1-3 journal | sort | uniq -d)
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.
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.
Reboot checks
- Single user mode on: SDDM autologin without greeter:
pgrep sddm-greeterempty,plasmashellrunning. - Everything off: plasmalogin greeter shown:
loginctl list-sessionsshows a greeter session, no userplasmashell.
Full test matrix
Reset to ssh-ready, start with --fremont, mount the repo, enable test
autologin, then (all passed last run; scripts/vmstate.sh after every step):
- Fresh run turning everything on (
'\ny\nn\n'), set session to plasma, reboot. - Rerun: all shown on, "Everything is already the way you want it".
are-apply: no duplicate journal entries.- Theme on: Steam Deck wallpaper, full-width 46px panel,
distributor-logo-steamdecklauncher icon,dark-lnf=com.valve.vapor.desktop(Brightness & Color's Dark Mode toggle is on, hint "Switch to Breeze"); with single user on, kickoff keepsprimaryActions=3. Theme off: CachyOS wallpaper, floating 30px panel, CachyOS launcher icon, BreezeDark colors (not light),cachyos-vaporremoved,cmp.shclean. - Single user off: switches to plasmalogin + sync bridge + sudoers; shortcut Exec uses
sudo -n. - Single user on: back to SDDM.
- Icons + Steam Machine support off: driver, udev rule, modules-load, steamos-manager removed; yay kept.
7b. DKMS:
vmstate.shshowsinstalledfor every kernel. Headers at boot:sudo pacman -R --noconfirm linux-cachyos-lts-headers(DKMS drops the LTS build), set the session to plasma, reboot, thenjournalctl -b -u ensure-kernel-headersshows the install and DKMS lists LTS again. - Conversion off: single user auto-unticked, plasmalogin
[Autologin]back to CachyOS'sSession=plasma, journals empty. - 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 '6\n\ny\ny\nUPDATE\n\nq\n' | WIZARD_BIOS_DRY_RUN=1 /mnt/setup-gamescope-boot.sh.
The wizard loops back to the menu after every run (Enter, or m/r when a
restart is needed) until q; scripted input that runs out ends it like q.
Visual checks
scripts/vmshot.sh <out.png> does the below. Starting spectacle straight
from SSH core-dumps; it has to run as a user unit (systemd-run --user --wait).
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
qdbus6 org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.activateLauncherMenu # optional, toggles
sleep 1; systemd-run --user --wait -q spectacle -b -n -f -o /tmp/x.png
EOF
scp -P 2222 theupriser@localhost:/tmp/x.png /tmp/x.png # then view it
The launcher call toggles; retake if the screenshot misses it. Apps started
directly over SSH lack the session's Qt platform theme and look light; start
them with systemd-run --user <app>.
Pitfalls
-
Broken mirror:
mirror5.krfoss.orgserved a bad.sig("Maximum file size exceeded"), failing the conversion's package install. Comment it out:sudo sed -i '/krfoss/s/^Server/#Server/' /etc/pacman.d/*mirrorlist*. -
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.shcloses them. -
The guest's
/tmpis cleared on reboot; keep baselines elsewhere. -
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:shellcheck -S warning -x setup-gamescope-boot.sh lib/*.sh(SC2154/SC2034 cross-file warnings are false positives). -
This repo's
.gitignoreis an allowlist: it ignores everything and un-ignores only the tracked scripts/docs. Add any new tracked file to it explicitly, or git will silently ignore it.