alpine/mirror_alpine.sh
2025-12-11 21:26:37 +00:00

85 lines
2.6 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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}/"