Files
zosbuilder/scripts/fetch-github.sh

215 lines
7.0 KiB
Bash
Executable File

#!/bin/sh
set -e
GITHUB_DIR="/build/github"
INITRAMFS_ROOT="/build/initramfs"
CACHE_TIMEOUT=3600 # 1 hour cache
echo "[+] Fetching GitHub components..."
# DIAGNOSTIC: Check GitHub connectivity and cache
echo "[DEBUG] Checking GitHub connectivity..."
echo "[DEBUG] Cache directory: $GITHUB_DIR"
echo "[DEBUG] Existing cache files: $(ls -la $GITHUB_DIR 2>/dev/null | wc -l)"
echo "[DEBUG] GitHub API rate limit check..."
github_status=$(curl -s -I https://api.github.com/repos/threefoldtech/zinit/releases/latest | head -1 | awk '{print $2}')
echo "[DEBUG] GitHub API response code: $github_status"
if [ "$github_status" != "200" ]; then
echo "[DEBUG] WARNING: GitHub API may be inaccessible - code: $github_status"
fi
echo "[DEBUG] Available tools: curl=$(command -v curl >/dev/null && echo 'YES' || echo 'NO'), wget=$(command -v wget >/dev/null && echo 'YES' || echo 'NO')"
# Create cache directory
mkdir -p "$GITHUB_DIR"
# Function to get latest release info
get_latest_release() {
local repo="$1"
local cache_file="$GITHUB_DIR/${repo//\//_}_release.json"
# Check cache first
if [ -f "$cache_file" ] && [ $(($(date +%s) - $(stat -c %Y "$cache_file"))) -lt $CACHE_TIMEOUT ]; then
cat "$cache_file"
return
fi
# Fetch latest release info
local api_url="https://api.github.com/repos/$repo/releases/latest"
echo " Fetching release info for $repo..." >&2
if command -v curl >/dev/null; then
curl -s "$api_url" | tee "$cache_file"
else
wget -qO- "$api_url" | tee "$cache_file"
fi
}
# Function to extract download URL from release JSON
get_download_url() {
local release_json="$1"
local pattern="$2"
echo "$release_json" | grep -o '"browser_download_url": *"[^"]*"' | \
grep "$pattern" | head -1 | cut -d '"' -f 4
}
# Function to download with retry
download_with_retry() {
local url="$1"
local output="$2"
local max_attempts=3
local attempt=1
while [ $attempt -le $max_attempts ]; do
echo " Attempt $attempt/$max_attempts..."
if command -v curl >/dev/null; then
if curl -L --fail -o "$output" "$url"; then
return 0
fi
else
if wget -O "$output" "$url"; then
return 0
fi
fi
attempt=$((attempt + 1))
if [ $attempt -le $max_attempts ]; then
echo " Retrying in 5 seconds..."
sleep 5
fi
done
echo " Error: Failed to download after $max_attempts attempts" >&2
return 1
}
# Function to download and install binary
install_github_binary() {
local repo="$1"
local binary_name="$2"
local install_path="$3"
local download_pattern="$4"
echo " Installing: $repo -> $install_path/$binary_name"
# Get release information
local release_json=$(get_latest_release "$repo")
if [ -z "$release_json" ]; then
echo " Error: Failed to get release info for $repo" >&2
echo "[DEBUG] GitHub API call failed for $repo - check network/rate limits"
return 1
fi
# Check if this is a "Not Found" response
if echo "$release_json" | grep -q '"message": *"Not Found"'; then
echo " Error: Repository $repo not found or has no releases" >&2
echo "[DEBUG] Repository $repo does not exist or has no releases"
return 1
fi
echo "[DEBUG] Successfully fetched release info for $repo"
# Extract version for logging
local version=$(echo "$release_json" | grep '"tag_name"' | cut -d '"' -f 4)
echo " Version: $version"
# Get download URL
local download_url=$(get_download_url "$release_json" "$download_pattern")
if [ -z "$download_url" ]; then
echo " Error: No matching release found for pattern: $download_pattern" >&2
return 1
fi
echo " Downloading: $(basename "$download_url")"
local filename=$(basename "$download_url")
local download_path="$GITHUB_DIR/$filename"
# Download if not cached
if [ ! -f "$download_path" ]; then
download_with_retry "$download_url" "$download_path"
else
echo " Using cached file"
fi
# Create install directory
mkdir -p "$INITRAMFS_ROOT$install_path"
# Extract and install based on file type
case "$filename" in
*.tar.gz|*.tgz)
echo " Extracting tar.gz..."
tar -xzf "$download_path" -C "$GITHUB_DIR"
# Find the binary in extracted files
local extracted_binary=$(find "$GITHUB_DIR" -name "$binary_name" -type f -executable | head -1)
if [ -n "$extracted_binary" ]; then
cp "$extracted_binary" "$INITRAMFS_ROOT$install_path/$binary_name"
else
echo " Error: Binary '$binary_name' not found in archive" >&2
return 1
fi
;;
*.zip)
echo " Extracting zip..."
unzip -q "$download_path" -d "$GITHUB_DIR"
local extracted_binary=$(find "$GITHUB_DIR" -name "$binary_name" -type f -executable | head -1)
if [ -n "$extracted_binary" ]; then
cp "$extracted_binary" "$INITRAMFS_ROOT$install_path/$binary_name"
else
echo " Error: Binary '$binary_name' not found in archive" >&2
return 1
fi
;;
*)
# Assume it's a direct binary
echo " Installing direct binary..."
cp "$download_path" "$INITRAMFS_ROOT$install_path/$binary_name"
;;
esac
# Make executable
chmod +x "$INITRAMFS_ROOT$install_path/$binary_name"
# Verify installation
if [ -x "$INITRAMFS_ROOT$install_path/$binary_name" ]; then
echo " Success: $install_path/$binary_name installed"
else
echo " Error: Failed to install $binary_name" >&2
return 1
fi
}
# Install each component
echo ""
# Zinit - Init system
install_github_binary "threefoldtech/zinit" "zinit" "/sbin" "linux-x86_64"
# Core-X - Container control (skip if repo doesn't exist)
echo " Checking: threefoldtech/core-x"
if install_github_binary "threefoldtech/core-x" "core-x" "/usr/bin" "linux.*amd64"; then
echo " Core-X installed successfully"
else
echo " Warning: Core-X repository not found or no releases available - continuing without it"
fi
# Seektime - Disk detection
install_github_binary "threefoldtech/seektime" "seektime" "/usr/bin" "linux-amd64"
# RFS - Rust filesystem (direct binary, no architecture in name)
install_github_binary "threefoldtech/rfs" "rfs" "/usr/bin" "rfs"
echo ""
echo "[+] GitHub components installed successfully"
# Show installed binaries info
echo ""
echo "[+] Installed components:"
for binary in "/sbin/zinit" "/usr/bin/core-x" "/usr/bin/seektime" "/usr/bin/rfs"; do
if [ -x "$INITRAMFS_ROOT$binary" ]; then
size=$(stat -c%s "$INITRAMFS_ROOT$binary" 2>/dev/null || echo "unknown")
echo " $binary (${size} bytes)"
else
echo " $binary (MISSING)"
fi
done