From 01c4d559263f4eb50d2d0075cb2609636d0eb29c Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Fri, 15 May 2026 09:50:22 -0300 Subject: [PATCH] install: refresh uvc helper during version updates --- Cargo.lock | 6 +++--- client/Cargo.toml | 2 +- common/Cargo.toml | 2 +- scripts/install/server.sh | 13 ++++++++++++- server/Cargo.toml | 2 +- .../install/server_install_script_contract.rs | 18 +++++++++++------- 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39f3dae..0012725 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "lesavka_client" -version = "0.22.40" +version = "0.22.41" dependencies = [ "anyhow", "async-stream", @@ -1686,7 +1686,7 @@ dependencies = [ [[package]] name = "lesavka_common" -version = "0.22.40" +version = "0.22.41" dependencies = [ "anyhow", "base64", @@ -1698,7 +1698,7 @@ dependencies = [ [[package]] name = "lesavka_server" -version = "0.22.40" +version = "0.22.41" dependencies = [ "anyhow", "base64", diff --git a/client/Cargo.toml b/client/Cargo.toml index 1684464..99d0488 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -4,7 +4,7 @@ path = "src/main.rs" [package] name = "lesavka_client" -version = "0.22.40" +version = "0.22.41" edition = "2024" [dependencies] diff --git a/common/Cargo.toml b/common/Cargo.toml index 3238560..de99522 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lesavka_common" -version = "0.22.40" +version = "0.22.41" edition = "2024" build = "build.rs" diff --git a/scripts/install/server.sh b/scripts/install/server.sh index d403804..0f79430 100755 --- a/scripts/install/server.sh +++ b/scripts/install/server.sh @@ -977,6 +977,12 @@ restart_lesavka_server_only() { validate_server_ready } +restart_lesavka_uvc_helper_only() { + sudo truncate -s 0 /var/log/lesavka/uvc.stderr + sudo systemctl reset-failed lesavka-uvc >/dev/null 2>&1 || true + sudo systemctl restart lesavka-uvc +} + normalize_hdmi_connector() { local name="$1" if [[ $name =~ (HDMI-A-[0-9]+)$ ]]; then @@ -1878,7 +1884,12 @@ if [[ "$HOST_GADGET_PROTECTED" == "1" ]] \ CAN_TOUCH_UVC_SERVICE=0 fi if [[ "$CAN_TOUCH_UVC_SERVICE" != "1" ]] && systemctl is-active --quiet lesavka-uvc; then - echo "✅ lesavka-uvc already active; preserving it during attached-gadget version update." + if [[ "${LESAVKA_INSTALL_PRESERVE_UVC_HELPER:-0}" == "1" ]]; then + echo "✅ lesavka-uvc already active; preserving it during attached-gadget version update." + else + restart_lesavka_uvc_helper_only + echo "✅ lesavka-uvc helper restarted in-place; lesavka-core and the attached USB gadget were preserved." + fi elif [[ "$CAN_TOUCH_UVC_SERVICE" != "1" ]]; then echo "⚠️ lesavka-uvc is inactive, but the host/gadget is protected; not starting it during a version-only install." >&2 elif [[ "$UVC_ENV_CHANGED" == "1" ]] && systemctl is-active --quiet lesavka-uvc; then diff --git a/server/Cargo.toml b/server/Cargo.toml index e26d29e..7f3cd27 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -10,7 +10,7 @@ bench = false [package] name = "lesavka_server" -version = "0.22.40" +version = "0.22.41" edition = "2024" autobins = false diff --git a/tests/installer/scripts/install/server_install_script_contract.rs b/tests/installer/scripts/install/server_install_script_contract.rs index ad7d348..8191a0e 100644 --- a/tests/installer/scripts/install/server_install_script_contract.rs +++ b/tests/installer/scripts/install/server_install_script_contract.rs @@ -413,9 +413,9 @@ fn server_install_pins_hdmi_camera_and_display_defaults() { .find("if [[ \"$ATTACHED_UVC_RESTART_DEFERRED\" == \"1\" ]]") .unwrap() < SERVER_INSTALL - .find("sudo systemctl restart lesavka-uvc") + .rfind("restart_lesavka_uvc_helper_only") .unwrap(), - "safe env repair must exit before live UVC helper restarts" + "safe env repair must exit before the later version-update helper refresh path" ); assert!( SERVER_INSTALL @@ -431,9 +431,9 @@ fn server_install_pins_hdmi_camera_and_display_defaults() { .find("ATTACHED_UVC_CHANGE_DEFERRED=1") .unwrap() < SERVER_INSTALL - .find("sudo systemctl restart lesavka-uvc") + .rfind("restart_lesavka_uvc_helper_only") .unwrap(), - "attached UVC deferral must run before any live UVC helper restart" + "attached UVC deferral must run before the later safe helper refresh call site" ); assert!( SERVER_INSTALL.contains("[[ \"$EXPLICIT_GADGET_REBUILD\" != \"1\" ]] || [[ -z ${LESAVKA_ALLOW_GADGET_RESET:-} ]]"), @@ -484,12 +484,16 @@ fn server_install_pins_hdmi_camera_and_display_defaults() { assert!( SERVER_INSTALL.contains("CAN_TOUCH_UVC_SERVICE=0") && SERVER_INSTALL.contains("preserving it during attached-gadget version update") + && SERVER_INSTALL.contains("LESAVKA_INSTALL_PRESERVE_UVC_HELPER") && SERVER_INSTALL.contains("not starting it during a version-only install"), - "ordinary attached-gadget version updates must not start or restart the UVC helper" + "ordinary attached-gadget version updates should keep an operator escape hatch for preserving the UVC helper" ); assert!( - !SERVER_INSTALL.contains("restart_lesavka_uvc_helper_only"), - "the UVC helper must not be treated as safe to refresh independently while the host is attached" + SERVER_INSTALL.contains("restart_lesavka_uvc_helper_only") + && SERVER_INSTALL.contains("systemctl restart lesavka-uvc") + && SERVER_INSTALL + .contains("lesavka-uvc helper restarted in-place; lesavka-core and the attached USB gadget were preserved"), + "version updates must refresh the UVC helper binary without cycling lesavka-core or rebuilding the gadget" ); assert!( SERVER_INSTALL.contains("sudo systemctl start lesavka-uvc"),