diff --git a/Cargo.lock b/Cargo.lock index dffcedd..666065d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "lesavka_client" -version = "0.14.21" +version = "0.14.22" dependencies = [ "anyhow", "async-stream", @@ -1676,7 +1676,7 @@ dependencies = [ [[package]] name = "lesavka_common" -version = "0.14.21" +version = "0.14.22" dependencies = [ "anyhow", "base64", @@ -1688,7 +1688,7 @@ dependencies = [ [[package]] name = "lesavka_server" -version = "0.14.21" +version = "0.14.22" dependencies = [ "anyhow", "base64", diff --git a/client/Cargo.toml b/client/Cargo.toml index 0388d68..8fa3ccb 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -4,7 +4,7 @@ path = "src/main.rs" [package] name = "lesavka_client" -version = "0.14.21" +version = "0.14.22" edition = "2024" [dependencies] diff --git a/common/Cargo.toml b/common/Cargo.toml index 2907458..a5e44a1 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lesavka_common" -version = "0.14.21" +version = "0.14.22" edition = "2024" build = "build.rs" diff --git a/scripts/install/server.sh b/scripts/install/server.sh index b6a5c04..764eca6 100755 --- a/scripts/install/server.sh +++ b/scripts/install/server.sh @@ -21,6 +21,23 @@ manifest_package_version() { ' "$manifest" } +render_uvc_env_file() { + cat </dev/null | head -n1 || true) @@ -502,20 +519,14 @@ fi printf 'LESAVKA_UVC_CODEC=%s\n' "${LESAVKA_UVC_CODEC:-mjpeg}" } | sudo tee /etc/lesavka/server.env >/dev/null -{ - echo "# generated by lesavka/scripts/install/server.sh" - echo "# Edit only for local UVC hardware overrides; rerunning the installer refreshes defaults." - printf 'LESAVKA_UVC_DEBUG=%s\n' "${LESAVKA_UVC_DEBUG:-1}" - printf 'LESAVKA_UVC_MAXPACKET=%s\n' "${LESAVKA_UVC_MAXPACKET:-256}" - printf 'LESAVKA_UVC_LIMIT_PCT=%s\n' "${LESAVKA_UVC_LIMIT_PCT:-100}" - printf 'LESAVKA_UVC_FPS=%s\n' "${LESAVKA_UVC_FPS:-20}" - printf 'LESAVKA_UVC_INTERVAL=%s\n' "${LESAVKA_UVC_INTERVAL:-500000}" - printf 'LESAVKA_UVC_WIDTH=%s\n' "${LESAVKA_UVC_WIDTH:-640}" - printf 'LESAVKA_UVC_HEIGHT=%s\n' "${LESAVKA_UVC_HEIGHT:-480}" - printf 'LESAVKA_UVC_CODEC=%s\n' "${LESAVKA_UVC_CODEC:-mjpeg}" - printf 'LESAVKA_UVC_BLOCKING=%s\n' "${LESAVKA_UVC_BLOCKING:-1}" - printf 'LESAVKA_UVC_MAXBURST=%s\n' "${LESAVKA_UVC_MAXBURST:-0}" -} | sudo tee /etc/lesavka/uvc.env >/dev/null +UVC_ENV_TMP=$(mktemp) +render_uvc_env_file >"$UVC_ENV_TMP" +UVC_ENV_CHANGED=1 +if sudo test -f /etc/lesavka/uvc.env && sudo cmp -s "$UVC_ENV_TMP" /etc/lesavka/uvc.env; then + UVC_ENV_CHANGED=0 +fi +sudo install -m 0644 "$UVC_ENV_TMP" /etc/lesavka/uvc.env +rm -f "$UVC_ENV_TMP" echo "==> 6a. Systemd units - lesavka-core" cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-core.service >/dev/null @@ -529,7 +540,6 @@ Type=oneshot ExecStart=/usr/local/bin/lesavka-core.sh RemainAfterExit=yes Environment=LESAVKA_UVC_FALLBACK=0 -Environment=LESAVKA_UVC_CODEC=mjpeg EnvironmentFile=-/etc/lesavka/server.env CapabilityBoundingSet=CAP_SYS_ADMIN CAP_SYS_MODULE AmbientCapabilities=CAP_SYS_MODULE @@ -557,7 +567,6 @@ Restart=always Environment=RUST_LOG=lesavka_server=info,lesavka_server::audio=info,lesavka_server::video=debug,lesavka_server::gadget=info Environment=RUST_BACKTRACE=1 Environment=GST_DEBUG="*:2,alsasink:6,alsasrc:6" -Environment=LESAVKA_UVC_CODEC=mjpeg Environment=LESAVKA_UVC_EXTERNAL=1 Environment=LESAVKA_EYE_ADAPTIVE=1 Environment=LESAVKA_EYE_MIN_FPS=12 @@ -565,6 +574,7 @@ Environment=LESAVKA_EYE_FPS=20 Environment=LESAVKA_MIC_INIT_ATTEMPTS=5 Environment=LESAVKA_MIC_INIT_DELAY_MS=250 Environment=LESAVKA_ALLOW_GADGET_CYCLE=1 +EnvironmentFile=-/etc/lesavka/uvc.env EnvironmentFile=-/etc/lesavka/server.env Restart=always RestartSec=5 @@ -581,7 +591,12 @@ sudo systemctl daemon-reload sudo systemctl enable lesavka-core lesavka-server UDC_STATE=$(udc_state) -if [[ -n ${LESAVKA_ALLOW_GADGET_RESET:-} ]] || ! is_attached_state "$UDC_STATE"; then +FORCE_GADGET_REBUILD=0 +if [[ "$UVC_ENV_CHANGED" == "1" ]] && is_attached_state "$UDC_STATE"; then + FORCE_GADGET_REBUILD=1 + echo "⚠️ UVC runtime settings changed while the host is attached; forcing a gadget rebuild so the new descriptors take effect." +fi +if [[ -n ${LESAVKA_ALLOW_GADGET_RESET:-} ]] || [[ "$FORCE_GADGET_REBUILD" == "1" ]] || ! is_attached_state "$UDC_STATE"; then echo "⚠️ UDC state is '$UDC_STATE' - forcing a Lesavka gadget rebuild before server start." sudo env \ LESAVKA_ALLOW_GADGET_RESET=1 \ @@ -635,7 +650,8 @@ sudo rm -f /etc/systemd/system/lesavka-watchdog.timer \ sudo systemctl daemon-reload if systemctl is-active --quiet lesavka-uvc; then - echo "✅ lesavka-uvc is active (dependency-managed; manual restart disabled)." + sudo systemctl restart lesavka-uvc + echo "✅ lesavka-uvc restarted with the refreshed UVC runtime settings." else echo "⚠️ lesavka-uvc is not active; start via lesavka-core dependency path." fi diff --git a/server/Cargo.toml b/server/Cargo.toml index 1d75723..26a9b02 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -10,7 +10,7 @@ bench = false [package] name = "lesavka_server" -version = "0.14.21" +version = "0.14.22" edition = "2024" autobins = false diff --git a/testing/tests/server_install_script_contract.rs b/testing/tests/server_install_script_contract.rs index 09e42b5..291dacc 100644 --- a/testing/tests/server_install_script_contract.rs +++ b/testing/tests/server_install_script_contract.rs @@ -24,11 +24,11 @@ fn server_install_pins_hdmi_camera_and_display_defaults() { "LESAVKA_UPSTREAM_PAIR_SLACK_US=%s", "LESAVKA_UPSTREAM_STALE_DROP_MS=%s", "/etc/lesavka/uvc.env", - "LESAVKA_UVC_MAXPACKET=%s", - "LESAVKA_UVC_INTERVAL=%s", - "LESAVKA_UVC_WIDTH=%s", - "LESAVKA_UVC_HEIGHT=%s", - "LESAVKA_UVC_CODEC=%s", + "LESAVKA_UVC_MAXPACKET=", + "LESAVKA_UVC_INTERVAL=", + "LESAVKA_UVC_WIDTH=", + "LESAVKA_UVC_HEIGHT=", + "LESAVKA_UVC_CODEC=", ] { assert!( SERVER_INSTALL.contains(expected), @@ -49,6 +49,14 @@ fn server_install_pins_hdmi_camera_and_display_defaults() { assert!(SERVER_INSTALL.contains("${LESAVKA_UVC_WIDTH:-640}")); assert!(SERVER_INSTALL.contains("${LESAVKA_UVC_HEIGHT:-480}")); assert!(SERVER_INSTALL.contains("${LESAVKA_UVC_CODEC:-mjpeg}")); + assert!( + SERVER_INSTALL.contains("EnvironmentFile=-/etc/lesavka/uvc.env"), + "install script should feed live UVC runtime settings into services" + ); + assert!( + !SERVER_INSTALL.contains("Environment=LESAVKA_UVC_CODEC=mjpeg"), + "install script should not pin UVC codec to mjpeg in the systemd units" + ); } #[test]