feat: scripts/vminstall.sh installs an ssh-ready test VM unattended; TESTPLAN.md; vm-install skill

This commit is contained in:
theupriser committed 2026-09-28 10:07:13 +02:00
1 parent 21547dd7bc
commit 60a2698d02
19 files changed
+705 -72

No files matched your search

+63 -56
View File
@@ -19,101 +19,108 @@ tracked file to it explicitly.
- `curl` and `sha256sum` for `get-iso.sh`.
- Optional: an NVIDIA dGPU for `--nvidia` (PRIME offload of the virgl renderer).
## Quick start
## Quick start: unattended install
```bash
./get-iso.sh # download and verify the latest CachyOS desktop ISO
./run.sh install # first run creates disk.qcow2 (60G) and vars.fd, boots the ISO
./get-iso.sh # latest CachyOS desktop ISO (verified)
VM_DIR=~/vms/steamify-vm scripts/vminstall.sh --fremont # 15-30 min, watch the VM's window
```
Install CachyOS with the **KDE Plasma** desktop and **plasma-login-manager**
as login manager. Power off and snapshot (only while the VM is off):
Installs CachyOS from the ISO without any manual step, with CachyOS's own
headless installer (KDE Plasma, plasma-login-manager, btrfs, Limine,
`linux-cachyos` + `-lts`), and leaves the snapshots `clean` and `ssh-ready`:
sshd with your key, passwordless sudo, autologin into Plasma, English, the
host's timezone. Details: [`.claude/skills/vm-install`](.claude/skills/vm-install/SKILL.md).
- **Login by hand**: your host username, password **`steamify`** (root too).
- **SSH**: `~/.ssh/steamify-vm_ed25519`, made on the first install (it asks:
that key, or one of your own `~/.ssh/*.pub`), then always used. Existing
keys are never overwritten; the VM's host key lives in `$VM_DIR/known_hosts`,
not in `~/.ssh/known_hosts`.
- `$VM_DIR` also records the user, key and Steamify checkout (`vm-user`,
`ssh-key`, `repo-path`); pass the same `VM_DIR` to the other scripts.
- `--iso <file>` installs another archiso-based ISO the same way (the Steam
Machine ISO, later); `--force` replaces an existing VM (asks first).
Snapshots (only while the VM is off; keep vars.fd with the disk):
```bash
qemu-img snapshot -c clean disk.qcow2 && cp vars.fd vars.clean.fd
qemu-img snapshot -a ssh-ready disk.qcow2 && cp vars.ssh-ready.fd vars.fd # restore
```
Boot the installed system (`./run.sh`) and, in the guest, enable SSH with key
auth and passwordless sudo through the read-only `vmtools` share:
### Manual install (fallback)
`./run.sh install` boots the ISO (a first run creates `disk.qcow2`, 60G, and
`vars.fd`). Install CachyOS with **KDE Plasma** and **plasma-login-manager**
through Calamares, power off, `qemu-img snapshot -c clean disk.qcow2 && cp
vars.fd vars.clean.fd`. Boot it (`./run.sh`) and, in the guest:
```bash
sudo mount -t 9p -o trans=virtio,version=9p2000.L vmtools /media && /media/guest-ssh-setup.sh
```
### Adding your SSH key
(sshd, the host's `~/.ssh/*.pub` from `share/host-keys.pub`, passwordless
sudo). Power off, `qemu-img snapshot -c ssh-ready disk.qcow2 && cp vars.fd
vars.ssh-ready.fd`.
`guest-ssh-setup.sh` authorizes the host's public keys. `run.sh` copies them
at every start from `~/.ssh/*.pub` into `share/host-keys.pub` (git-ignored),
which the guest sees as `/media/host-keys.pub`. So:
1. Make sure you have a key on the host; create one if `ls ~/.ssh/*.pub`
shows nothing:
```bash
ssh-keygen -t ed25519
```
2. Start (or restart) the VM with `./run.sh`, so the key is copied into the
share.
3. In the guest, run the setup script (above). It installs and starts
`sshd`, opens port 22 if a firewall is active, adds every host key to
`~/.ssh/authorized_keys` (without duplicates) and gives the guest user
passwordless sudo.
4. Test from the host: `ssh -p 2222 <vm-user>@localhost true` should return
without asking for a password.
If you ran the setup script before the key existed (it prints "No host keys
were shared"), or you want to add another key later, either restart the VM
and run the setup script again, or copy the key over SSH with the guest
user's password:
### The same key on the Steam Machine
```bash
ssh-copy-id -p 2222 <vm-user>@localhost
scripts/steammachine-addkey.sh [user@host] # default: steammachine (~/.ssh/config)
```
If SSH hangs at "banner exchange", `sshd` isn't running in the
guest or a firewall blocks port 22; check with `systemctl is-active sshd` in
the guest.
Power off and snapshot again:
```bash
qemu-img snapshot -c ssh-ready disk.qcow2 && cp vars.fd vars.ssh-ready.fd
```
Connect with `ssh -p 2222 <user>@localhost`. The project repo is shared
read-write as 9p tag `repo`; in the guest:
`sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt`.
authorizes `~/.ssh/steamify-vm_ed25519` on the Steam Machine too (asks its
password once), so one key reaches the VM and the real machine.
### run.sh options
```
[REPO=/path/to/cachyos-gamescope-boot] ./run.sh [install] [--nvidia] [--vulkan] [--fremont]
[REPO=/path/to/steamify-cachyos] ./run.sh [install] [--nvidia] [--vulkan [--amd]] [--fremont]
```
- `install`: boot the installer ISO
- `install`: boot the installer ISO (`VM_ISO`, default `cachyos.iso`)
- `--nvidia`: render the guest's virtio-gpu (virgl) on the host NVIDIA dGPU
- `--vulkan`: expose Vulkan to the guest (venus; unstable)
- `--fremont`: fake the Valve Steam Machine (Fremont) DMI data via `-smbios`
- `REPO` defaults to `$HOME/projects/cachyos-gamescope-boot` (the local clone of
[steamify-cachyos](https://github.com/theupriser/steamify-cachyos))
- `REPO`: the Steamify checkout shared as 9p `repo` (in the guest: `sudo
mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt`); default
`repo-path` next to the disk, else `$HOME/projects/cachyos-gamescope-boot`
- `VM_KERNEL`/`VM_INITRD`/`VM_APPEND` (boot a kernel directly) and
`VM_SERIAL` (serial console log + socket): used by `vminstall.sh`
## Helper scripts
- `scripts/vminstall.sh [--force] [--iso <file>] [--fremont]`: unattended install (above)
- `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/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/vminstallsim.sh [--fresh] [--defaults options]`: Steamify's install-time mode for a
user who never logged in (the Steam Machine ISO's installer step)
- `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/vmcec.sh [--no-sleep]`: HDMI-CEC against a fake TV (vivid)
- `scripts/qmptype.py <qmp.sock> "<text>"` / `scripts/qmpkey.py <qmp.sock> <keys>`: type text / press
keys in the VM (e.g. drive the Steamify app: `down right ctrl-ret ret`)
- `scripts/cmp.sh [save]`: save / diff the guest's KDE configs against a baseline
- `scripts/steammachine-addkey.sh [user@host]`: the VM key on the Steam Machine (above)
They use `VM_USER` (default `theupriser`), `VM_PORT` (`2222`) and `VM_HOST` (`localhost`).
They use `VM_DIR` (default: this repo if it has `disk.qcow2`, else
`~/vms/cachyos-test`), and from it `VM_USER` (`vm-user`, else `theupriser`)
and `VM_SSH_KEY` (`ssh-key`); `VM_PORT` (`2222`), `VM_HOST` (`localhost`).
## Claude Code skill
## Test plan
The full test workflow is documented in
[`.claude/skills/cachyos-vm-testing/SKILL.md`](.claude/skills/cachyos-vm-testing/SKILL.md);
Claude Code picks it up when run from this repo.
[`TESTPLAN.md`](TESTPLAN.md): what to test per release (regression, the app,
new features, Steam Machine hardware faked and real) and the results log.
## Claude Code skills
- [`cachyos-vm-testing`](.claude/skills/cachyos-vm-testing/SKILL.md): the test workflow in the VM
- [`vm-install`](.claude/skills/vm-install/SKILL.md): creating the VM unattended
- [`steam-machine-testing`](.claude/skills/steam-machine-testing/SKILL.md): on the real Steam Machine
- [`steam-machine-iso`](.claude/skills/steam-machine-iso/SKILL.md): the Steam Machine ISO
Claude Code picks them up when run from this repo.