nvidia suite for 2.12.0: the conversion on NVIDIA, the patched gamescope (G1, N1-N5)
Sync git.upriser.nl mirror / sync (push) Skipped

This commit is contained in:
theupriser committed 2026-10-14 09:16:11 +02:00
1 parent 3d005b3412
commit 7dd1f37fe1
5 files changed
+151 -69

No files matched your search

+15 -11
View File
@@ -64,21 +64,24 @@ change only shows right after Enter).
## F. Features per release
### F2.10.0 Gaming on NVIDIA (`feature/nvidia-gaming-fix`; suite `nvidia`, fake NVIDIA PC)
### F2.12.0 The SteamOS conversion on NVIDIA (`release/2.12.0`; suite `nvidia`, fake NVIDIA PC)
gamescope's session is broken on NVIDIA (see `nvidia/HARDWARE-RESULTS.md`), so on an NVIDIA PC the conversion is replaced by
"Gaming on NVIDIA" (Steam on the Plasma desktop, started at login, optionally in Big Picture) and single user mode logs in to Plasma.
The VM has no NVIDIA GPU: `fake_nvidia` (`share/vmtest/prelude.sh`) fakes one through Steamify's `NVIDIA_DRM_DIR` test hook and installs
fake NVIDIA modules for every kernel. What no VM can show (real driver, the picture, Big Picture on a real GPU) is checked on the real PC.
Since 2.12.0 "Gaming on NVIDIA" (Steam on the desktop) is replaced by the SteamOS conversion with a patched gamescope
(`lib/gamescope-nvidia.sh`, package from `steamify-gamescope-nvidia`: GBM scan-out cures the corrupted picture) and the DRM kernel
parameters / initramfs setup of `lib/nvidia.sh`. The VM has no NVIDIA GPU: `fake_nvidia` (`share/vmtest/prelude.sh`) fakes one
through Steamify's `NVIDIA_DRM_DIR` test hook and installs fake NVIDIA modules for every kernel; `vulkan-swrast` (lavapipe) gives
gamescope's smoke test a Vulkan device. What no VM can show (real driver, the picture, the display mode, suspend, Steam on a real GPU)
is checked on the real RTX 5080 PC (N6).
| # | Step | Expect |
|---|---|---|
| N1 | `--defaults --list` and `--backend status` with the fake GPU (`nvidia/10-n1-menu.sh`) | `nvidia`, `bigpicture` (parent `nvidia`), `single` offered and preselected; `gaming`, `boot`, `glyphs` hidden; without the fake GPU the conversion is offered and `nvidia` is not |
| N2 | `--defaults --options nvidia,bigpicture,single` (`nvidia/20-n2-n5-lifecycle.host.sh`) | exit 0; Steam installed; unit with `-gamepadui` enabled; `loginMode=emptySession`; parameters in `/etc/default/limine` and `/boot/limine.conf`; early-load file, hook and script; modules in the initramfs; SDDM enabled and `zzz-steamify-autologin.conf` (Plasma session) |
| N3 | reboot | Plasma straight in (no greeter), parameters on `/proc/cmdline`, the Steam unit started, `loginMode` kept |
| N4 | `--defaults --options notify` | exit 0; Steam removed (Steamify installed it), unit and autologin file gone, `loginMode` back to not set, parameters/early-load/hook gone, plasma-login-manager the login manager again |
| N5 | reboot | Plasma up through the test autologin, no NVIDIA parameters |
| N6 | real RTX 5080 PC | **done by hand 2026-10-01** (earlier prototype): Big Picture on the Plasma desktop smooth and clean; the apply/boot of the final component is the user's next step |
| N1 | `--defaults --list` and `--backend status` with and without the fake GPU (`nvidia/10-n1-menu.sh`) | `gaming`, `boot`, `glyphs`, `single` offered; `nvidia`, `bigpicture`, `nvsilent` hidden; the same menu without the GPU |
| G1 | `nvidia/15-g1-gamescope-nvidia-functions.sh` (no install) | version compare; CPU level; every pinned sha256 is a hash and the PKGBUILD builds the pinned version; no GitHub: no latest tag, a damaged backup copy refused, one with a matching hash used; update notice (newer / same / offline); pre-flight refuses a pacman lock; failure reminder set and cleared; environment files idempotent and keep other lines; display wrapper + drop-in installed/removed, a foreign file at the wrapper's path kept |
| N2 | pacman locked, `--defaults --options gaming` (`nvidia/20-n2-n5-lifecycle.host.sh`) | exit not 0, names `db.lck`, no patched gamescope, no kernel parameters |
| N3 | 2.11 state ("Gaming on NVIDIA": Steam + autostart unit), then `--options gaming` | the menu shows the conversion as an update; exit 0; autostart unit gone, Steam stays; patched gamescope installed (pinned or newer) and provides `gamescope`; smoke test passes; environment files, display wrapper, kernel parameters (`/etc/default/limine`, `/boot/limine.conf`), early-load file, hook, modules in the initramfs; second run downloads and installs nothing; reboot: parameters on `/proc/cmdline` |
| N4 | (part of N3) | the old autostart unit is gone, Steam stays |
| N5 | package removed + no GitHub: `gsn_install_package`; then `--options notify` | installed again from the download cache and starts; turn-off: environment files, wrapper, drop-in, kernel parameters, early-load file, hook gone; patched gamescope package stays |
| N6 | real RTX 5080 PC | **by hand**: gaming mode picture clean (no corruption), display's own mode and refresh rate, Steam UI size, switching to the desktop and back, suspend/resume, newer-release update notice |
### F2.10.0 Extended controller support (`feature/extended-controller-support`; suite `cli`, block `60-c1-controllers.sh`)
@@ -172,3 +175,4 @@ and started with `--fremont`. Automated: `scripts/vmtest.sh` (see the vm-install
| 2026-09-29 | Steamify `release/2.9.1` (CEC driver cache), ISO `feat/steamify` (PRs #2, #3), dev `main` | everything automated incl. hw block 50 (CEC cache) and the B1 boot entry check | **341 pass, 0 fail** in 19 minutes (toggles 42 +1 expected skip, hw 77, cli 55, menu 36, installer 4, Limine 43, systemd-boot 42, GRUB 42) |
| 2026-09-30 | Steamify 2.9.6 (`steamify-cachyos` main `d93f9ea`), the official ISO `steamify-cachyos-2.9.6-260930-x86_64.iso` from git.upriser.nl (sha256 `4a94f308…aec41`), dev `main`; on the PC, headless (`CI=1`/`VM_HEADLESS=1`), `MAX_PARALLEL=5` | everything automated: B1-B8 (3 loaders, `--install` from the new ISO), cli, menu, hw, installer, toggles (base VM from the same ISO with `VM_STEAMIFY=skip`) | **341 pass, 0 fail** (toggles 42 +1 expected skip, hw 77, cli 55, menu 36, installer 4, Limine 43, systemd-boot 42, GRUB 42). Found on the way (test setup, not Steamify or the ISO): with five VMs at once the loaders' first boot took longer than `waitssh` waited (5 min), so all three stopped with `FAIL no SSH` although the VMs were up; `waitssh` now waits up to 15 minutes and the loaders were run again (install kept) |
| 2026-10-01 | Steamify `feature/extended-controller-support` (7dae14c; on top of `feature/nvidia-gaming-fix` d0e4d8c, 2.9.7), plain CachyOS ISO 260809 (VM `~/vms/steamify-vm`, `vminstall.sh --iso`), dev `main` + the nvidia suite; on the PC (native CachyOS, KVM), headless | N1-N5 (new suite `nvidia`), C1-C3 (cli block 60), R1.1-R1.6/R1.10, H1-H5 and the CEC/CEC cache blocks, R2.1, toggles | **269 pass, 0 fail**: cli 65, nvidia 43, menu 37, hw 78, installer 4, toggles 42. Found on the way (test side, not Steamify): R1.1 and H3 pressed menu rows by number and the new Extended controller support row shifted them (now by name); the N4 check for the parameter in `/boot/limine.conf` must ignore snapper's snapshot entries, which keep the command line of their time. The kernel part (parameters, early-load file, hook, initramfs) behaves in a real Limine VM; the real driver and picture are only checked on the RTX 5080 PC |
| 2026-10-14 | Steamify `release/2.12.0` (dc189dc), plain CachyOS VM `~/vms/steamify-vm` (new ssh key: the old throwaway one was gone, authorized in the `ssh-ready` snapshot), dev `main` + the new nvidia suite; on the laptop (Ubuntu, KVM), headless | cli, menu, hw, installer, toggles, nvidia (N1, G1, N2-N5 rewritten for 2.12.0); boot loaders and the plain-PC install check not run (need the Steamify ISO) | **292 pass, 0 fail** (cli 65, menu 37, hw 78, installer 4, toggles 42, nvidia 66). Before the rewrite the old nvidia suite failed 8 checks, all because "Gaming on NVIDIA" is gone in 2.12.0. Test side: gamescope's smoke test needs a Vulkan device, so the VM gets `vulkan-swrast`; after a reboot the same gamescope fails with `vkAllocateMemory failed (-2)` on lavapipe in this VM (before the reboot it passes), so the offline-reinstall check runs before the reboot. Not seen on real hardware yet (N6) |
+8 -12
View File
@@ -1,18 +1,14 @@
# N1: an NVIDIA PC (fake GPU): the menu hides the SteamOS conversion and its gamescope options, shows Gaming on NVIDIA, its
# Big Picture option and Single user mode. Covers TESTPLAN N1.
# N1: an NVIDIA PC (fake GPU), 2.12.0: the menu is the SteamOS conversion's, as on any PC. "Gaming on NVIDIA" (nvidia, bigpicture,
# nvsilent) is not offered any more. Covers TESTPLAN N1.
fake_nvidia
out="$(sf --defaults --list)"
ids="$(python3 -c 'import json,sys; d=json.load(sys.stdin); print(" ".join(sorted(i["id"] for i in d)))' <<< "$out" 2>/dev/null)"
[[ -n "$ids" ]] && pass "N1 --defaults --list is valid JSON: $ids" || { fail "N1 --defaults --list is not JSON: $(echo "$out" | head -c 300)"; exit 0; }
for i in nvidia bigpicture single; do [[ " $ids " == *" $i "* ]] && pass "N1 $i is offered" || fail "N1 $i is missing"; done
for i in gaming boot glyphs; do [[ " $ids " == *" $i "* ]] && fail "N1 $i is offered on an NVIDIA PC" || pass "N1 $i is hidden"; done
python3 -c '
import json,sys
d={i["id"]:i for i in json.load(sys.stdin)}
ok = d["bigpicture"]["parent"]=="nvidia" and d["nvidia"]["on"] and d["bigpicture"]["on"] and d["single"]["on"]
sys.exit(0 if ok else 1)' <<< "$out" && pass "N1 Big Picture is a sub-option of Gaming on NVIDIA, all three preselected" || fail "N1 parent or preselection wrong"
for i in gaming boot glyphs single; do [[ " $ids " == *" $i "* ]] && pass "N1 $i is offered on an NVIDIA PC" || fail "N1 $i is missing on an NVIDIA PC"; done
for i in nvidia bigpicture nvsilent; do [[ " $ids " == *" $i "* ]] && fail "N1 $i (Gaming on NVIDIA) is still offered" || pass "N1 $i is hidden"; done
st="$(sf --backend status)"
python3 -c 'import json,sys; d=json.load(sys.stdin); ids=[i["id"] for i in d.get("items",d)]; sys.exit(1 if "gaming" in ids else 0)' <<< "$st" 2>/dev/null && pass "N1 --backend status (the app) has no conversion row" || fail "N1 --backend status lists the conversion"
# Without a NVIDIA GPU nothing changes: the conversion is offered, Gaming on NVIDIA is not.
python3 -c 'import json,sys; d=json.load(sys.stdin); ids=[i["id"] for i in d.get("items",d)]; sys.exit(0 if "gaming" in ids and "nvidia" not in ids else 1)' <<< "$st" 2>/dev/null && pass "N1 --backend status (the app) has the conversion row and no Gaming on NVIDIA row" || fail "N1 --backend status rows wrong"
# Without a NVIDIA GPU the menu is the same.
out2="$(NVIDIA_DRM_DIR=/nonexistent sf --defaults --list)"
python3 -c 'import json,sys; ids=[i["id"] for i in json.load(sys.stdin)]; sys.exit(0 if "gaming" in ids and "nvidia" not in ids and "bigpicture" not in ids else 1)' <<< "$out2" && pass "N1 no NVIDIA GPU: the conversion is offered, Gaming on NVIDIA is not" || fail "N1 no-NVIDIA menu wrong"
ids2="$(python3 -c 'import json,sys; print(" ".join(sorted(i["id"] for i in json.load(sys.stdin))))' <<< "$out2" 2>/dev/null)"
[[ "$ids2" == "$ids" ]] && pass "N1 no NVIDIA GPU: the same menu" || fail "N1 menus differ: [$ids] vs [$ids2]"
@@ -0,0 +1,67 @@
# G1: lib/gamescope-nvidia.sh's pieces without installing anything (the patched gamescope on NVIDIA): version compare, CPU variant, the
# pinned checksums, a damaged package and no GitHub, the update notice, the pre-flight, the failure reminder, the environment files
# and the display wrapper. Covers TESTPLAN G1.
fake_nvidia
T=/var/tmp/gsn-test; rm -rf "$T"; mkdir -p "$T/state" "$T/cache" "$T/backup"
export STATE_DIR="$T/state" XDG_CACHE_HOME="$T/cache" GSN_BACKUP_DIR="$T/backup" GSN_RELEASES=http://127.0.0.1:9
gsn_newer 3.16.32-1 3.16.31-3 && gsn_newer 3.17.0-1 3.16.31-3 && gsn_newer 3.16.31-4 3.16.31-3 && pass "G1 gsn_newer: later versions are newer" || fail "G1 gsn_newer later"
! gsn_newer 3.16.31-3 3.16.31-3 && ! gsn_newer 3.16.30-9 3.16.31-3 && pass "G1 gsn_newer: equal and older are not" || fail "G1 gsn_newer equal/older"
v="$(gsn_cpu_variant)"; [[ "$v" =~ ^(generic|v3|v4|znver4)$ ]] && pass "G1 gsn_cpu_variant: $v" || fail "G1 gsn_cpu_variant: '$v'"
bad=""; for v in generic v3 v4 znver4; do [[ "${GSN_SHA256[$v]}" =~ ^[0-9a-f]{64}$ ]] || bad+=" $v"; done
[[ -z "$bad" ]] && pass "G1 the pinned sha256 of every CPU level is a hash" || fail "G1 pinned sha256 broken for:$bad"
pk="$(sed -n 's/^pkgver=//p' patches/gamescope-nvidia.PKGBUILD)-$(sed -n 's/^pkgrel=//p' patches/gamescope-nvidia.PKGBUILD)"
[[ "$pk" == "$GSN_VERSION" ]] && pass "G1 the PKGBUILD in patches/ builds the pinned version ($GSN_VERSION)" || fail "G1 PKGBUILD $pk != pin $GSN_VERSION"
[[ "$(gsn_sha_of "$GSN_VERSION" x v3)" == "${GSN_SHA256[v3]}" ]] && pass "G1 gsn_sha_of: the pinned version needs no network" || fail "G1 gsn_sha_of pinned"
# No GitHub (port 9 refuses): no latest tag, and a damaged copy is never used.
gsn_latest_tag 2 >/dev/null && fail "G1 gsn_latest_tag answered without GitHub" || pass "G1 gsn_latest_tag: nothing when GitHub can't be reached"
f="$GSN_PKG-$GSN_VERSION-generic.pkg.tar.zst"
echo "not a package" > "$GSN_BACKUP_DIR/$f"
out="$(gsn_fetch_package generic 2>&1)"; rc=$?
[[ $rc -ne 0 ]] && pass "G1 offline with a damaged backup copy: no package (the checksum refuses it)" || fail "G1 damaged copy accepted: $out"
[[ "$out" == *"failed"* ]] && pass "G1 and says so" || fail "G1 no message: $out"
# A copy whose hash matches the table is used.
saved="${GSN_SHA256[generic]}"; GSN_SHA256[generic]="$(sha256sum "$GSN_BACKUP_DIR/$f" | awk '{print $1}')"
[[ "$(gsn_fetch_package generic 2>/dev/null)" == "$GSN_BACKUP_DIR/$f" ]] && pass "G1 offline: the copy that came with Steamify is used when its hash matches" || fail "G1 backup copy with a matching hash not used"
GSN_SHA256[generic]="$saved"; rm -f "$GSN_BACKUP_DIR/$f"
# The update notice (the installed package is faked).
gsn_package_installed() { return 0; }; gsn_installed_version() { echo 3.16.31-3; }
state_set gamescope_nvidia checked "$(date +%s)"
state_set gamescope_nvidia latest 3.16.32-1; gsn_update_pending && pass "G1 a newer release than the installed package: update pending" || fail "G1 update not pending"
state_set gamescope_nvidia latest 3.16.31-3; gsn_update_pending && fail "G1 update pending for the same version" || pass "G1 the same version: no update"
state_set gamescope_nvidia checked 1
gsn_update_pending; [[ "$(state_get gamescope_nvidia checked 0)" -gt 1 ]] && pass "G1 the look at GitHub is remembered, offline changes nothing" || fail "G1 check time not stored"
unset -f gsn_package_installed gsn_installed_version
# The pre-flight.
msg="$(gsn_preflight)" && pass "G1 gsn_preflight passes on a normal PC" || fail "G1 gsn_preflight: $msg"
sudo touch /var/lib/pacman/db.lck; msg="$(gsn_preflight)"; rc=$?; sudo rm -f /var/lib/pacman/db.lck
[[ $rc -ne 0 && "$msg" == *db.lck* ]] && pass "G1 gsn_preflight refuses while pacman is locked" || fail "G1 preflight with a lock: rc=$rc $msg"
# The failure reminder.
gsn_fail_mark "the test failure" >/dev/null 2>&1
[[ "$(gsn_fail_note 2>&1)" == *"the test failure"* ]] && pass "G1 a failed setup is remembered and reminded" || fail "G1 fail note: $(gsn_fail_note 2>&1)"
state_set gamescope_nvidia failed ""
[[ -z "$(gsn_fail_note 2>&1)" ]] && pass "G1 no reminder once it worked" || fail "G1 stale reminder"
# The environment files.
GSN_ENV_D="$T/env/99.conf"; GSN_SESSION_ENV="$T/sess/environment"
mkdir -p "$T/sess"; echo 'OTHER=1' > "$GSN_SESSION_ENV"
gsn_env_enable; gsn_env_enable
[[ "$(grep -c "^$GSN_ENV_LINE\$" "$GSN_SESSION_ENV")" == 1 ]] && grep -qx 'OTHER=1' "$GSN_SESSION_ENV" && grep -qx "$GSN_ENV_LINE" "$GSN_ENV_D" && pass "G1 env files: set once however often, other lines kept" || fail "G1 env enable: $(cat "$GSN_SESSION_ENV")"
gsn_env_disable
[[ ! -e "$GSN_ENV_D" ]] && ! grep -q gbm_scanout "$GSN_SESSION_ENV" && grep -qx 'OTHER=1' "$GSN_SESSION_ENV" && pass "G1 env files: turned off, other lines kept" || fail "G1 env disable"
# The display wrapper.
GSN_DISPLAY_WRAPPER="$T/bin/gamescope"; GSN_DISPLAY_DROPIN="$T/dropin/gamescope-session.service.d/steamify-display.conf"
gsn_display_enable
[[ -x "$GSN_DISPLAY_WRAPPER" && -f "$GSN_DISPLAY_DROPIN" ]] && gsn_display_status && pass "G1 display wrapper and drop-in installed" || fail "G1 display enable"
grep -q "^ExecStart=/usr/bin/bash -c 'PATH=\"$T/bin:" "$GSN_DISPLAY_DROPIN" && pass "G1 the drop-in puts the wrapper first in the session's PATH" || fail "G1 drop-in: $(cat "$GSN_DISPLAY_DROPIN")"
bash -n "$GSN_DISPLAY_WRAPPER" && pass "G1 the wrapper is valid bash" || fail "G1 wrapper syntax"
gsn_display_disable
[[ ! -e "$GSN_DISPLAY_WRAPPER" && ! -e "$GSN_DISPLAY_DROPIN" ]] && pass "G1 display wrapper and drop-in removed" || fail "G1 display disable"
echo '#!/bin/sh' > "$GSN_DISPLAY_WRAPPER"; gsn_display_disable
[[ -e "$GSN_DISPLAY_WRAPPER" ]] && pass "G1 a foreign file at the wrapper's path is left alone" || fail "G1 foreign file removed"
rm -rf "$T"
+60 -45
View File
@@ -1,51 +1,66 @@
# N2-N5: Gaming on NVIDIA + Big Picture + Single user mode on a fake NVIDIA PC, for real: pacman installs Steam, the SDDM autologin,
# the boot loader files and the initramfs, then a reboot into Plasma, then everything off again and a second reboot.
# Covers TESTPLAN N2 (apply), N3 (after the reboot), N4 (turn off), N5 (after the second reboot).
# N2-N5 (2.12.0): the SteamOS conversion on a fake NVIDIA PC, for real (pacman, the patched gamescope from GitHub, limine, initramfs).
# Covers TESTPLAN N2 (failure leaves the PC as it was), N3 (apply), N4 (the update path from "Gaming on NVIDIA"), N5 (offline reinstall
# from the cache, turn off).
unit='~/.config/systemd/user/steamify-steam-autostart.service'
g() { guest "$@"; }
yes_() { [[ "$(g "$1 && echo YES || echo NO" | tail -n 1)" == YES ]]; } # a guest condition
info "N2 applying nvidia,bigpicture,single (Steam, SDDM, initramfs: several minutes)..."
rc="$(g 'fake_nvidia; sf --defaults --options nvidia,bigpicture,single > /tmp/n2.log; echo "rc=$?"' | tail -n 1)"
[[ "$rc" == rc=0 ]] && pass "N2 apply exit 0" || { fail "N2 apply: $rc: $(g 'tail -n 15 /tmp/n2.log')"; return 0 2>/dev/null || exit 0; }
yes_ 'pacman -Q steam >/dev/null 2>&1' && pass "N2 Steam is installed" || fail "N2 Steam missing"
yes_ "grep -qx 'ExecStart=/usr/bin/steam -gamepadui' $unit" && pass "N2 the autostart unit starts Steam with -gamepadui" || fail "N2 unit: $(g "cat $unit")"
yes_ 'systemctl --user is-enabled -q steamify-steam-autostart.service' && pass "N2 the unit is enabled" || fail "N2 unit not enabled"
[[ "$(g 'kreadconfig6 --file ksmserverrc --group General --key loginMode' | tail -n 1)" == emptySession ]] && pass "N2 Plasma starts with an empty session" || fail "N2 loginMode"
g 'is nvidia && is bigpicture && echo ON' | grep -qx ON && pass "N2 nvidia and bigpicture report on" || fail "N2 status functions"
yes_ "grep -q 'nvidia-drm.modeset=1 nvidia-drm.fbdev=1' /etc/default/limine" && pass "N2 the kernel parameters are in /etc/default/limine" || fail "N2 limine defaults"
yes_ "sudo grep -q 'nvidia-drm.fbdev=1' /boot/limine.conf" && pass "N2 and in the generated /boot/limine.conf" || fail "N2 limine.conf"
yes_ 'test -f /etc/mkinitcpio.conf.d/90-steamify-nvidia.conf && test -x /usr/local/libexec/steamify-nvidia-initramfs && test -f /etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook' && pass "N2 early-load file, hook and its script installed" || fail "N2 initramfs files"
yes_ 'sudo find /boot -name "initramfs*" -exec sh -c "lsinitcpio {} | grep -q nvidia" \; -print | grep -q .' && pass "N2 the NVIDIA modules are in the initramfs" || fail "N2 initramfs has no nvidia modules"
yes_ 'systemctl is-enabled -q sddm.service' && pass "N2 SDDM is the login manager" || fail "N2 sddm not enabled"
yes_ "grep -qx 'Session=plasma.desktop' /etc/sddm.conf.d/zzz-steamify-autologin.conf && grep -qx \"User=\$USER\" /etc/sddm.conf.d/zzz-steamify-autologin.conf" && pass "N2 SDDM autologin: the user into the Plasma session" || fail "N2 autologin file: $(g 'cat /etc/sddm.conf.d/zzz-steamify-autologin.conf')"
yes_ 'is single' && pass "N2 single user mode is on" || fail "N2 single not on"
g 'fake_nvidia; sf --defaults --options nvidia,bigpicture,single | tail -n 3' | grep -qiE 'nothing|already|exit: 0' && pass "N2 a second run is quiet" || info "N2 second run: $(g 'fake_nvidia; sf --defaults --options nvidia,bigpicture,single | tail -n 3')"
reboot_guest && pass "N3 the VM is back after the reboot" || { fail "N3 no ssh after the reboot"; return 0 2>/dev/null || exit 0; }
up=""; for _ in $(seq 40); do vm_ssh "pgrep -u $VM_USER -x plasmashell" >/dev/null 2>&1 && { up=1; break; }; sleep 3; done
[[ -n "$up" ]] && pass "N3 Plasma straight after the boot (SDDM autologin, no greeter)" || fail "N3 no plasmashell after the reboot"
yes_ '! pgrep -x sddm-greeter >/dev/null' && pass "N3 no greeter running" || fail "N3 sddm-greeter is running"
yes_ 'grep -q "nvidia-drm.modeset=1" /proc/cmdline && grep -q "nvidia-drm.fbdev=1" /proc/cmdline' && pass "N3 the kernel parameters are on the running command line" || fail "N3 cmdline: $(g 'cat /proc/cmdline')"
yes_ 'systemctl is-active -q sddm.service' && pass "N3 sddm is the running display manager" || fail "N3 sddm not active"
yes_ 'journalctl --user -b --no-pager -u steamify-steam-autostart.service | grep -qiE "Started|Starting"' && pass "N3 the Steam autostart unit was started at login" || fail "N3 unit never started: $(g 'systemctl --user status steamify-steam-autostart.service 2>&1 | head -n 8')"
[[ "$(g 'kreadconfig6 --file ksmserverrc --group General --key loginMode' | tail -n 1)" == emptySession ]] && pass "N3 the empty session setting survived" || fail "N3 loginMode after the reboot"
# N2: a locked pacman database: the run fails, says why and changes nothing (the pre-flight's own messages are checked in G1).
g 'sudo touch /var/lib/pacman/db.lck'
rc="$(g 'fake_nvidia; sf --defaults --options gaming > /tmp/n2.log; echo "rc=$?"' | tail -n 1)"
g 'sudo rm -f /var/lib/pacman/db.lck'
[[ "$rc" != rc=0 ]] && pass "N2 a locked pacman database: the run fails ($rc)" || fail "N2 the run passed with pacman locked"
yes_ 'grep -q "db.lck" /tmp/n2.log' && pass "N2 and names the lock" || fail "N2 no reason in the log: $(g 'tail -n 8 /tmp/n2.log')"
yes_ '! pacman -Q steamify-gamescope-nvidia >/dev/null 2>&1 && ! grep -q nvidia-drm /etc/default/limine' && pass "N2 nothing was installed or changed" || fail "N2 the failed run changed the PC"
info "N4 turning everything off (only notify stays)..."
rc="$(g 'fake_nvidia; sf --defaults --options notify > /tmp/n4.log; echo "rc=$?"' | tail -n 1)"
[[ "$rc" == rc=0 ]] && pass "N4 turn-off exit 0" || { fail "N4 turn-off: $rc: $(g 'tail -n 15 /tmp/n4.log')"; return 0 2>/dev/null || exit 0; }
yes_ '! pacman -Q steam >/dev/null 2>&1' && pass "N4 Steam is removed again (Steamify installed it)" || fail "N4 Steam is still installed"
yes_ "! test -e $unit" && pass "N4 the autostart unit is gone" || fail "N4 unit still there"
[[ -z "$(g 'kreadconfig6 --file ksmserverrc --group General --key loginMode' | tail -n 1)" ]] && pass "N4 loginMode is back to not set" || fail "N4 loginMode: $(g 'kreadconfig6 --file ksmserverrc --group General --key loginMode')"
yes_ '! grep -q nvidia-drm /etc/default/limine' && pass "N4 the kernel parameters are gone from /etc/default/limine" || fail "N4 limine defaults still have them"
# Snapshot entries (snapper's, rootflags=.../.snapshots/N/snapshot) keep the command line of their time: a snapshot of the state with the
# parameters is meant to boot that state. Only the current boot entries count.
yes_ "! sudo grep 'cmdline:' /boot/limine.conf | grep -v '\.snapshots/' | grep -q nvidia-drm" && pass "N4 and from the current entries in /boot/limine.conf (snapshot entries keep their old command line)" || fail "N4 limine.conf still has them: $(g "sudo grep 'cmdline:' /boot/limine.conf | grep -v '\.snapshots/' | cut -c1-150" | tr '\n' '|')"
yes_ '! test -e /etc/mkinitcpio.conf.d/90-steamify-nvidia.conf && ! test -e /usr/local/libexec/steamify-nvidia-initramfs && ! test -e /etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook' && pass "N4 early-load file, hook and script removed" || fail "N4 initramfs files remain"
yes_ '! test -e /etc/sddm.conf.d/zzz-steamify-autologin.conf' && pass "N4 the SDDM autologin file is gone" || fail "N4 autologin file remains"
yes_ 'systemctl is-enabled -q plasmalogin.service && ! systemctl is-enabled -q sddm.service' && pass "N4 plasma-login-manager is the login manager again" || fail "N4 login manager: $(g 'systemctl show -p Id --value display-manager')"
yes_ '! is nvidia && ! is bigpicture && ! is single' && pass "N4 nvidia, bigpicture and single report off" || fail "N4 status still on"
# The VM has no GPU: gamescope's smoke test needs a Vulkan device, so the software one (lavapipe) goes in first, as a real PC has its driver.
g 'sudo pacman -S --needed --noconfirm vulkan-swrast > /tmp/swrast.log 2>&1' >/dev/null
reboot_guest && pass "N5 the VM is back after the second reboot" || { fail "N5 no ssh after the second reboot"; return 0 2>/dev/null || exit 0; }
up=""; for _ in $(seq 40); do vm_ssh "pgrep -u $VM_USER -x plasmashell" >/dev/null 2>&1 && { up=1; break; }; sleep 3; done
[[ -n "$up" ]] && pass "N5 Plasma comes up (the test autologin of plasma-login-manager)" || fail "N5 no plasmashell after the second reboot"
yes_ '! grep -q "nvidia-drm" /proc/cmdline' && pass "N5 the kernel parameters are off the command line" || fail "N5 cmdline still has them"
# N4 first state: "Gaming on NVIDIA" as 2.11 left it (Steam on the desktop, started at login).
info "N4 setting up the 2.11 state (Gaming on NVIDIA: Steam, autostart unit)..."
g 'sudo pacman -S --needed --noconfirm steam > /tmp/steam.log 2>&1; fake_nvidia; nvidia_write_unit -gamepadui && user_systemctl enable steamify-steam-autostart.service' >/dev/null
yes_ 'fake_nvidia; nvidia_status' && pass "N4 the old Gaming on NVIDIA state is on" || fail "N4 could not set the old state up"
python3 -c 'import json,sys; d={i["id"]:i for i in json.load(sys.stdin)["items"]}; sys.exit(0 if d["gaming"].get("update") and d["gaming"]["on"] else 1)' <<< "$(g 'fake_nvidia; sf --backend status' | sed -n '/^[\[{]/,$p')" 2>/dev/null && pass "N4 the menu shows the conversion as an update, ticked" || info "N4 menu: $(g 'fake_nvidia; sf --backend status' | head -c 400)"
# N3: apply the conversion.
info "N3 applying gaming (Steam, gamescope-session, the patched gamescope from GitHub, initramfs: several minutes)..."
rc="$(g 'fake_nvidia; sf --defaults --options gaming > /tmp/n3.log; echo "rc=$?"' | tail -n 1)"
[[ "$rc" == rc=0 ]] && pass "N3 apply exit 0" || { fail "N3 apply: $rc: $(g 'tail -n 20 /tmp/n3.log')"; return 0 2>/dev/null || exit 0; }
yes_ '! test -e ~/.config/systemd/user/steamify-steam-autostart.service && ! systemctl --user is-enabled -q steamify-steam-autostart.service' && pass "N4 the old autostart unit is gone (Steam no longer starts on the desktop)" || fail "N4 the autostart unit is still there"
yes_ 'pacman -Q steam >/dev/null 2>&1' && pass "N4 Steam stays installed" || fail "N4 Steam was removed"
ver="$(g 'pacman -Q steamify-gamescope-nvidia' | tail -n 1 | awk '{print $2}')"
pin="$(g 'fake_nvidia; echo $GSN_VERSION' | tail -n 1)"
[[ -n "$ver" && "$(printf '%s\n%s\n' "$pin" "$ver" | sort -V | head -n 1)" == "$pin" ]] && pass "N3 the patched gamescope is installed: $ver (pinned $pin or newer)" || fail "N3 patched gamescope: '$ver' (pin $pin)"
yes_ 'gamescope --version 2>&1 | grep -qi gamescope; pacman -Qi steamify-gamescope-nvidia | grep -q "^Provides.*gamescope"' && pass "N3 it provides gamescope (the stock one is replaced)" || fail "N3 not providing gamescope"
yes_ 'fake_nvidia; gsn_smoke_test' && pass "N3 the smoke test: the installed gamescope starts headless and runs a program" || fail "N3 smoke test failed"
yes_ 'fake_nvidia; gsn_status && is gaming' && pass "N3 gaming and the patched gamescope report on" || fail "N3 status"
yes_ 'grep -qx gamescope_drm_gbm_scanout=1 ~/.config/environment.d/99-steamify-gamescope-nvidia.conf && grep -qx gamescope_drm_gbm_scanout=1 ~/.config/gamescope-session/environment' && pass "N3 the GBM scan-out setting is in the session's environment files" || fail "N3 env files"
yes_ 'fake_nvidia; gsn_display_status' && pass "N3 the display-mode wrapper and its drop-in are installed" || fail "N3 display wrapper"
yes_ 'systemctl --user cat gamescope-session.service 2>/dev/null | grep -q "steamify-display\|\.local/share/steamify/bin"' && pass "N3 the gaming session unit uses the wrapper (drop-in loaded)" || info "N3 gamescope-session.service not loadable here: $(g 'systemctl --user cat gamescope-session.service 2>&1 | tail -n 4')"
yes_ "grep -q 'nvidia-drm.modeset=1 nvidia-drm.fbdev=1' /etc/default/limine && sudo grep -q 'nvidia-drm.fbdev=1' /boot/limine.conf" && pass "N3 the DRM kernel parameters are in /etc/default/limine and /boot/limine.conf" || fail "N3 kernel parameters"
yes_ 'test -f /etc/mkinitcpio.conf.d/90-steamify-nvidia.conf && test -f /etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook' && pass "N3 early-load file and initramfs hook installed" || fail "N3 initramfs files"
yes_ 'sudo find /boot -name "initramfs*" -exec sh -c "lsinitcpio {} | grep -q nvidia" \; -print | grep -q .' && pass "N3 the NVIDIA modules are in the initramfs" || fail "N3 initramfs has no nvidia modules"
yes_ '! grep -q "failed" <<< "$(fake_nvidia; state_get gamescope_nvidia failed)" && [[ -z "$(fake_nvidia; state_get gamescope_nvidia failed)" ]]' && pass "N3 the earlier failure mark is cleared" || fail "N3 failure mark remains"
yes_ 'grep -q "Patched gamescope installed" /tmp/n3.log' && pass "N3 the log says the patched gamescope was installed" || info "N3 log: $(g 'grep -i gamescope /tmp/n3.log | tail -n 5')"
out="$(g 'fake_nvidia; sf --defaults --options gaming')"
echo "$out" | grep -qiE 'Downloading|Installing|Building' && fail "N3 a second run downloads or installs again: $(echo "$out" | tail -n 5)" || pass "N3 a second run changes nothing (no download, no install)"
# N5 (before the reboot: after a boot lavapipe in this VM fails vkAllocateMemory for gamescope, see TESTPLAN G-notes): the package is gone and GitHub can't be reached: the copy in the cache is installed again, and still starts.
info "N5 removing the patched gamescope, no GitHub: reinstall from the download cache..."
rc="$(g 'fake_nvidia; sudo pacman -Rdd --noconfirm steamify-gamescope-nvidia >/dev/null 2>&1; GSN_RELEASES=http://127.0.0.1:9 gsn_install_package > /tmp/n5.log 2>&1; echo "rc=$?"' | tail -n 1)"
[[ "$rc" == rc=0 ]] && yes_ 'pacman -Q steamify-gamescope-nvidia >/dev/null 2>&1' && pass "N5 offline: installed again from the cache" || fail "N5 offline reinstall ($rc): $(g 'tail -n 8 /tmp/n5.log')"
yes_ 'fake_nvidia; gsn_smoke_test' && pass "N5 and it starts" || fail "N5 smoke test after the reinstall"
reboot_guest && pass "N3 the VM boots with the DRM parameters and the NVIDIA initramfs" || { fail "N3 no ssh after the reboot"; return 0 2>/dev/null || exit 0; }
yes_ 'grep -q "nvidia-drm.modeset=1" /proc/cmdline && grep -q "nvidia-drm.fbdev=1" /proc/cmdline' && pass "N3 the parameters are on the running command line" || fail "N3 cmdline: $(g 'cat /proc/cmdline')"
# N5: turn off.
info "N5 turning the conversion off..."
rc="$(g 'fake_nvidia; sf --defaults --options notify > /tmp/n5off.log; echo "rc=$?"' | tail -n 1)"
[[ "$rc" == rc=0 ]] && pass "N5 turn-off exit 0" || { fail "N5 turn-off: $rc: $(g 'tail -n 15 /tmp/n5off.log')"; return 0 2>/dev/null || exit 0; }
yes_ '! test -e ~/.config/environment.d/99-steamify-gamescope-nvidia.conf && ! grep -qs gbm_scanout ~/.config/gamescope-session/environment' && pass "N5 the GBM setting is gone from both files" || fail "N5 env files remain"
yes_ '! test -e ~/.local/share/steamify/bin/gamescope && ! test -e ~/.config/systemd/user/gamescope-session.service.d/steamify-display.conf' && pass "N5 the display wrapper and drop-in are gone" || fail "N5 display files remain"
yes_ '! grep -q nvidia-drm /etc/default/limine' && pass "N5 the kernel parameters are gone from /etc/default/limine" || fail "N5 limine defaults"
yes_ "! sudo grep 'cmdline:' /boot/limine.conf | grep -v '\.snapshots/' | grep -q nvidia-drm" && pass "N5 and from the current entries of /boot/limine.conf" || fail "N5 limine.conf"
yes_ '! test -e /etc/mkinitcpio.conf.d/90-steamify-nvidia.conf && ! test -e /etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook' && pass "N5 early-load file and hook removed" || fail "N5 initramfs files remain"
yes_ 'pacman -Q steamify-gamescope-nvidia >/dev/null 2>&1' && pass "N5 the patched gamescope package stays (like the conversion's other packages)" || fail "N5 package removed"
yes_ '! is gaming' && pass "N5 gaming reports off" || fail "N5 gaming still on"
+1 -1
View File
@@ -6,7 +6,7 @@ pass() { echo "PASS $*"; }; fail() { echo "FAIL $*"; }; skip() { echo "SKIP $*";
sudo mountpoint -q /mnt || sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt
cd /mnt || exit 1
export SCRIPT_DIR=/mnt # steamify.sh sets it; the libs alone read patches/ and services/ from it
for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia controllers cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier; do
for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia gamescope-nvidia controllers cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier; do
# shellcheck source=/dev/null
. "lib/$lib.sh" 2>/dev/null
done