mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 01:00:18 +02:00
tests/frame-container/frame-image.sh extracts rootfs-A from Valve's Frame recovery image (steamdeck-images.steamos.cloud/recovery), mounts it read-only with a throwaway writable layer and starts the image's own sshd, so the iPhone app can pair with and run its server on the real SteamOS for Frame userland. Verified: password pairing then key login in the image's sshd log, the power password check through the image's sudo, status reading SteamOS 0.3.0. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
36 lines
1.9 KiB
Bash
Executable File
36 lines
1.9 KiB
Bash
Executable File
#!/bin/sh
|
|
# Run Valve's own Steam Frame OS, from its recovery image, as an SSH target for
|
|
# testing (see README.md). Run on a Linux host or VM with btrfs, as root:
|
|
# frame-image.sh steamframe-oobe-repair-<build>.img.bz2
|
|
# It extracts the rootfs-A partition, mounts it read-only, adds a throwaway
|
|
# writable layer, and starts the image's own sshd on port 2223 (user steamos,
|
|
# password frame-test-pw). systemctl only records what it's asked.
|
|
set -e
|
|
command -v bzcat >/dev/null && command -v python3 >/dev/null || {
|
|
command -v apt-get >/dev/null && apt-get install -y -qq bzip2 python3 >/dev/null; }
|
|
IMG=${1:?recovery .img.bz2}; RAW=${RAW:-$(dirname "$IMG")/frame-rootfs-A.img}
|
|
if [ ! -f "$RAW" ]; then
|
|
# Partition 3 (rootfs-A) from the image's GPT: start and size in 512-byte sectors.
|
|
set -- $(bzcat "$IMG" | head -c 1048576 | python3 -c '
|
|
import struct,sys; d=sys.stdin.buffer.read(); e=d[1024+2*128:1024+3*128]
|
|
a,b=struct.unpack("<QQ",e[32:48]); print(a, b-a+1)')
|
|
bzcat "$IMG" | tail -c +$(( $1 * 512 + 1 )) | head -c $(( $2 * 512 )) > "$RAW"
|
|
fi
|
|
R=/mnt/frame; O=/var/lib/frame-ovl; M=/srv/frame
|
|
mkdir -p $R $O/upper $O/work $M
|
|
mountpoint -q $R || mount -o ro -t btrfs "$(losetup -f --show -r "$RAW")" $R
|
|
mountpoint -q $M || mount -t overlay overlay -o lowerdir=$R,upperdir=$O/upper,workdir=$O/work $M
|
|
for d in proc sys dev dev/pts; do mountpoint -q $M/$d || mount --rbind /$d $M/$d; done
|
|
mountpoint -q $M/run || mount -t tmpfs tmpfs $M/run
|
|
mountpoint -q $M/tmp || mount -t tmpfs tmpfs $M/tmp
|
|
mkdir -p $M/run/sshd $M/home/steamos $M/usr/local/bin
|
|
chroot $M chown 1000:1000 /home/steamos
|
|
echo 'steamos:frame-test-pw' | chroot $M chpasswd
|
|
chroot $M ssh-keygen -A >/dev/null
|
|
# No systemd here: systemctl records power requests instead of acting.
|
|
printf '#!/bin/sh\necho "systemctl $*" >> /tmp/power-requests.log\n' > $M/usr/local/bin/systemctl
|
|
chmod +x $M/usr/local/bin/systemctl
|
|
pkill -f "[s]shd -p 2223" 2>/dev/null || true
|
|
chroot $M /usr/bin/sshd -p 2223 -E /tmp/sshd.log
|
|
echo up
|