85 lines
2.6 KiB
Bash
Executable File
85 lines
2.6 KiB
Bash
Executable File
#!/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}/"
|