#!/bin/bash # build-cross.sh — Cross-compile KubeSolo OS Go binaries for multiple architectures # # Builds static binaries for amd64 and arm64 (or a single target). # This is used by CI/CD and for ARM64 device support. # # Usage: # build/scripts/build-cross.sh # Build both amd64 + arm64 # build/scripts/build-cross.sh --arch amd64 # Build amd64 only # build/scripts/build-cross.sh --arch arm64 # Build arm64 only # build/scripts/build-cross.sh --skip-tests # Skip Go tests (for CI where tests run separately) # # Output: # build/cache/kubesolo-update-linux-{amd64,arm64} # build/cache/kubesolo-cloudinit-linux-{amd64,arm64} set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" CACHE_DIR="${CACHE_DIR:-$PROJECT_ROOT/build/cache}" # Defaults ARCHES="amd64 arm64" SKIP_TESTS=false # Parse args while [ $# -gt 0 ]; do case "$1" in --arch) ARCHES="${2:?--arch requires a value (amd64 or arm64)}" shift 2 ;; --skip-tests) SKIP_TESTS=true shift ;; *) echo "Unknown option: $1" >&2 exit 1 ;; esac done mkdir -p "$CACHE_DIR" echo "=== KubeSolo OS Cross-Compilation ===" echo " Architectures: $ARCHES" echo "" # Run tests once (not per-arch, since Go tests are arch-independent) if [ "$SKIP_TESTS" = false ]; then echo "--- Running cloud-init tests ---" (cd "$PROJECT_ROOT/cloud-init" && go test ./... -count=1) || { echo "ERROR: Cloud-init tests failed" >&2 exit 1 } echo "--- Running update agent tests ---" (cd "$PROJECT_ROOT/update" && go test ./... -count=1) || { echo "ERROR: Update agent tests failed" >&2 exit 1 } echo "" fi # Build for each architecture for ARCH in $ARCHES; do echo "=== Building for linux/$ARCH ===" # Cloud-init binary CLOUDINIT_OUT="$CACHE_DIR/kubesolo-cloudinit-linux-$ARCH" echo "--- cloud-init → $CLOUDINIT_OUT ---" (cd "$PROJECT_ROOT/cloud-init" && \ CGO_ENABLED=0 GOOS=linux GOARCH="$ARCH" \ go build -ldflags='-s -w' -o "$CLOUDINIT_OUT" ./cmd/) echo " Size: $(ls -lh "$CLOUDINIT_OUT" | awk '{print $5}')" # Update agent binary UPDATE_OUT="$CACHE_DIR/kubesolo-update-linux-$ARCH" echo "--- update agent → $UPDATE_OUT ---" (cd "$PROJECT_ROOT/update" && \ CGO_ENABLED=0 GOOS=linux GOARCH="$ARCH" \ go build -ldflags='-s -w' -o "$UPDATE_OUT" .) echo " Size: $(ls -lh "$UPDATE_OUT" | awk '{print $5}')" # Create symlink for default arch (amd64) if [ "$ARCH" = "amd64" ]; then ln -sf "kubesolo-cloudinit-linux-$ARCH" "$CACHE_DIR/kubesolo-cloudinit" ln -sf "kubesolo-update-linux-$ARCH" "$CACHE_DIR/kubesolo-update" fi echo "" done echo "=== Cross-compilation complete ===" echo "" echo "Binaries:" for ARCH in $ARCHES; do echo " linux/$ARCH:" echo " $CACHE_DIR/kubesolo-cloudinit-linux-$ARCH" echo " $CACHE_DIR/kubesolo-update-linux-$ARCH" done echo ""