deerflow-code/offline-backend-20260512/prepare_wheelhouse.sh
2026-09-07 18:24:55 +08:00

104 lines
3.1 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PYTHON_BIN="${PYTHON_BIN:-python3}"
REQUIREMENTS_FILE="${REQUIREMENTS_FILE:-${SCRIPT_DIR}/offline-runtime-requirements.txt}"
WHEELHOUSE_DIR="${WHEELHOUSE_DIR:-${SCRIPT_DIR}/wheelhouse}"
PIP_INDEX_URL="${PIP_INDEX_URL:-https://pypi.org/simple}"
# The supplied backend image is CPython 3.12 on Debian x86_64. These values can
# be overridden when building an offline bundle for a different image/CPU.
TARGET_PLATFORM="${TARGET_PLATFORM:-manylinux2014_x86_64}"
TARGET_PYTHON_VERSION="${TARGET_PYTHON_VERSION:-312}"
TARGET_IMPLEMENTATION="${TARGET_IMPLEMENTATION:-cp}"
TARGET_ABI="${TARGET_ABI:-cp312}"
die() {
echo "ERROR: $*" >&2
exit 1
}
require_cmd() {
command -v "$1" >/dev/null 2>&1 || die "command not found: $1"
}
require_wheel() {
local pattern="$1"
compgen -G "${WHEELHOUSE_DIR}/${pattern}" >/dev/null || die "wheel not downloaded: ${pattern}"
}
require_cmd "${PYTHON_BIN}"
require_cmd sha256sum
[ -f "${REQUIREMENTS_FILE}" ] || die "requirements file not found: ${REQUIREMENTS_FILE}"
"${PYTHON_BIN}" -m pip --version >/dev/null 2>&1 || die "pip is not available for ${PYTHON_BIN}"
mkdir -p "${WHEELHOUSE_DIR}"
download_args=(
download
--dest "${WHEELHOUSE_DIR}"
--only-binary=:all:
--platform "${TARGET_PLATFORM}"
--python-version "${TARGET_PYTHON_VERSION}"
--implementation "${TARGET_IMPLEMENTATION}"
--abi "${TARGET_ABI}"
)
echo "Downloading Linux/Python runtime wheels"
echo " requirements: ${REQUIREMENTS_FILE}"
echo " destination: ${WHEELHOUSE_DIR}"
echo " platform: ${TARGET_PLATFORM}"
echo " Python/ABI: ${TARGET_PYTHON_VERSION}/${TARGET_ABI}"
"${PYTHON_BIN}" -m pip "${download_args[@]}" \
--index-url "${PIP_INDEX_URL}" \
--requirement "${REQUIREMENTS_FILE}"
require_wheel 'croniter-6.2.2-*.whl'
require_wheel 'hindsight_client-0.6.2-*.whl'
require_wheel 'redis-5.2.1-*.whl'
require_wheel 'aiomysql-0.3.2-*.whl'
require_wheel 'pymysql-1.2.0-*.whl'
require_wheel 'sqlalchemy-2.0.51-*.whl'
require_wheel 'greenlet-3.2.5-*.whl'
# Resolve the same requirements a second time using only wheelhouse. This
# catches a missing transitive dependency before the bundle reaches offline.
verify_dir="$(mktemp -d)"
cleanup() {
if [ -n "${verify_dir:-}" ] && [ -d "${verify_dir}" ]; then
rm -rf -- "${verify_dir}"
fi
}
trap cleanup EXIT
verify_args=(
download
--dest "${verify_dir}"
--no-index
--find-links "${WHEELHOUSE_DIR}"
--only-binary=:all:
--platform "${TARGET_PLATFORM}"
--python-version "${TARGET_PYTHON_VERSION}"
--implementation "${TARGET_IMPLEMENTATION}"
--abi "${TARGET_ABI}"
--requirement "${REQUIREMENTS_FILE}"
)
"${PYTHON_BIN}" -m pip "${verify_args[@]}" >/dev/null
shopt -s nullglob
wheels=("${WHEELHOUSE_DIR}"/*.whl)
[ "${#wheels[@]}" -gt 0 ] || die "wheelhouse is empty: ${WHEELHOUSE_DIR}"
(
cd "${WHEELHOUSE_DIR}"
sha256sum -- *.whl | LC_ALL=C sort > SHA256SUMS
)
echo
echo "Wheelhouse is complete for the pinned runtime requirements."
echo " wheel count: ${#wheels[@]}"
echo " checksums: ${WHEELHOUSE_DIR}/SHA256SUMS"
echo "Copy the wheelhouse directory with the deployment bundle."