ohhhhhhhhhhh (exclude linux-extra-rootfs.img build artifact)

This commit is contained in:
Linehu
2026-10-01 23:13:42 +08:00
parent 737a2cb0db
commit 1074962546
533 changed files with 133239 additions and 5460 deletions
+177
View File
@@ -0,0 +1,177 @@
#!/usr/bin/env bash
# Headless QEMU verify: Linux guest park + native desktop + KDE scanout.
set -Eeuo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
IMG="${IMG_OVERRIDE:-$ROOT/ISO/deshab-dev.img}"
LOG="${QEMU_SERIAL_LOG:-/home/deshab/qemu_serial_loop1.log}"
MON="${QEMU_MONITOR:-telnet:127.0.0.1:45454,server,nowait}"
TIMEOUT="${QEMU_VERIFY_TIMEOUT:-480}"
SEND_KDE="${QEMU_SEND_KDE:-1}"
SERIAL_TCP="${QEMU_SERIAL_TCP:-127.0.0.1:45455}"
rm -f "$LOG"
: > "$LOG"
export IMG_OVERRIDE="$IMG"
export QEMU_SERIAL_LOG="$LOG"
export QEMU_DISPLAY=none
export QEMU_MONITOR="$MON"
export QEMU_SERIAL_TCP="$SERIAL_TCP"
# Do not attach the AHCI SATA *sidecar*. The boot disk is already AHCI
# (ISO/deshab-dev.img). The old sata_fat32_dsk.img hid ESP deshab.elf.
export SATA_IMG_OVERRIDE="/tmp/deshab-verify-no-sata"
export NVME_IMG_OVERRIDE="/tmp/deshab-verify-no-nvme"
export USB_IMG_OVERRIDE="/tmp/deshab-verify-no-usb"
echo "[verify] starting QEMU, log=$LOG timeout=${TIMEOUT}s serial_tcp=$SERIAL_TCP"
cd "$ROOT/ISO"
# Strip CRLF if the script was edited on Windows.
sed -i 's/\r$//' ./run_qemu_kvm.sh 2>/dev/null || true
bash ./run_qemu_kvm.sh &
QEMU_PID=$!
cleanup() {
set +e
if kill -0 "$QEMU_PID" 2>/dev/null; then
kill "$QEMU_PID" 2>/dev/null || true
sleep 1
kill -9 "$QEMU_PID" 2>/dev/null || true
fi
}
trap cleanup EXIT
log_text() {
# Serial logs often contain CR / NUL; strip so grep anchors work.
tr -d '\r\0' < "$LOG" 2>/dev/null || true
}
log_has() {
log_text | grep -qE "$1"
}
send_serial() {
local msg="$1"
local host="${SERIAL_TCP%%:*}"
local port="${SERIAL_TCP##*:}"
python3 - "$host" "$port" "$msg" <<'PY' || true
import socket, sys
host, port, msg = sys.argv[1], int(sys.argv[2]), sys.argv[3]
s = socket.create_connection((host, port), 3)
s.sendall(msg.encode())
s.close()
PY
}
sent_kde=0
dsk_started=0
plasma_painted=0
deadline=$((SECONDS + TIMEOUT))
guest_ok=0
session_ok=0
kde_ok=0
desktop_ready=0
while kill -0 "$QEMU_PID" 2>/dev/null && [[ $SECONDS -lt $deadline ]]; do
if log_has 'EXEC_READY received from /dev/utsm' && \
log_has 'guest parked \(daemon ready\)'; then
guest_ok=1
fi
if log_has '\[DSK\] session=(kde|native)$' || \
log_has '\[DSK\] session=ask, waiting for 1/2'; then
session_ok=1
fi
if log_has 'desktop ready'; then
desktop_ready=1
fi
if log_has 'session=ask, waiting for 1/2'; then
if [[ "$SEND_KDE" == "1" && "$sent_kde" == "0" ]]; then
sleep 1
echo "[verify] sending serial 2 for KDE (chooser)"
send_serial '2'
sent_kde=1
fi
fi
if [[ "$desktop_ready" == "1" && "$SEND_KDE" == "1" && "$sent_kde" == "0" ]]; then
echo "[verify] sending serial 2 for KDE (native desktop)"
send_serial '2'
sent_kde=1
deadline=$((SECONDS + 180))
fi
# "Plasma failed" is sometimes dropped by kmsg. The loader error
# and the chroot exit status are the ones that actually reach serial.
if log_has '\[deshab-kde\] Plasma failed|invalid ELF header|error while loading shared libraries|exited with status [1-9]|fatal signal'; then
kde_ok=3
elif log_has '\[deshab-kde\] starting Plasma'; then
kde_ok=1
elif [[ "$kde_ok" != "1" ]] && \
log_has 'KDE preflight missing|KDE scanout timeout|KDE failed|could not bind|chroot session exited'; then
kde_ok=3
elif [[ "$kde_ok" == "0" ]] && \
log_has 'serial 2: launch KDE|kde: launching fullscreen Plasma|KDE host loop|KDE spawned|\[deshab-kde\] interpreter alive|\[deshab-kde\] entering KDE'; then
kde_ok=2
fi
# P9: Plasma 只活着还不够,必须真的推帧。Xorg/modesetting 每次提交
# 都发 RESOURCE_FLUSH;utsm.elf 里加了 FLUSH_N 计数日志(每 64 次一行)。
# starting Plasma 之后出现 FLUSH_N 才算 Plasma 画了。
if [[ "$kde_ok" == "1" ]]; then
if log_has '\[VGPU\] FLUSH_N'; then
plasma_painted=1
fi
fi
# drm fbdev SET_SCANOUT at boot is not Plasma. "entering KDE" only
# means the session reached the chroot setup, not that Plasma painted.
if [[ "$kde_ok" == "1" ]] && [[ "$guest_ok" == "1" ]]; then
if [[ "$sent_kde" == "1" ]]; then
sleep 60
else
sleep 8
fi
# starting Plasma is logged before the child returns. Recheck
# after the wait so a 127 during this window is not a false OK.
if log_has '\[deshab-kde\] Plasma failed|invalid ELF header|error while loading shared libraries|exited with status [1-9]|fatal signal'; then
kde_ok=3
elif log_has '\[VGPU\] FLUSH_N'; then
plasma_painted=1
break
else
break
fi
fi
if [[ "$guest_ok" == "1" && "$session_ok" == "1" && "$kde_ok" == "3" ]]; then
sleep 20
break
fi
if [[ "$dsk_started" == "0" ]] && log_has '\[DSK\] FUCK config loaded'; then
dsk_started=1
deadline=$((SECONDS + 240))
echo "[verify] DSK started, extending wait 240s"
fi
sleep 2
echo "[verify] t=${SECONDS}s log=$(wc -c < "$LOG" 2>/dev/null || echo 0) guest=$guest_ok session=$session_ok desktop=$desktop_ready kde=$kde_ok"
done
echo "===== VERIFY SUMMARY ====="
echo "guest_ok=$guest_ok session_ok=$session_ok kde_ok=$kde_ok sent_kde=$sent_kde desktop_ready=$desktop_ready plasma_painted=$plasma_painted"
echo "----- markers -----"
log_text | grep -E 'EXEC_READY|guest parked|session=ask|session=kde|session=native|KDE |Linux guest|FUCK config loaded|switch_root|utsm-linux|desktop ready|serial 2|FAT32 volume LBA|desktop load|user/desktop|VGPU|scanout|FLUSH|deshab-kde|vdc|persist|segfault|fatal signal|Xorg.0.log|Fatal server|overlay' | tail -n 120 || true
if [[ "$guest_ok" != "1" || "$session_ok" != "1" ]]; then
echo VERIFY_FAIL
exit 1
fi
if [[ "$kde_ok" == "1" ]]; then
if [[ "$plasma_painted" == "1" ]]; then
echo VERIFY_KDE_PLASMA_OK
exit 0
else
echo VERIFY_KDE_ALIVE_NO_FRAME
exit 1
fi
fi
if [[ "$kde_ok" == "2" ]]; then
echo VERIFY_KDE_SPAWNED
exit 1
fi
echo VERIFY_PARTIAL_OK
exit 1