#!/usr/bin/env bash set -euo pipefail ALPINE_VERSION="v3.23" PACKAGES=("bash" "curl" "jq" "git" "docker") REPOS=("main" "community") BASE_URL="https://dl-cdn.alpinelinux.org/alpine" DEST_DIR="." ARCHES=("x86_64" "aarch64" "armv7") # only mirror the arches you care about CURL_OPTS="-fSL --retry 3 --retry-delay 2 --connect-timeout 10" mkdir -p "$DEST_DIR" # Function to download a single package and its deps for a given arch download_pkg() { local pkg="$1" local arch="$2" local found=false for repo in "${REPOS[@]}"; do local index_url="${BASE_URL}/${ALPINE_VERSION}/${repo}/${arch}/APKINDEX.tar.gz" local tmpdir tmpdir=$(mktemp -d) trap "rm -rf $tmpdir" EXIT echo "📥 Fetching APKINDEX: $index_url" if ! curl $CURL_OPTS "$index_url" -o "$tmpdir/APKINDEX.tar.gz"; then echo "⚠️ Failed to fetch $index_url, skipping." continue fi tar -xzf "$tmpdir/APKINDEX.tar.gz" -C "$tmpdir" # Extract version for the package local version version=$(grep -A1 "^P:${pkg}$" "$tmpdir"/APKINDEX | grep "^V:" | cut -d':' -f2 | sed 's/^[ \t]*//;s/[ \t]*$//' || true) if [ -z "$version" ]; then continue fi local file="${pkg}-${version}.apk" local out_dir="${DEST_DIR}/${ALPINE_VERSION}/${arch}" mkdir -p "$out_dir" if [ ! -f "$out_dir/$file" ]; then echo "🔽 Downloading $file for arch $arch from $repo" curl $CURL_OPTS "${BASE_URL}/${ALPINE_VERSION}/${repo}/${arch}/${file}" -o "$out_dir/$file" else echo "ℹ️ $file already exists for arch $arch, skipping download." fi found=true # Handle dependencies local deps deps=$(grep -A10 "^P:${pkg}$" "$tmpdir"/APKINDEX | grep "^D:" | cut -d':' -f2- | sed 's/^[ \t]*//' || true) for dep in $deps; do # Strip version constraints (e.g., >1.0, =2.0) to get base dep name dep_name=$(echo "$dep" | sed 's/[><=].*//;s/so://') if [ -n "$dep_name" ] && [ "$dep_name" != "$pkg" ]; then download_pkg "$dep_name" "$arch" fi done break # Stop after finding in one repo done if ! $found; then echo "⚠️ Package not found: $pkg for arch $arch" fi } for arch in "${ARCHES[@]}"; do echo "==============================" echo "📦 Processing architecture: $arch" echo "==============================" for pkg in "${PACKAGES[@]}"; do download_pkg "$pkg" "$arch" done done echo echo "✅ Done! Packages saved under: ${DEST_DIR}/${ALPINE_VERSION}/"