#!/bin/bash # fetch-components.sh — Download Tiny Core ISO and KubeSolo binary 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}" # Load versions # shellcheck source=../config/versions.env . "$SCRIPT_DIR/../config/versions.env" # Verify SHA256 checksum of a downloaded file verify_checksum() { local file="$1" expected="$2" name="$3" # Skip if no expected checksum provided [ -z "$expected" ] && return 0 local actual actual=$(sha256sum "$file" | awk '{print $1}') if [ "$actual" = "$expected" ]; then echo " Checksum OK: $name" return 0 else echo "ERROR: Checksum mismatch for $name" echo " Expected: $expected" echo " Got: $actual" rm -f "$file" return 1 fi } mkdir -p "$CACHE_DIR" # Detect target architecture FETCH_ARCH="${TARGET_ARCH:-amd64}" # --- ARM64: piCore64 image instead of x86_64 ISO --- if [ "$FETCH_ARCH" = "arm64" ]; then PICORE_IMG="$CACHE_DIR/$PICORE_IMAGE" if [ -f "$PICORE_IMG" ]; then echo "==> piCore64 image already cached: $PICORE_IMG" else echo "==> Downloading piCore64 ${PICORE_VERSION} (${PICORE_ARCH})..." echo " URL: $PICORE_IMAGE_URL" wget -q --show-progress -O "$PICORE_IMG" "$PICORE_IMAGE_URL" 2>/dev/null || \ curl -fSL "$PICORE_IMAGE_URL" -o "$PICORE_IMG" echo "==> Downloaded: $PICORE_IMG ($(du -h "$PICORE_IMG" | cut -f1))" fi # Also fetch RPi firmware echo "==> Fetching RPi firmware..." "$SCRIPT_DIR/fetch-rpi-firmware.sh" # Download ARM64 KubeSolo binary KUBESOLO_VERSION="${KUBESOLO_VERSION:-v1.1.0}" KUBESOLO_BIN_ARM64="$CACHE_DIR/kubesolo-arm64" if [ -f "$KUBESOLO_BIN_ARM64" ]; then echo "==> KubeSolo ARM64 binary already cached: $KUBESOLO_BIN_ARM64" else echo "==> Downloading KubeSolo ${KUBESOLO_VERSION} (arm64)..." BIN_URL="https://github.com/portainer/kubesolo/releases/download/${KUBESOLO_VERSION}/kubesolo-${KUBESOLO_VERSION}-linux-arm64-musl.tar.gz" BIN_URL_FALLBACK="https://github.com/portainer/kubesolo/releases/download/${KUBESOLO_VERSION}/kubesolo-${KUBESOLO_VERSION}-linux-arm64.tar.gz" TEMP_DIR=$(mktemp -d) echo " URL: $BIN_URL" if curl -fSL "$BIN_URL" -o "$TEMP_DIR/kubesolo.tar.gz" 2>/dev/null; then echo " Downloaded musl variant (arm64)" elif curl -fSL "$BIN_URL_FALLBACK" -o "$TEMP_DIR/kubesolo.tar.gz" 2>/dev/null; then echo " Downloaded glibc variant (arm64 fallback)" else echo "ERROR: Failed to download KubeSolo ARM64 from GitHub." rm -rf "$TEMP_DIR" exit 1 fi tar -xzf "$TEMP_DIR/kubesolo.tar.gz" -C "$TEMP_DIR" FOUND_BIN=$(find "$TEMP_DIR" -name "kubesolo" -type f ! -name "*.tar.gz" | head -1) if [ -z "$FOUND_BIN" ]; then echo "ERROR: Could not find kubesolo binary in extracted archive" rm -rf "$TEMP_DIR" exit 1 fi cp "$FOUND_BIN" "$KUBESOLO_BIN_ARM64" chmod +x "$KUBESOLO_BIN_ARM64" rm -rf "$TEMP_DIR" echo "==> KubeSolo ARM64 binary: $KUBESOLO_BIN_ARM64 ($(du -h "$KUBESOLO_BIN_ARM64" | cut -f1))" fi # Skip x86_64 ISO and TCZ downloads for ARM64 echo "" echo "==> ARM64 fetch complete." echo "==> Component cache:" ls -lh "$CACHE_DIR"/ 2>/dev/null || true exit 0 fi # --- x86_64: Tiny Core Linux ISO --- TC_ISO="$CACHE_DIR/$TINYCORE_ISO" TC_URL="${TINYCORE_MIRROR}/${TINYCORE_VERSION%%.*}.x/${TINYCORE_ARCH}/release/${TINYCORE_ISO}" if [ -f "$TC_ISO" ]; then echo "==> Tiny Core ISO already cached: $TC_ISO" else echo "==> Downloading Tiny Core Linux ${TINYCORE_VERSION} (${TINYCORE_ARCH})..." echo " URL: $TC_URL" wget -q --show-progress -O "$TC_ISO" "$TC_URL" || { # Fallback: try alternate mirror structure TC_URL_ALT="${TINYCORE_MIRROR}/${TINYCORE_VERSION%%.*}.x/${TINYCORE_ARCH}/release/CorePure64-current.iso" echo " Primary URL failed, trying: $TC_URL_ALT" wget -q --show-progress -O "$TC_ISO" "$TC_URL_ALT" } echo "==> Downloaded: $TC_ISO ($(du -h "$TC_ISO" | cut -f1))" verify_checksum "$TC_ISO" "$TINYCORE_ISO_SHA256" "Tiny Core ISO" fi # --- KubeSolo --- KUBESOLO_VERSION="${KUBESOLO_VERSION:-v1.1.0}" KUBESOLO_BIN="$CACHE_DIR/kubesolo" if [ -f "$KUBESOLO_BIN" ]; then echo "==> KubeSolo binary already cached: $KUBESOLO_BIN" else echo "==> Downloading KubeSolo ${KUBESOLO_VERSION}..." # Determine architecture ARCH="${TARGET_ARCH:-amd64}" OS="linux" # Build download URL from GitHub releases # Available variants: kubesolo-v1.1.0-linux-amd64.tar.gz, kubesolo-v1.1.0-linux-amd64-musl.tar.gz # We use the musl variant for maximum compatibility with Tiny Core Linux (musl-based) BIN_URL="https://github.com/portainer/kubesolo/releases/download/${KUBESOLO_VERSION}/kubesolo-${KUBESOLO_VERSION}-${OS}-${ARCH}-musl.tar.gz" BIN_URL_FALLBACK="https://github.com/portainer/kubesolo/releases/download/${KUBESOLO_VERSION}/kubesolo-${KUBESOLO_VERSION}-${OS}-${ARCH}.tar.gz" TEMP_DIR=$(mktemp -d) trap 'rm -rf "$TEMP_DIR"' EXIT echo " URL: $BIN_URL" if curl -fSL "$BIN_URL" -o "$TEMP_DIR/kubesolo.tar.gz" 2>/dev/null; then echo " Downloaded musl variant" elif curl -fSL "$BIN_URL_FALLBACK" -o "$TEMP_DIR/kubesolo.tar.gz" 2>/dev/null; then echo " Downloaded glibc variant (fallback)" else echo "ERROR: Failed to download KubeSolo from GitHub." echo " Tried: $BIN_URL" echo " Tried: $BIN_URL_FALLBACK" echo "" echo " Manual step:" echo " 1. Download from: https://github.com/portainer/kubesolo/releases" echo " 2. Extract and copy binary to: $KUBESOLO_BIN" echo " 3. Re-run: make rootfs" exit 1 fi # Extract binary from tarball tar -xzf "$TEMP_DIR/kubesolo.tar.gz" -C "$TEMP_DIR" # Find the kubesolo binary in extracted contents FOUND_BIN=$(find "$TEMP_DIR" -name "kubesolo" -type f ! -name "*.tar.gz" | head -1) if [ -z "$FOUND_BIN" ]; then echo "ERROR: Could not find kubesolo binary in extracted archive" echo " Archive contents:" ls -la "$TEMP_DIR"/ exit 1 fi cp "$FOUND_BIN" "$KUBESOLO_BIN" chmod +x "$KUBESOLO_BIN" trap - EXIT rm -rf "$TEMP_DIR" echo "==> KubeSolo binary: $KUBESOLO_BIN ($(du -h "$KUBESOLO_BIN" | cut -f1))" verify_checksum "$KUBESOLO_BIN" "$KUBESOLO_SHA256" "KubeSolo binary" fi # --- Tiny Core kernel module extensions (netfilter, iptables) --- # The base Tiny Core initramfs does NOT include netfilter kernel modules. # They are distributed as separate TCZ (squashfs) extensions. # KubeSolo requires netfilter for kube-proxy, iptables NAT, conntrack, etc. # Detect kernel version from the cached ISO KVER="" if [ -f "$TC_ISO" ]; then # Try to detect kernel version from ISO without mounting # Tiny Core 17.0 uses 6.18.2-tinycore64 KVER="6.18.2-tinycore64" fi NETFILTER_TCZ="$CACHE_DIR/ipv6-netfilter-${KVER}.tcz" NETFILTER_TCZ_URL="https://distro.ibiblio.org/tinycorelinux/${TINYCORE_VERSION%%.*}.x/${TINYCORE_ARCH}/tcz/ipv6-netfilter-${KVER}.tcz" if [ -f "$NETFILTER_TCZ" ]; then echo "==> Netfilter modules already cached: $NETFILTER_TCZ" else echo "==> Downloading netfilter kernel modules (ipv6-netfilter-${KVER}.tcz)..." echo " URL: $NETFILTER_TCZ_URL" if wget -q --show-progress -O "$NETFILTER_TCZ" "$NETFILTER_TCZ_URL" 2>/dev/null || \ curl -fSL "$NETFILTER_TCZ_URL" -o "$NETFILTER_TCZ" 2>/dev/null; then echo "==> Downloaded: $NETFILTER_TCZ ($(du -h "$NETFILTER_TCZ" | cut -f1))" verify_checksum "$NETFILTER_TCZ" "$NETFILTER_TCZ_SHA256" "netfilter TCZ" else echo "WARN: Failed to download netfilter modules. kube-proxy may not work." rm -f "$NETFILTER_TCZ" fi fi NET_BRIDGING_TCZ="$CACHE_DIR/net-bridging-${KVER}.tcz" NET_BRIDGING_TCZ_URL="https://distro.ibiblio.org/tinycorelinux/${TINYCORE_VERSION%%.*}.x/${TINYCORE_ARCH}/tcz/net-bridging-${KVER}.tcz" if [ -f "$NET_BRIDGING_TCZ" ]; then echo "==> Net-bridging modules already cached: $NET_BRIDGING_TCZ" else echo "==> Downloading net-bridging kernel modules (net-bridging-${KVER}.tcz)..." echo " URL: $NET_BRIDGING_TCZ_URL" if wget -q --show-progress -O "$NET_BRIDGING_TCZ" "$NET_BRIDGING_TCZ_URL" 2>/dev/null || \ curl -fSL "$NET_BRIDGING_TCZ_URL" -o "$NET_BRIDGING_TCZ" 2>/dev/null; then echo "==> Downloaded: $NET_BRIDGING_TCZ ($(du -h "$NET_BRIDGING_TCZ" | cut -f1))" verify_checksum "$NET_BRIDGING_TCZ" "$NET_BRIDGING_TCZ_SHA256" "net-bridging TCZ" else echo "WARN: Failed to download net-bridging modules. CNI bridge may not work." rm -f "$NET_BRIDGING_TCZ" fi fi IPTABLES_TCZ="$CACHE_DIR/iptables.tcz" IPTABLES_TCZ_URL="https://distro.ibiblio.org/tinycorelinux/${TINYCORE_VERSION%%.*}.x/${TINYCORE_ARCH}/tcz/iptables.tcz" if [ -f "$IPTABLES_TCZ" ]; then echo "==> iptables userspace already cached: $IPTABLES_TCZ" else echo "==> Downloading iptables userspace tools..." echo " URL: $IPTABLES_TCZ_URL" if wget -q --show-progress -O "$IPTABLES_TCZ" "$IPTABLES_TCZ_URL" 2>/dev/null || \ curl -fSL "$IPTABLES_TCZ_URL" -o "$IPTABLES_TCZ" 2>/dev/null; then echo "==> Downloaded: $IPTABLES_TCZ ($(du -h "$IPTABLES_TCZ" | cut -f1))" verify_checksum "$IPTABLES_TCZ" "$IPTABLES_TCZ_SHA256" "iptables TCZ" else echo "WARN: Failed to download iptables. KubeSolo bundles its own but this is a fallback." rm -f "$IPTABLES_TCZ" fi fi # --- Summary --- echo "" echo "==> Component cache:" ls -lh "$CACHE_DIR"/ 2>/dev/null || true echo "" echo "==> Fetch complete."