Add Windows ARM64 support for host agent (related to #654)
Windows 11 25H2 ships exclusively on ARM64 hardware. When users on ARM64 attempt to install the host agent, the Service Control Manager fails to load the amd64 binary with ERROR_BAD_EXE_FORMAT, surfaced as "The Pulse Host Agent is not compatible with this Windows version". Changes: - Dockerfile: Build pulse-host-agent-windows-arm64.exe alongside amd64 - Dockerfile: Copy windows-arm64 binary and create symlink for download endpoint - install-host-agent.ps1: Use RuntimeInformation.OSArchitecture to detect ARM64 - build-release.sh: Build darwin-amd64, darwin-arm64, windows-amd64, windows-arm64 - build-release.sh: Package Windows binaries as .zip archives - validate-release.sh: Check for windows-arm64 binary and symlink - validate-release.sh: Add architecture validation for all darwin/windows variants The installer now correctly detects ARM64 and downloads the appropriate binary.
This commit is contained in:
parent
2a79d57f73
commit
32e0d453c4
5 changed files with 65 additions and 11 deletions
12
Dockerfile
12
Dockerfile
|
|
@ -108,7 +108,11 @@ RUN --mount=type=cache,id=pulse-go-mod,target=/go/pkg/mod \
|
|||
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build \
|
||||
-ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=${VERSION}" \
|
||||
-trimpath \
|
||||
-o pulse-host-agent-windows-amd64.exe ./cmd/pulse-host-agent
|
||||
-o pulse-host-agent-windows-amd64.exe ./cmd/pulse-host-agent && \
|
||||
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build \
|
||||
-ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=${VERSION}" \
|
||||
-trimpath \
|
||||
-o pulse-host-agent-windows-arm64.exe ./cmd/pulse-host-agent
|
||||
|
||||
# Build pulse-sensor-proxy for all Linux architectures (for download endpoint)
|
||||
RUN --mount=type=cache,id=pulse-go-mod,target=/go/pkg/mod \
|
||||
|
|
@ -206,8 +210,10 @@ COPY --from=backend-builder /app/pulse-host-agent-linux-armv7 /opt/pulse/bin/
|
|||
COPY --from=backend-builder /app/pulse-host-agent-darwin-amd64 /opt/pulse/bin/
|
||||
COPY --from=backend-builder /app/pulse-host-agent-darwin-arm64 /opt/pulse/bin/
|
||||
COPY --from=backend-builder /app/pulse-host-agent-windows-amd64.exe /opt/pulse/bin/
|
||||
# Create symlink for Windows without .exe extension
|
||||
RUN ln -s pulse-host-agent-windows-amd64.exe /opt/pulse/bin/pulse-host-agent-windows-amd64
|
||||
COPY --from=backend-builder /app/pulse-host-agent-windows-arm64.exe /opt/pulse/bin/
|
||||
# Create symlinks for Windows without .exe extension
|
||||
RUN ln -s pulse-host-agent-windows-amd64.exe /opt/pulse/bin/pulse-host-agent-windows-amd64 && \
|
||||
ln -s pulse-host-agent-windows-arm64.exe /opt/pulse/bin/pulse-host-agent-windows-arm64
|
||||
|
||||
# Copy multi-arch pulse-sensor-proxy binaries for download endpoint
|
||||
COPY --from=backend-builder /app/pulse-sensor-proxy-linux-amd64 /opt/pulse/bin/
|
||||
|
|
|
|||
|
|
@ -131,7 +131,16 @@ Write-Host " Install Path: $InstallPath"
|
|||
Write-Host ""
|
||||
|
||||
# Determine architecture
|
||||
$arch = if ([Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" }
|
||||
$osArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
||||
switch ($osArch) {
|
||||
'Arm64' { $arch = 'arm64' }
|
||||
'X64' { $arch = 'amd64' }
|
||||
'X86' { $arch = '386' }
|
||||
default {
|
||||
Write-Error "Unsupported architecture: $osArch"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
$downloadUrl = "$PulseUrl/download/pulse-host-agent?platform=windows&arch=$arch"
|
||||
|
||||
Write-Info "Downloading agent binary from $downloadUrl..."
|
||||
|
|
|
|||
|
|
@ -235,7 +235,14 @@ chmod +x "$universal_dir/bin/pulse-host-agent"
|
|||
# Add VERSION file
|
||||
echo "$VERSION" > "$universal_dir/VERSION"
|
||||
|
||||
# Build host agent for macOS arm64
|
||||
# Build host agent for macOS
|
||||
echo "Building host agent for macOS amd64..."
|
||||
env GOOS=darwin GOARCH=amd64 go build \
|
||||
-ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \
|
||||
-trimpath \
|
||||
-o "$BUILD_DIR/pulse-host-agent-darwin-amd64" \
|
||||
./cmd/pulse-host-agent
|
||||
|
||||
echo "Building host agent for macOS arm64..."
|
||||
env GOOS=darwin GOARCH=arm64 go build \
|
||||
-ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \
|
||||
|
|
@ -243,8 +250,26 @@ env GOOS=darwin GOARCH=arm64 go build \
|
|||
-o "$BUILD_DIR/pulse-host-agent-darwin-arm64" \
|
||||
./cmd/pulse-host-agent
|
||||
|
||||
# Package macOS host agent
|
||||
# Build host agent for Windows
|
||||
echo "Building host agent for Windows amd64..."
|
||||
env GOOS=windows GOARCH=amd64 go build \
|
||||
-ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \
|
||||
-trimpath \
|
||||
-o "$BUILD_DIR/pulse-host-agent-windows-amd64.exe" \
|
||||
./cmd/pulse-host-agent
|
||||
|
||||
echo "Building host agent for Windows arm64..."
|
||||
env GOOS=windows GOARCH=arm64 go build \
|
||||
-ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \
|
||||
-trimpath \
|
||||
-o "$BUILD_DIR/pulse-host-agent-windows-arm64.exe" \
|
||||
./cmd/pulse-host-agent
|
||||
|
||||
# Package standalone host agent binaries
|
||||
tar -czf "$RELEASE_DIR/pulse-host-agent-v${VERSION}-darwin-amd64.tar.gz" -C "$BUILD_DIR" pulse-host-agent-darwin-amd64
|
||||
tar -czf "$RELEASE_DIR/pulse-host-agent-v${VERSION}-darwin-arm64.tar.gz" -C "$BUILD_DIR" pulse-host-agent-darwin-arm64
|
||||
zip -j "$RELEASE_DIR/pulse-host-agent-v${VERSION}-windows-amd64.zip" "$BUILD_DIR/pulse-host-agent-windows-amd64.exe"
|
||||
zip -j "$RELEASE_DIR/pulse-host-agent-v${VERSION}-windows-arm64.zip" "$BUILD_DIR/pulse-host-agent-windows-arm64.exe"
|
||||
|
||||
# Create universal tarball
|
||||
cd "$universal_dir"
|
||||
|
|
@ -268,8 +293,11 @@ for build_name in "${!builds[@]}"; do
|
|||
cp "$BUILD_DIR/pulse-host-agent-$build_name" "$RELEASE_DIR/"
|
||||
done
|
||||
|
||||
# Also copy standalone macOS host-agent (not tarballed version)
|
||||
# Also copy standalone macOS and Windows host-agent binaries
|
||||
cp "$BUILD_DIR/pulse-host-agent-darwin-amd64" "$RELEASE_DIR/"
|
||||
cp "$BUILD_DIR/pulse-host-agent-darwin-arm64" "$RELEASE_DIR/"
|
||||
cp "$BUILD_DIR/pulse-host-agent-windows-amd64.exe" "$RELEASE_DIR/"
|
||||
cp "$BUILD_DIR/pulse-host-agent-windows-arm64.exe" "$RELEASE_DIR/"
|
||||
|
||||
# Optionally package Helm chart
|
||||
if [ "${SKIP_HELM_PACKAGE:-0}" != "1" ]; then
|
||||
|
|
|
|||
|
|
@ -131,7 +131,16 @@ Write-Host " Install Path: $InstallPath"
|
|||
Write-Host ""
|
||||
|
||||
# Determine architecture
|
||||
$arch = if ([Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" }
|
||||
$osArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
||||
switch ($osArch) {
|
||||
'Arm64' { $arch = 'arm64' }
|
||||
'X64' { $arch = 'amd64' }
|
||||
'X86' { $arch = '386' }
|
||||
default {
|
||||
Write-Error "Unsupported architecture: $osArch"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
$downloadUrl = "$PulseUrl/download/pulse-host-agent?platform=windows&arch=$arch"
|
||||
|
||||
Write-Info "Downloading agent binary from $downloadUrl..."
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ success "All installer/uninstaller scripts present and executable"
|
|||
|
||||
# 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-host-agent-linux-amd64 pulse-host-agent-linux-arm64 pulse-host-agent-linux-armv7 pulse-host-agent-darwin-amd64 pulse-host-agent-darwin-arm64 pulse-host-agent-windows-amd64.exe pulse-host-agent-windows-amd64 pulse-sensor-proxy pulse-sensor-proxy-linux-amd64 pulse-sensor-proxy-linux-arm64 pulse-sensor-proxy-linux-armv7"; 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 symlink broken" >&2; exit 1; }; echo "All binaries present"' || { error "Binary validation failed"; exit 1; }
|
||||
success "All downloadable binaries present (16 binaries + Windows symlink)"
|
||||
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-host-agent-linux-amd64 pulse-host-agent-linux-arm64 pulse-host-agent-linux-armv7 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"; 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 (18 binaries + 2 Windows symlinks)"
|
||||
|
||||
# Validate version embedding in Docker image binaries
|
||||
info "Validating version embedding in Docker image binaries..."
|
||||
|
|
@ -191,8 +191,10 @@ if command -v file >/dev/null 2>&1; then
|
|||
file pulse-host-agent-linux-amd64 | grep -qF 'ELF 64-bit' | grep -qF 'x86-64' || warn "pulse-host-agent-linux-amd64 architecture check failed"
|
||||
file pulse-host-agent-linux-arm64 | grep -qF 'ELF 64-bit' | grep -qF 'aarch64' || warn "pulse-host-agent-linux-arm64 architecture check failed"
|
||||
file pulse-host-agent-linux-armv7 | grep -qF 'ELF 32-bit' | grep -qF 'ARM' || warn "pulse-host-agent-linux-armv7 architecture check failed"
|
||||
file pulse-host-agent-darwin-amd64 | grep -qF 'Mach-O' | grep -qF 'x86_64' || warn "pulse-host-agent-darwin-amd64 architecture check failed"
|
||||
file pulse-host-agent-darwin-arm64 | grep -qF 'Mach-O' | grep -qF 'arm64' || warn "pulse-host-agent-darwin-arm64 architecture check failed"
|
||||
file pulse-host-agent-windows-amd64.exe | grep -qF 'PE32+' || warn "pulse-host-agent-windows-amd64.exe architecture check failed"
|
||||
file pulse-host-agent-windows-amd64.exe | grep -qF 'PE32+' | grep -qF 'x86-64' || warn "pulse-host-agent-windows-amd64.exe architecture check failed"
|
||||
file pulse-host-agent-windows-arm64.exe | grep -qF 'PE32+' | grep -qF 'Aarch64' || warn "pulse-host-agent-windows-arm64.exe architecture check failed"
|
||||
|
||||
success "Binary architectures validated"
|
||||
fi
|
||||
|
|
|
|||
Loading…
Reference in a new issue