From 6677cd61320c2f020d8a9daea12c8b2f274f4e66 Mon Sep 17 00:00:00 2001 From: UNITRONIX <36471318+UNITRONIX@users.noreply.github.com> Date: Sun, 16 Aug 2026 10:19:57 +0200 Subject: [PATCH] fix(installer): clone matching branch from one-line install Refs #371 Thanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow) --- CHANGELOG.md | 1 + betterdesk.sh | 36 +++++++++++++++++++++++++--- docs/important/installer-contract.md | 5 ++++ install.sh | 32 +++++++++++++++++++------ 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ed27b65..ade39b03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ## [3.5.43] — 2026-08-15 ### Fixed +- **Native installer used `main` when curling `/dev/install.sh` (#371):** `install.sh` on the Development channel now defaults to branch `dev`, prints the cloned commit SHA, and switches an existing `/opt/betterdesk/source` clone onto that branch. Module download also prints Go/GOPROXY diagnostics, keeps a 15s heartbeat, and prefers `GOTOOLCHAIN=local` so the step cannot hang silently while auto-fetching another toolchain. - **Support Agent generator builds (Linux + Windows):** Windows MSI/portable no longer fail when `winicon` ran against sealed `BDBR1` branding (`invalid character 'B'`). Linux `.deb` / `.rpm` / AppImage / tar.gz packaging now expects the default Wails single binary instead of missing X11/Wayland companions (`ENOENT` under `data/build-cache`). Fyne dual layout remains when those binaries are present. Ships via panel update (`agentBuildWorker.js` + agent-source `build.sh`); retry Client Builds after update. Refs #373. --- diff --git a/betterdesk.sh b/betterdesk.sh index fe3e0f82..068a83d2 100644 --- a/betterdesk.sh +++ b/betterdesk.sh @@ -2662,33 +2662,63 @@ compile_go_server() { # Build print_info "Building BetterDesk server for $ARCH_NAME..." local output_name="betterdesk-server" + local go_bin + go_bin=$(command -v go) + print_info "Using $($go_bin version 2>/dev/null || echo 'unknown go')" + print_info "GOPROXY=${GOPROXY:-} GOSUMDB=${GOSUMDB:-} GOTOOLCHAIN=${GOTOOLCHAIN:-auto}" + + # Prefer the already-validated local toolchain so `go mod download` does not + # hang while silently fetching another toolchain from the network. + export GOTOOLCHAIN="${GOTOOLCHAIN:-local}" # Download dependencies. Keep this visible and bounded: Go may otherwise # silently fetch the toolchain named in go.mod on hosts with an older Go. print_info "Downloading Go modules (timeout: ${GO_MODULE_DOWNLOAD_TIMEOUT}s)..." local module_download_status=0 + local download_cmd=(go mod download -x) + if command -v stdbuf &> /dev/null; then + download_cmd=(stdbuf -oL -eL go mod download -x) + fi + + # Heartbeat so idle SSH sessions see progress even when proxy/DNS stalls. + local heartbeat_pid="" + ( + local elapsed=0 + while true; do + sleep 15 + elapsed=$((elapsed + 15)) + echo "[install] still downloading Go modules… ${elapsed}s elapsed" >&2 + done + ) & + heartbeat_pid=$! + if command -v timeout &> /dev/null; then - if timeout "${GO_MODULE_DOWNLOAD_TIMEOUT}s" go mod download -x; then + if timeout --foreground "${GO_MODULE_DOWNLOAD_TIMEOUT}s" "${download_cmd[@]}"; then : else module_download_status=$? fi else print_warning "'timeout' command is unavailable; module download will run without a deadline" - if go mod download -x; then + if "${download_cmd[@]}"; then : else module_download_status=$? fi fi + if [ -n "$heartbeat_pid" ]; then + kill "$heartbeat_pid" 2>/dev/null || true + wait "$heartbeat_pid" 2>/dev/null || true + fi + if [ "$module_download_status" -ne 0 ]; then if [ "$module_download_status" -eq 124 ]; then print_error "Go module download timed out after ${GO_MODULE_DOWNLOAD_TIMEOUT}s" else print_error "Go module download failed (exit code ${module_download_status})" fi - print_error "Check DNS, outbound HTTPS, firewall and GOPROXY access, then retry" + print_error "Check DNS, outbound HTTPS to proxy.golang.org / sum.golang.org / go.dev, firewall and GOPROXY, then retry" return 1 fi diff --git a/docs/important/installer-contract.md b/docs/important/installer-contract.md index 090a618e..bb66b939 100644 --- a/docs/important/installer-contract.md +++ b/docs/important/installer-contract.md @@ -18,6 +18,11 @@ result. | `betterdesk-support-agent/install.go` | Linux, Windows, macOS | Support-agent self-install/uninstall | | `scripts/installer-protocol-check.js` | Linux, Windows, Docker | Shared HTTP/HTTPS, redirect, SAN and TCP verification | +`install.sh` embeds `BETTERDESK_INSTALLER_CHANNEL` so a one-line install from +`.../dev/install.sh` clones `dev` and `.../main/install.sh` clones `main`. +When releasing this file onto `main`, set that channel to `main` (operators can +still override with `--branch` / `BETTERDESK_BRANCH`). + The `build-betterdesk.*` wrappers and `betterdesk-server/deploy.sh` are development or migration tools. They must not silently replace the official installer lifecycle or be presented as the primary production installation diff --git a/install.sh b/install.sh index 1d305b98..a900f9cb 100755 --- a/install.sh +++ b/install.sh @@ -8,15 +8,18 @@ # Docker legacy (two-container split images): # curl -fsSL .../install.sh | sudo bash -s -- --split # -# Native (git clone + betterdesk.sh --auto): +# Native stable (git clone + betterdesk.sh --auto): # curl -fsSL https://raw.githubusercontent.com/UNITRONIX/BetterDesk/main/install.sh | sudo bash -s -- --native # +# Native Development channel (this file on the `dev` branch defaults to --branch dev): +# curl -fsSL https://raw.githubusercontent.com/UNITRONIX/BetterDesk/dev/install.sh | sudo bash -s -- --native +# # Options (pass after "bash -s --"): # --docker | --native Installation mode (default: docker) # --split Legacy two-container layout (server + console images) # --install-dir PATH Install directory (default: /opt/betterdesk) # --version TAG Docker image tag / release baseline (default: 3.5.43) -# --branch BRANCH Git branch for native install (default: main) +# --branch BRANCH Git branch for native install (default: this installer channel) # --relay-mode auto|local|public Relay auto-detection strategy # --relay-servers IP[:port] Fixed relay address (overrides --relay-mode) # --admin-password PASS Set admin password (Docker: ADMIN_PASSWORD env) @@ -38,7 +41,11 @@ set -euo pipefail VERSION="1.0.0" BETTERDESK_REPO="${BETTERDESK_REPO:-UNITRONIX/BetterDesk}" -BETTERDESK_BRANCH="${BETTERDESK_BRANCH:-main}" +# Must match the GitHub branch that serves this install.sh URL +# (.../dev/install.sh → dev, .../main/install.sh → main). Override with +# --branch / BETTERDESK_BRANCH. Flip to "main" when releasing this file on main. +BETTERDESK_INSTALLER_CHANNEL="dev" +BETTERDESK_BRANCH="${BETTERDESK_BRANCH:-$BETTERDESK_INSTALLER_CHANNEL}" BETTERDESK_VERSION="${BETTERDESK_VERSION:-3.5.43}" BETTERDESK_RAW_BASE="${BETTERDESK_RAW_BASE:-https://raw.githubusercontent.com/${BETTERDESK_REPO}/${BETTERDESK_BRANCH}}" INSTALL_DIR="${INSTALL_DIR:-/opt/betterdesk}" @@ -79,7 +86,7 @@ warn() { echo -e "${C_YELLOW}!${C_RESET} $*" >&2; } die() { echo -e "${C_RED}✗${C_RESET} $*" >&2; exit 1; } usage() { - sed -n '4,27p' "$0" | sed 's/^# \?//' + sed -n '4,33p' "$0" | sed 's/^# \?//' exit 0 } @@ -529,17 +536,25 @@ uninstall_docker_mode() { install_native_mode() { local repo_dir="${INSTALL_DIR}/source" local relay + local commit_sha log "BetterDesk native installer v${VERSION}" + log "Native install branch: ${BETTERDESK_BRANCH} (override with --branch)" require_command git relay=$(resolve_relay_address) if [ -d "$repo_dir/.git" ]; then - log "Updating existing clone in ${repo_dir}..." + log "Updating existing clone in ${repo_dir} to ${BETTERDESK_BRANCH}..." + git -C "$repo_dir" remote set-url origin "https://github.com/${BETTERDESK_REPO}.git" || true git -C "$repo_dir" fetch --depth 1 origin "$BETTERDESK_BRANCH" - git -C "$repo_dir" checkout "$BETTERDESK_BRANCH" - git -C "$repo_dir" pull --ff-only origin "$BETTERDESK_BRANCH" || true + # Shallow clones previously pinned to another branch need a hard reset. + if ! git -C "$repo_dir" checkout -B "$BETTERDESK_BRANCH" "FETCH_HEAD"; then + warn "Could not switch existing clone to ${BETTERDESK_BRANCH}; recloning..." + rm -rf "$repo_dir" + git clone --depth 1 --branch "$BETTERDESK_BRANCH" \ + "https://github.com/${BETTERDESK_REPO}.git" "$repo_dir" + fi else log "Cloning ${BETTERDESK_REPO} (${BETTERDESK_BRANCH})..." rm -rf "$repo_dir" @@ -547,6 +562,9 @@ install_native_mode() { "https://github.com/${BETTERDESK_REPO}.git" "$repo_dir" fi + commit_sha=$(git -C "$repo_dir" rev-parse --short HEAD 2>/dev/null || echo "unknown") + log "Using ${BETTERDESK_REPO}@${BETTERDESK_BRANCH} (${commit_sha})" + chmod +x "${repo_dir}/betterdesk.sh" log "Running betterdesk.sh --auto..."