From 135b378820c160dcb858cbdfa968ff70358860a3 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Tue, 11 Nov 2025 21:26:33 +0000 Subject: [PATCH] Fix Windows/macOS host agent downloads for bare metal installs (related to #684) Bare metal installations couldn't serve Windows host agent downloads because the Windows and macOS binaries weren't included in the universal tarball. The download endpoint would return 404 when Windows users tried to install the host agent from a bare metal Pulse deployment (Proxmox LXC, Debian VM, etc.). Changes: - build-release.sh: Copy Windows/macOS host agent binaries into universal tarball - build-release.sh: Create symlinks for Windows binaries without .exe extension - validate-release.sh: Add Windows 386 binary and symlink to Docker validation - validate-release.sh: Add explicit validation that universal tarball contains all Windows/macOS binaries The universal tarball now matches the Docker image, ensuring both deployment methods can serve the complete set of downloadable binaries for the /download/ endpoint. --- scripts/build-release.sh | 17 +++++++++++++---- scripts/validate-release.sh | 20 +++++++++++++++++--- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/scripts/build-release.sh b/scripts/build-release.sh index ae6d9c9..821e08a 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -281,6 +281,19 @@ zip -j "$RELEASE_DIR/pulse-host-agent-v${VERSION}-windows-amd64.zip" "$BUILD_DIR zip -j "$RELEASE_DIR/pulse-host-agent-v${VERSION}-windows-arm64.zip" "$BUILD_DIR/pulse-host-agent-windows-arm64.exe" zip -j "$RELEASE_DIR/pulse-host-agent-v${VERSION}-windows-386.zip" "$BUILD_DIR/pulse-host-agent-windows-386.exe" +# Copy Windows and macOS binaries into universal tarball for /download/ endpoint +echo "Adding Windows and macOS binaries to universal tarball..." +cp "$BUILD_DIR/pulse-host-agent-darwin-amd64" "$universal_dir/bin/" +cp "$BUILD_DIR/pulse-host-agent-darwin-arm64" "$universal_dir/bin/" +cp "$BUILD_DIR/pulse-host-agent-windows-amd64.exe" "$universal_dir/bin/" +cp "$BUILD_DIR/pulse-host-agent-windows-arm64.exe" "$universal_dir/bin/" +cp "$BUILD_DIR/pulse-host-agent-windows-386.exe" "$universal_dir/bin/" + +# Create symlinks for Windows binaries without .exe extension (required for download endpoint) +ln -s pulse-host-agent-windows-amd64.exe "$universal_dir/bin/pulse-host-agent-windows-amd64" +ln -s pulse-host-agent-windows-arm64.exe "$universal_dir/bin/pulse-host-agent-windows-arm64" +ln -s pulse-host-agent-windows-386.exe "$universal_dir/bin/pulse-host-agent-windows-386" + # Create universal tarball cd "$universal_dir" tar -czf "../../$RELEASE_DIR/pulse-v${VERSION}.tar.gz" . @@ -289,10 +302,6 @@ cd ../.. # Cleanup rm -rf "$universal_dir" -# NOTE: Standalone binaries are NOT copied to release directory -# They are only included in Docker images for /download/ endpoints -# Users should download versioned tarballs/zips from GitHub releases instead - # Optionally package Helm chart if [ "${SKIP_HELM_PACKAGE:-0}" != "1" ]; then if command -v helm >/dev/null 2>&1; then diff --git a/scripts/validate-release.sh b/scripts/validate-release.sh index ba123c7..421514a 100755 --- a/scripts/validate-release.sh +++ b/scripts/validate-release.sh @@ -98,8 +98,8 @@ if [ "$SKIP_DOCKER" = false ]; then # Validate all required binaries exist and are non-empty info "Checking downloadable binaries in /opt/pulse/bin/..." - docker run --rm --entrypoint /bin/sh "$IMAGE" -c 'set -euo pipefail; cd /opt/pulse/bin; required="pulse pulse-docker-agent pulse-docker-agent-linux-amd64 pulse-docker-agent-linux-arm64 pulse-docker-agent-linux-armv7 pulse-docker-agent-linux-armv6 pulse-docker-agent-linux-386 pulse-host-agent-linux-amd64 pulse-host-agent-linux-arm64 pulse-host-agent-linux-armv7 pulse-host-agent-linux-armv6 pulse-host-agent-linux-386 pulse-host-agent-darwin-amd64 pulse-host-agent-darwin-arm64 pulse-host-agent-windows-amd64.exe pulse-host-agent-windows-amd64 pulse-host-agent-windows-arm64.exe pulse-host-agent-windows-arm64 pulse-sensor-proxy pulse-sensor-proxy-linux-amd64 pulse-sensor-proxy-linux-arm64 pulse-sensor-proxy-linux-armv7 pulse-sensor-proxy-linux-armv6 pulse-sensor-proxy-linux-386"; for f in $required; do [ -e "$f" ] || { echo "missing binary $f" >&2; exit 1; }; [ -s "$f" ] || { echo "empty binary $f" >&2; exit 1; }; done; [ "$(readlink pulse-host-agent-windows-amd64)" = "pulse-host-agent-windows-amd64.exe" ] || { echo "windows amd64 symlink broken" >&2; exit 1; }; [ "$(readlink pulse-host-agent-windows-arm64)" = "pulse-host-agent-windows-arm64.exe" ] || { echo "windows arm64 symlink broken" >&2; exit 1; }; echo "All binaries present"' || { error "Binary validation failed"; exit 1; } - success "All downloadable binaries present (24 binaries + 2 Windows symlinks)" + docker run --rm --entrypoint /bin/sh "$IMAGE" -c 'set -euo pipefail; cd /opt/pulse/bin; required="pulse pulse-docker-agent pulse-docker-agent-linux-amd64 pulse-docker-agent-linux-arm64 pulse-docker-agent-linux-armv7 pulse-docker-agent-linux-armv6 pulse-docker-agent-linux-386 pulse-host-agent-linux-amd64 pulse-host-agent-linux-arm64 pulse-host-agent-linux-armv7 pulse-host-agent-linux-armv6 pulse-host-agent-linux-386 pulse-host-agent-darwin-amd64 pulse-host-agent-darwin-arm64 pulse-host-agent-windows-amd64.exe pulse-host-agent-windows-amd64 pulse-host-agent-windows-arm64.exe pulse-host-agent-windows-arm64 pulse-host-agent-windows-386.exe pulse-host-agent-windows-386 pulse-sensor-proxy pulse-sensor-proxy-linux-amd64 pulse-sensor-proxy-linux-arm64 pulse-sensor-proxy-linux-armv7 pulse-sensor-proxy-linux-armv6 pulse-sensor-proxy-linux-386"; for f in $required; do [ -e "$f" ] || { echo "missing binary $f" >&2; exit 1; }; [ -s "$f" ] || { echo "empty binary $f" >&2; exit 1; }; done; [ "$(readlink pulse-host-agent-windows-amd64)" = "pulse-host-agent-windows-amd64.exe" ] || { echo "windows amd64 symlink broken" >&2; exit 1; }; [ "$(readlink pulse-host-agent-windows-arm64)" = "pulse-host-agent-windows-arm64.exe" ] || { echo "windows arm64 symlink broken" >&2; exit 1; }; [ "$(readlink pulse-host-agent-windows-386)" = "pulse-host-agent-windows-386.exe" ] || { echo "windows 386 symlink broken" >&2; exit 1; }; echo "All binaries present"' || { error "Binary validation failed"; exit 1; } + success "All downloadable binaries present (26 binaries + 3 Windows symlinks)" # Validate version embedding in Docker image binaries info "Validating version embedding in Docker image binaries..." @@ -189,7 +189,21 @@ success "Platform-specific tarballs contain all required files" # Validate universal tarball tar -tzf "pulse-v${PULSE_VERSION}.tar.gz" ./VERSION >/dev/null 2>&1 || { error "Universal tarball missing VERSION file"; exit 1; } -success "Universal tarball validated" + +# Validate universal tarball contains Windows/macOS binaries for download endpoint +info "Validating universal tarball contains Windows/macOS binaries..." +for binary in \ + ./bin/pulse-host-agent-darwin-amd64 \ + ./bin/pulse-host-agent-darwin-arm64 \ + ./bin/pulse-host-agent-windows-amd64.exe \ + ./bin/pulse-host-agent-windows-arm64.exe \ + ./bin/pulse-host-agent-windows-386.exe \ + ./bin/pulse-host-agent-windows-amd64 \ + ./bin/pulse-host-agent-windows-arm64 \ + ./bin/pulse-host-agent-windows-386; do + tar -tzf "pulse-v${PULSE_VERSION}.tar.gz" "$binary" >/dev/null 2>&1 || { error "Universal tarball missing $binary"; exit 1; } +done +success "Universal tarball validated (includes Windows/macOS binaries)" # Validate macOS tarball tar -tzf "pulse-host-agent-v${PULSE_VERSION}-darwin-arm64.tar.gz" pulse-host-agent-darwin-arm64 >/dev/null 2>&1 || { error "macOS tarball validation failed"; exit 1; }