fix(sync): fail loud when uvc rebuild disappears

This commit is contained in:
Brad Stein 2026-04-27 16:05:42 -03:00
parent 36a198db4c
commit 909b9c51fe
6 changed files with 72 additions and 7 deletions

6
Cargo.lock generated
View File

@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "lesavka_client"
version = "0.14.22"
version = "0.14.23"
dependencies = [
"anyhow",
"async-stream",
@ -1676,7 +1676,7 @@ dependencies = [
[[package]]
name = "lesavka_common"
version = "0.14.22"
version = "0.14.23"
dependencies = [
"anyhow",
"base64",
@ -1688,7 +1688,7 @@ dependencies = [
[[package]]
name = "lesavka_server"
version = "0.14.22"
version = "0.14.23"
dependencies = [
"anyhow",
"base64",

View File

@ -4,7 +4,7 @@ path = "src/main.rs"
[package]
name = "lesavka_client"
version = "0.14.22"
version = "0.14.23"
edition = "2024"
[dependencies]

View File

@ -1,6 +1,6 @@
[package]
name = "lesavka_common"
version = "0.14.22"
version = "0.14.23"
edition = "2024"
build = "build.rs"

View File

@ -38,6 +38,57 @@ LESAVKA_UVC_MAXBURST=${LESAVKA_UVC_MAXBURST:-0}
EOF
}
find_uvc_output_node() {
local by_path_root=/dev/v4l/by-path
local ctrl=""
ctrl=$(ls /sys/class/udc 2>/dev/null | head -n1 || true)
if [[ -n $ctrl && -e "$by_path_root/platform-$ctrl-video-index0" ]]; then
printf '%s\n' "$by_path_root/platform-$ctrl-video-index0"
return 0
fi
local candidate
shopt -s nullglob
for candidate in "$by_path_root"/platform-*-video-index0; do
printf '%s\n' "$candidate"
shopt -u nullglob
return 0
done
shopt -u nullglob
return 1
}
wait_for_uvc_output_node() {
local node=""
for _ in {1..50}; do
if node=$(find_uvc_output_node); then
printf '%s\n' "$node"
return 0
fi
sleep 0.1
done
return 1
}
validate_uvc_gadget_ready() {
if [[ -n ${LESAVKA_DISABLE_UVC:-} ]]; then
return 0
fi
if [[ ! -d /sys/kernel/config/usb_gadget/lesavka/functions/uvc.usb0 ]]; then
echo "❌ UVC gadget function is missing after rebuild; refusing to continue with a half-applied install." >&2
return 1
fi
local node=""
if ! node=$(wait_for_uvc_output_node); then
echo "❌ UVC gadget video-output node did not appear after rebuild; refusing to continue." >&2
return 1
fi
echo "✅ UVC gadget output ready at ${node}"
}
udc_state() {
local udc=""
udc=$(ls /sys/class/udc 2>/dev/null | head -n1 || true)
@ -603,7 +654,7 @@ if [[ -n ${LESAVKA_ALLOW_GADGET_RESET:-} ]] || [[ "$FORCE_GADGET_REBUILD" == "1"
LESAVKA_ATTACH_WRITE_UDC=1 \
LESAVKA_DETACH_CLEAR_UDC=1 \
LESAVKA_RELOAD_UVCVIDEO=1 \
LESAVKA_UVC_FALLBACK=1 \
LESAVKA_UVC_FALLBACK=0 \
LESAVKA_UVC_CODEC="${LESAVKA_UVC_CODEC:-mjpeg}" \
/usr/local/bin/lesavka-core.sh
sudo systemctl restart lesavka-core
@ -656,6 +707,8 @@ else
echo "⚠️ lesavka-uvc is not active; start via lesavka-core dependency path."
fi
validate_uvc_gadget_ready
sudo systemctl restart lesavka-server
INSTALLED_VERSION=$(manifest_package_version "$SRC_DIR/server/Cargo.toml" 2>/dev/null || true)
INSTALLED_SHA=$(git -C "$SCRIPT_REPO_ROOT" rev-parse --short HEAD 2>/dev/null || true)

View File

@ -10,7 +10,7 @@ bench = false
[package]
name = "lesavka_server"
version = "0.14.22"
version = "0.14.23"
edition = "2024"
autobins = false

View File

@ -57,6 +57,18 @@ fn server_install_pins_hdmi_camera_and_display_defaults() {
!SERVER_INSTALL.contains("Environment=LESAVKA_UVC_CODEC=mjpeg"),
"install script should not pin UVC codec to mjpeg in the systemd units"
);
assert!(
SERVER_INSTALL.contains("LESAVKA_UVC_FALLBACK=0"),
"forced gadget rebuilds should fail loud instead of silently dropping UVC"
);
assert!(
SERVER_INSTALL.contains("validate_uvc_gadget_ready"),
"install script should verify that the UVC gadget comes back before declaring success"
);
assert!(
SERVER_INSTALL.contains("video-output node did not appear after rebuild"),
"install script should explain why it refuses a half-applied UVC install"
);
}
#[test]