diff --git a/.gitignore b/.gitignore index 28c9d3f..19dc8f1 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ share/* *.tmp host-keys.pub __pycache__/ +!share/golden/ diff --git a/CHANGELOG.md b/CHANGELOG.md index ac4fde0..69df759 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes, per version and per commit. Versions follow [Semantic Versioning](https://semver.org/) and were numbered from the start of the history. +## Unreleased + +- **feat: `share/golden/`: a no-VM sandbox (bubblewrap, fake `/etc` `/sys` `$HOME`, shim `pacman` `systemctl` `sudo` `uname` `modinfo`) and golden `--backend status` and apply `plan` output of the bash 2.11.1 backend for an AMD PC, an NVIDIA PC and a Steam Machine; `record.sh` records, `record.sh check` compares (the Go refactor's safety net)** + ## 0.5.0 - 2026-10-02 The whole automated test (boot loaders plus suites), the Steamify ISO pipeline, diff --git a/share/golden/expected/amd-pc.plan-gaming-desktop.json b/share/golden/expected/amd-pc.plan-gaming-desktop.json new file mode 100644 index 0000000..d24b606 --- /dev/null +++ b/share/golden/expected/amd-pc.plan-gaming-desktop.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["gaming","boot"]} diff --git a/share/golden/expected/amd-pc.plan-gaming.json b/share/golden/expected/amd-pc.plan-gaming.json new file mode 100644 index 0000000..feba85d --- /dev/null +++ b/share/golden/expected/amd-pc.plan-gaming.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["gaming"]} diff --git a/share/golden/expected/amd-pc.plan-nothing.json b/share/golden/expected/amd-pc.plan-nothing.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/amd-pc.plan-nothing.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/amd-pc.plan-nvidia.json b/share/golden/expected/amd-pc.plan-nvidia.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/amd-pc.plan-nvidia.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/amd-pc.plan-poweroff.json b/share/golden/expected/amd-pc.plan-poweroff.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/amd-pc.plan-poweroff.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/amd-pc.plan-single.json b/share/golden/expected/amd-pc.plan-single.json new file mode 100644 index 0000000..f05b90a --- /dev/null +++ b/share/golden/expected/amd-pc.plan-single.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["gaming","single"]} diff --git a/share/golden/expected/amd-pc.status.json b/share/golden/expected/amd-pc.status.json new file mode 100644 index 0000000..6019375 --- /dev/null +++ b/share/golden/expected/amd-pc.status.json @@ -0,0 +1 @@ +{"version":"2.12.0","firstRun":true,"steamMachine":false,"kernel":"7.0.0-fixture-cachyos","pinnedKernel":"7.1.6-1","cecDevices":"","leds":0,"bios":null,"items":[{"id":"gaming","label":"SteamOS conversion","hint":"boot into gaming mode, Steam on the desktop","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"boot","label":"Boot into the desktop instead of gaming mode","hint":"","kind":"choice","parent":"gaming","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"silent","label":"Start Steam silently in desktop mode","hint":"in the tray at login on the desktop, no window","kind":"toggle","parent":"gaming","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"glyphs","label":"Install Steam Deck/Machine icons","hint":"Deck button icons in gaming mode","kind":"toggle","parent":"gaming","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"theme","label":"Install SteamOS theme","hint":"Vapor look (cachyos-vapor)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"single","label":"Single user mode","hint":"no password, lock screen or log out (SDDM)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"launcher","label":"Steamify shortcut","hint":"the app on the desktop, Steamify Terminal in the launcher","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"notify","label":"Update notifications","hint":"a notification when there's a new Steamify, never updates by itself","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"extended_controller_support","label":"Extended controller support","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"cec","label":"HDMI-CEC","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true}]} diff --git a/share/golden/expected/nvidia-pc.plan-gaming-desktop.json b/share/golden/expected/nvidia-pc.plan-gaming-desktop.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/nvidia-pc.plan-gaming-desktop.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/nvidia-pc.plan-gaming.json b/share/golden/expected/nvidia-pc.plan-gaming.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/nvidia-pc.plan-gaming.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/nvidia-pc.plan-nothing.json b/share/golden/expected/nvidia-pc.plan-nothing.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/nvidia-pc.plan-nothing.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/nvidia-pc.plan-nvidia.json b/share/golden/expected/nvidia-pc.plan-nvidia.json new file mode 100644 index 0000000..8e59aed --- /dev/null +++ b/share/golden/expected/nvidia-pc.plan-nvidia.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["nvidia","bigpicture"]} diff --git a/share/golden/expected/nvidia-pc.plan-poweroff.json b/share/golden/expected/nvidia-pc.plan-poweroff.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/nvidia-pc.plan-poweroff.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/nvidia-pc.plan-single.json b/share/golden/expected/nvidia-pc.plan-single.json new file mode 100644 index 0000000..7a75397 --- /dev/null +++ b/share/golden/expected/nvidia-pc.plan-single.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["single"]} diff --git a/share/golden/expected/nvidia-pc.status.json b/share/golden/expected/nvidia-pc.status.json new file mode 100644 index 0000000..3a68736 --- /dev/null +++ b/share/golden/expected/nvidia-pc.status.json @@ -0,0 +1 @@ +{"version":"2.12.0","firstRun":true,"steamMachine":false,"kernel":"7.0.0-fixture-cachyos","pinnedKernel":"7.1.6-1","cecDevices":"","leds":0,"bios":null,"items":[{"id":"nvidia","label":"Gaming on NVIDIA","hint":"Steam on the desktop, started at login","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"bigpicture","label":"Steam starts in Big Picture","hint":"the controller-friendly Steam (untick: Steam's normal window)","kind":"toggle","parent":"nvidia","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"nvsilent","label":"Start Steam silently","hint":"in the tray at login, no window (untick: Steam's normal window)","kind":"toggle","parent":"nvidia","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"theme","label":"Install SteamOS theme","hint":"Vapor look (cachyos-vapor)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"single","label":"Single user mode","hint":"no password, lock screen or log out (SDDM)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"launcher","label":"Steamify shortcut","hint":"the app on the desktop, Steamify Terminal in the launcher","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"notify","label":"Update notifications","hint":"a notification when there's a new Steamify, never updates by itself","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"extended_controller_support","label":"Extended controller support","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"cec","label":"HDMI-CEC","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true}]} diff --git a/share/golden/expected/steam-machine.plan-gaming-desktop.json b/share/golden/expected/steam-machine.plan-gaming-desktop.json new file mode 100644 index 0000000..d24b606 --- /dev/null +++ b/share/golden/expected/steam-machine.plan-gaming-desktop.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["gaming","boot"]} diff --git a/share/golden/expected/steam-machine.plan-gaming.json b/share/golden/expected/steam-machine.plan-gaming.json new file mode 100644 index 0000000..feba85d --- /dev/null +++ b/share/golden/expected/steam-machine.plan-gaming.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["gaming"]} diff --git a/share/golden/expected/steam-machine.plan-nothing.json b/share/golden/expected/steam-machine.plan-nothing.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/steam-machine.plan-nothing.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/steam-machine.plan-nvidia.json b/share/golden/expected/steam-machine.plan-nvidia.json new file mode 100644 index 0000000..290ecc1 --- /dev/null +++ b/share/golden/expected/steam-machine.plan-nvidia.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":[]} diff --git a/share/golden/expected/steam-machine.plan-poweroff.json b/share/golden/expected/steam-machine.plan-poweroff.json new file mode 100644 index 0000000..3c3d372 --- /dev/null +++ b/share/golden/expected/steam-machine.plan-poweroff.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["machine","poweroff"]} diff --git a/share/golden/expected/steam-machine.plan-single.json b/share/golden/expected/steam-machine.plan-single.json new file mode 100644 index 0000000..f05b90a --- /dev/null +++ b/share/golden/expected/steam-machine.plan-single.json @@ -0,0 +1 @@ +{"event":"plan","disable":[],"enable":["gaming","single"]} diff --git a/share/golden/expected/steam-machine.status.json b/share/golden/expected/steam-machine.status.json new file mode 100644 index 0000000..d5eb5bd --- /dev/null +++ b/share/golden/expected/steam-machine.status.json @@ -0,0 +1 @@ +{"version":"2.12.0","firstRun":true,"steamMachine":true,"kernel":"7.0.0-fixture-cachyos","pinnedKernel":"7.1.6-1","cecDevices":"","leds":0,"bios":{"current":"unknown","newest":"","selectable":false,"dryRun":false},"items":[{"id":"gaming","label":"SteamOS conversion","hint":"boot into gaming mode, Steam on the desktop","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"boot","label":"Boot into the desktop instead of gaming mode","hint":"","kind":"choice","parent":"gaming","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"silent","label":"Start Steam silently in desktop mode","hint":"in the tray at login on the desktop, no window","kind":"toggle","parent":"gaming","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"glyphs","label":"Install Steam Deck/Machine icons","hint":"Deck button icons in gaming mode","kind":"toggle","parent":"gaming","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"theme","label":"Install SteamOS theme","hint":"Vapor look (cachyos-vapor)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"single","label":"Single user mode","hint":"no password, lock screen or log out (SDDM)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"launcher","label":"Steamify shortcut","hint":"the app on the desktop, Steamify Terminal in the launcher","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"notify","label":"Update notifications","hint":"a notification when there's a new Steamify, never updates by itself","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"extended_controller_support","label":"Extended controller support","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"cec","label":"HDMI-CEC","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"machine","label":"Steam Machine support","hint":"LED bar driver, hardware settings in Steam","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"poweroff","label":"Power-off fix","hint":"the Steam Machine stays off after shutting down","kind":"toggle","parent":"machine","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"bios","label":"Update BIOS","hint":"now unknown, newest unknown (offline?)","kind":"action","parent":"machine","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":false}]} diff --git a/share/golden/fixtures/amd-pc/etc/os-release b/share/golden/fixtures/amd-pc/etc/os-release new file mode 100644 index 0000000..a5494cd --- /dev/null +++ b/share/golden/fixtures/amd-pc/etc/os-release @@ -0,0 +1,3 @@ +NAME="CachyOS Linux" +ID=cachyos +ID_LIKE=arch diff --git a/share/golden/fixtures/amd-pc/packages b/share/golden/fixtures/amd-pc/packages new file mode 100644 index 0000000..47991f6 --- /dev/null +++ b/share/golden/fixtures/amd-pc/packages @@ -0,0 +1,2 @@ +sddm +plasma-desktop diff --git a/share/golden/fixtures/amd-pc/sys/class/dmi/id/product_name b/share/golden/fixtures/amd-pc/sys/class/dmi/id/product_name new file mode 100644 index 0000000..1411ccd --- /dev/null +++ b/share/golden/fixtures/amd-pc/sys/class/dmi/id/product_name @@ -0,0 +1 @@ +PRIME B650 diff --git a/share/golden/fixtures/amd-pc/sys/class/dmi/id/sys_vendor b/share/golden/fixtures/amd-pc/sys/class/dmi/id/sys_vendor new file mode 100644 index 0000000..c06f0f6 --- /dev/null +++ b/share/golden/fixtures/amd-pc/sys/class/dmi/id/sys_vendor @@ -0,0 +1 @@ +ASUSTeK diff --git a/share/golden/fixtures/nvidia-pc/etc/os-release b/share/golden/fixtures/nvidia-pc/etc/os-release new file mode 100644 index 0000000..a5494cd --- /dev/null +++ b/share/golden/fixtures/nvidia-pc/etc/os-release @@ -0,0 +1,3 @@ +NAME="CachyOS Linux" +ID=cachyos +ID_LIKE=arch diff --git a/share/golden/fixtures/nvidia-pc/modules b/share/golden/fixtures/nvidia-pc/modules new file mode 100644 index 0000000..c01f206 --- /dev/null +++ b/share/golden/fixtures/nvidia-pc/modules @@ -0,0 +1 @@ +nvidia_drm diff --git a/share/golden/fixtures/nvidia-pc/packages b/share/golden/fixtures/nvidia-pc/packages new file mode 100644 index 0000000..a76876f --- /dev/null +++ b/share/golden/fixtures/nvidia-pc/packages @@ -0,0 +1,3 @@ +sddm +plasma-desktop +nvidia-utils diff --git a/share/golden/fixtures/nvidia-pc/sys/class/dmi/id/product_name b/share/golden/fixtures/nvidia-pc/sys/class/dmi/id/product_name new file mode 100644 index 0000000..1411ccd --- /dev/null +++ b/share/golden/fixtures/nvidia-pc/sys/class/dmi/id/product_name @@ -0,0 +1 @@ +PRIME B650 diff --git a/share/golden/fixtures/nvidia-pc/sys/class/dmi/id/sys_vendor b/share/golden/fixtures/nvidia-pc/sys/class/dmi/id/sys_vendor new file mode 100644 index 0000000..c06f0f6 --- /dev/null +++ b/share/golden/fixtures/nvidia-pc/sys/class/dmi/id/sys_vendor @@ -0,0 +1 @@ +ASUSTeK diff --git a/share/golden/fixtures/nvidia-pc/sys/class/drm/card0/device/class b/share/golden/fixtures/nvidia-pc/sys/class/drm/card0/device/class new file mode 100644 index 0000000..c5f02e3 --- /dev/null +++ b/share/golden/fixtures/nvidia-pc/sys/class/drm/card0/device/class @@ -0,0 +1 @@ +0x030000 diff --git a/share/golden/fixtures/nvidia-pc/sys/class/drm/card0/device/vendor b/share/golden/fixtures/nvidia-pc/sys/class/drm/card0/device/vendor new file mode 100644 index 0000000..466e5df --- /dev/null +++ b/share/golden/fixtures/nvidia-pc/sys/class/drm/card0/device/vendor @@ -0,0 +1 @@ +0x10de diff --git a/share/golden/fixtures/steam-machine/etc/os-release b/share/golden/fixtures/steam-machine/etc/os-release new file mode 100644 index 0000000..a5494cd --- /dev/null +++ b/share/golden/fixtures/steam-machine/etc/os-release @@ -0,0 +1,3 @@ +NAME="CachyOS Linux" +ID=cachyos +ID_LIKE=arch diff --git a/share/golden/fixtures/steam-machine/packages b/share/golden/fixtures/steam-machine/packages new file mode 100644 index 0000000..47991f6 --- /dev/null +++ b/share/golden/fixtures/steam-machine/packages @@ -0,0 +1,2 @@ +sddm +plasma-desktop diff --git a/share/golden/fixtures/steam-machine/sys/class/dmi/id/product_name b/share/golden/fixtures/steam-machine/sys/class/dmi/id/product_name new file mode 100644 index 0000000..fda0fed --- /dev/null +++ b/share/golden/fixtures/steam-machine/sys/class/dmi/id/product_name @@ -0,0 +1 @@ +Fremont diff --git a/share/golden/fixtures/steam-machine/sys/class/dmi/id/sys_vendor b/share/golden/fixtures/steam-machine/sys/class/dmi/id/sys_vendor new file mode 100644 index 0000000..ab926ba --- /dev/null +++ b/share/golden/fixtures/steam-machine/sys/class/dmi/id/sys_vendor @@ -0,0 +1 @@ +Valve diff --git a/share/golden/record.sh b/share/golden/record.sh new file mode 100755 index 0000000..03e4182 --- /dev/null +++ b/share/golden/record.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Record what the bash backend (steamify.sh in $REPO) prints, per fixture, into share/golden/expected/. +# share/golden/record.sh record all | share/golden/record.sh check compare with the recorded files +set -uo pipefail +here="$(cd "$(dirname "$0")" && pwd)" +export REPO="${REPO:-$here/../../../steamify-cachyos}"; REPO="$(cd "$REPO" && pwd)" +backend="${BACKEND:-bash $REPO/steamify.sh}" +mode="${1:-record}"; failures=0 +# case name -> backend arguments +# status: the whole output. plan-*: only the first line of the apply stream (the plan event, where the rules live); +# the steps after it need the real system (the VM suite), they are not stable with a fake sudo. +cases=("status:--backend status" + "plan-gaming:--backend apply gaming" + "plan-gaming-desktop:--backend apply --boot desktop gaming boot" + "plan-single:--backend apply single" + "plan-poweroff:--backend apply poweroff" + "plan-nothing:--backend apply" + "plan-nvidia:--backend apply nvidia bigpicture") +for fixture in "$here"/fixtures/*/; do + name="$(basename "$fixture")" + for entry in "${cases[@]}"; do + label="${entry%%:*}"; arguments="${entry#*:}" + expected="$here/expected/$name.$label.json"; mkdir -p "$here/expected" + actual="$("$here/sandbox.sh" "$fixture" $backend $arguments 2>&1)" + [[ "$label" == plan-* ]] && actual="$(head -n 1 <<<"$actual")" + if [[ "$mode" == record ]]; then printf '%s\n' "$actual" > "$expected"; echo "recorded $expected" + elif ! diff -u "$expected" <(printf '%s\n' "$actual"); then echo "FAIL $name $label"; failures=$((failures+1)) + else echo "PASS $name $label"; fi + done +done +exit $failures diff --git a/share/golden/sandbox.sh b/share/golden/sandbox.sh new file mode 100755 index 0000000..9fc5b40 --- /dev/null +++ b/share/golden/sandbox.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Run a command in a throw-away copy of a machine described by a fixture folder (no VM, no root). +# share/golden/sandbox.sh ... +# /etc/**, /sys/**, /usr/** : files shown at those places (the rest of /etc and /sys is empty) +# /home/ : the user's home (fresh copy each run) +# /packages, enabled-units, active-units : answers of the fake pacman and systemctl (shims/) +# /env : optional VAR=value lines for the command +# Needs bubblewrap. $GOLDEN_LOG collects the writes the shims were asked to make. +set -euo pipefail +here="$(cd "$(dirname "$0")" && pwd)" +fixture="$(cd "${1:?usage: $0 ...}" && pwd)"; shift +work="$(mktemp -d)"; trap 'rm -rf "$work"' EXIT +mkdir -p "$work/home" "$work/fixture" +cp -a "$fixture/." "$work/fixture/" +[[ -d "$fixture/home" ]] && cp -a "$fixture/home/." "$work/home/" +arguments=(--die-with-parent --unshare-pid --ro-bind / / --dev /dev --proc /proc --tmpfs /tmp --tmpfs /sys --tmpfs /etc + --bind "$work/home" "$HOME" --bind "$work/fixture" /mnt --ro-bind "$here/shims" /media) +[[ -n "${REPO:-}" ]] && arguments+=(--ro-bind "$REPO" "$REPO") +for keep in passwd group nsswitch.conf ld.so.cache ld.so.conf ld.so.conf.d localtime alternatives resolv.conf hostname; do + [[ -e "/etc/$keep" ]] && arguments+=(--ro-bind "/etc/$keep" "/etc/$keep") +done +for root in etc sys; do + [[ -d "$fixture/$root" ]] || continue + while IFS= read -r -d '' file; do + arguments+=(--ro-bind "$work/fixture/${file#"$fixture/"}" "/${file#"$fixture/"}") + done < <(find "$fixture/$root" -type f -print0) +done +environment=(--setenv FIXTURE /mnt --setenv PATH "/media:$PATH" --setenv GOLDEN_LOG "${GOLDEN_LOG:-/mnt/writes.log}") +[[ -f "$fixture/env" ]] && while IFS= read -r line; do + [[ "$line" == *=* ]] && environment+=(--setenv "${line%%=*}" "${line#*=}") +done < "$fixture/env" +exec bwrap "${arguments[@]}" "${environment[@]}" "$@" diff --git a/share/golden/shims/modinfo b/share/golden/shims/modinfo new file mode 100755 index 0000000..7a1a78f --- /dev/null +++ b/share/golden/shims/modinfo @@ -0,0 +1,3 @@ +#!/bin/bash +# Fake modinfo: modules listed in $FIXTURE/modules exist. +for module in "$@"; do [[ "$module" == -* ]] || grep -qx -- "$module" "$FIXTURE/modules" 2>/dev/null || exit 1; done diff --git a/share/golden/shims/pacman b/share/golden/shims/pacman new file mode 100755 index 0000000..62f9e09 --- /dev/null +++ b/share/golden/shims/pacman @@ -0,0 +1,10 @@ +#!/bin/bash +# Fake pacman for the golden sandbox: the installed packages are listed in $FIXTURE/packages (one name per line). +# Only the queries the status code makes: -Q/-Qq , -T ..., -Qi . Writes (-S, -U, -R) are logged and succeed. +list="$FIXTURE/packages"; touch "$list" 2>/dev/null +case "$1" in + -T) shift; for package in "$@"; do grep -qx -- "$package" "$list" || echo "$package"; done; [[ $# -gt 0 ]] ;; + -Q|-Qq|-Qi|-Qs) shift; status=0; for package in "$@"; do [[ "$package" == -* ]] && continue; grep -qx -- "$package" "$list" || status=1; done; exit $status ;; + -Ss|-Si) exit 1 ;; + *) echo "pacman $*" >> "${GOLDEN_LOG:-/dev/null}"; exit 0 ;; +esac diff --git a/share/golden/shims/sudo b/share/golden/shims/sudo new file mode 100755 index 0000000..257daf9 --- /dev/null +++ b/share/golden/shims/sudo @@ -0,0 +1,4 @@ +#!/bin/bash +# Fake sudo: logs the command and succeeds; nothing runs. +while [[ "$1" == -* ]]; do shift; done +echo "sudo $*" >> "${GOLDEN_LOG:-/dev/null}" diff --git a/share/golden/shims/systemctl b/share/golden/shims/systemctl new file mode 100755 index 0000000..af28847 --- /dev/null +++ b/share/golden/shims/systemctl @@ -0,0 +1,13 @@ +#!/bin/bash +# Fake systemctl: enabled units listed in $FIXTURE/enabled-units, active ones in $FIXTURE/active-units. +# Queries answer from those lists; everything else is logged and succeeds. +verb=""; units=() +for argument in "$@"; do + [[ "$argument" == -* ]] && continue + if [[ -z "$verb" ]]; then verb="$argument"; else units+=("$argument"); fi +done +case "$verb" in + is-enabled) for unit in "${units[@]}"; do grep -qx -- "$unit" "$FIXTURE/enabled-units" 2>/dev/null || { echo disabled; exit 1; }; done; echo enabled ;; + is-active) for unit in "${units[@]}"; do grep -qx -- "$unit" "$FIXTURE/active-units" 2>/dev/null || { echo inactive; exit 3; }; done; echo active ;; + *) echo "systemctl $*" >> "${GOLDEN_LOG:-/dev/null}"; exit 0 ;; +esac diff --git a/share/golden/shims/uname b/share/golden/shims/uname new file mode 100755 index 0000000..c16e0d8 --- /dev/null +++ b/share/golden/shims/uname @@ -0,0 +1,2 @@ +#!/bin/bash +if [[ "$1" == -r ]]; then echo 7.0.0-fixture-cachyos; else command uname "$@"; fi