From acfe7d6bfadde217a135bf843cc1bd81339f1e1a Mon Sep 17 00:00:00 2001 From: librelad Date: Mon, 25 May 2026 18:13:09 +0100 Subject: [PATCH] feat(update): release-aware update detection + apply (phase D) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the WebUI updater work off release versions, not git commits, in release mode (git/local paths untouched): - webui_system_update.sh: a release branch resolves latest_version from the channel manifest (lpReleaseLatestVersion), computes update_available via lpVersionGt vs the local VERSION, reuses the same throttle + the same update_status.json schema (source="release"); reuses last-known latest when throttled so the badge doesn't flicker. - check_update.sh webuiRunUpdate: a release branch version-compares and, if newer, lpFetchRelease (download + checksum-verify) the new tarball + dockerInstallApp redeploy + regen. No config-backup dance — lpFetchRelease replaces only the install tree; configs/logs are in the separate system tree. Verified against a local server: latest-version read + the no-update / update- available decision (0.2.0==0.2.0 no; 0.3.0>0.2.0 yes). Remaining: route the reset/reinstall recovery paths through the release fetch. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- scripts/update/check_update.sh | 29 ++++++++++++++- .../generators/system/webui_system_update.sh | 36 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/scripts/update/check_update.sh b/scripts/update/check_update.sh index 174db19..371f88b 100755 --- a/scripts/update/check_update.sh +++ b/scripts/update/check_update.sh @@ -25,10 +25,37 @@ webuiRunUpdate() return 1 fi if [[ "$git_updates" != "true" ]]; then - isError "Git updates are disabled (CFG_GIT_UPDATES). Enable them to update from the WebUI." + isError "Updates are disabled (CFG_GIT_UPDATES). Enable them to update from the WebUI." return 1 fi + # Release mode: version-compare the channel's latest against the local VERSION + # and, if newer, fetch + verify the new tarball and redeploy. No config backup + # dance — lpFetchRelease replaces only the install tree; configs/logs live in + # the separate system tree. + if [[ "$install_mode" == "release" ]]; then + webuiSystemUpdateCheck "force" + local cur lat + cur=$(tr -d ' \t\n\r' < "$script_dir/VERSION" 2>/dev/null) + lat=$(lpReleaseLatestVersion 2>/dev/null) + if [[ -z "$lat" ]]; then + isError "Could not reach the release server ($(lpReleaseBaseUrl))." + return 1 + fi + if ! lpVersionGt "$lat" "$cur"; then + isSuccessful "LibrePortal is already up to date (v${cur})." + return 0 + fi + isNotice "Update found — v${cur} → v${lat}. Fetching the verified release..." + lpFetchRelease "$lat" || { isError "Release fetch failed — install unchanged."; return 1; } + isNotice "Redeploying LibrePortal with the new version..." + dockerInstallApp "libreportal" + WEBUI_UPDATER_FORCE=1 webuiLibrePortalUpdate + webuiSystemUpdateCheck "force" + isSuccessful "LibrePortal has been updated to v${lat}." + return 0 + fi + # Credential guard — gitReset()/gitCheckGitDetails() would otherwise prompt # for missing git details and hang the task forever. Fail fast with a clear # message instead. diff --git a/scripts/webui/data/generators/system/webui_system_update.sh b/scripts/webui/data/generators/system/webui_system_update.sh index 797925a..88ecbfa 100755 --- a/scripts/webui/data/generators/system/webui_system_update.sh +++ b/scripts/webui/data/generators/system/webui_system_update.sh @@ -98,6 +98,42 @@ EOF fi } + # Release mode: compare the local VERSION against the channel's published + # latest.json (no git). Same throttle + same JSON schema, source="release". + if [[ "$install_mode" == "release" ]]; then + local latest_version="$current_version" rel_error="" + local do_fetch="false" + if [[ "$force_flag" == "force" || ! -f "$stamp_file" ]]; then + do_fetch="true" + else + local _now _last; _now=$(date +%s); _last=$(stat -c '%Y' "$stamp_file" 2>/dev/null || echo 0) + (( _now - _last >= fetch_interval )) && do_fetch="true" + fi + if [[ "$do_fetch" == "true" ]] && declare -f lpReleaseLatestVersion >/dev/null 2>&1; then + local _lv; _lv=$(lpReleaseLatestVersion 2>/dev/null) + if [[ -n "$_lv" ]]; then + latest_version="$_lv" + runAsManager touch "$stamp_file" 2>/dev/null || touch "$stamp_file" 2>/dev/null + else + rel_error="Could not reach the update server." + fi + elif [[ -f "$final_file" ]]; then + # Throttled: reuse the last-known latest so the badge doesn't flicker. + local _prev; _prev=$(grep -oE '"latest_version"[^,]*' "$final_file" 2>/dev/null | head -1 | sed -E 's/.*"([^"]*)"$/\1/') + [[ -n "$_prev" ]] && latest_version="$_prev" + fi + local update_available="false" + if declare -f lpVersionGt >/dev/null 2>&1 && lpVersionGt "$latest_version" "$current_version"; then + update_available="true" + fi + local can_update="false" + [[ "$git_updates" == "true" ]] && can_update="true" + _webuiWriteUpdateStatus "$update_available" "$can_update" \ + "$current_version" "$latest_version" \ + "" "" "0" "0" "${CFG_RELEASE_CHANNEL:-stable}" "release" "$rel_error" + return 0 + fi + # Not a git working copy, or a deliberately local install: we can't compare # against an upstream, so report "managed manually" rather than an error. if [[ ! -d "$repo_dir/.git" || "$install_mode" == "local" ]]; then