Files
Genarrative/scripts/prepare-server-provision-tools.sh

264 lines
10 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
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
PROVISION_TOOLS_DIR="${PROVISION_TOOLS_DIR:-provision-tools}"
PROVISION_DOWNLOADS_DIR="${PROVISION_DOWNLOADS_DIR:-}"
OTELCOL_VERSION="${OTELCOL_VERSION:-0.151.0}"
PREPARE_OTELCOL="${PREPARE_OTELCOL:-${ENABLE_OTELCOL:-true}}"
OTELCOL_DOWNLOAD_ROOT="${OTELCOL_DOWNLOAD_ROOT:-https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download}"
OTELCOL_ARCHIVE_PATH="${OTELCOL_ARCHIVE_PATH:-}"
SPACETIME_INSTALLER_URL="${SPACETIME_INSTALLER_URL:-https://install.spacetimedb.com}"
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/latest/download}"
SPACETIME_TARGET_HOST="${SPACETIME_TARGET_HOST:-x86_64-unknown-linux-gnu}"
SPACETIME_ARCHIVE_PATH="${SPACETIME_ARCHIVE_PATH:-}"
SPACETIME_INSTALLER_PATH="${SPACETIME_INSTALLER_PATH:-}"
SPACETIME_UPDATE_INSTALLER_PATH="${SPACETIME_UPDATE_INSTALLER_PATH:-}"
PROVISION_DOWNLOAD_PROXY="${PROVISION_DOWNLOAD_PROXY:-}"
PROVISION_NO_PROXY="${PROVISION_NO_PROXY:-127.0.0.1,localhost}"
PROVISION_REQUIRE_LOCAL_DOWNLOADS="${PROVISION_REQUIRE_LOCAL_DOWNLOADS:-false}"
PROVISION_TOOLS_TMP_PARENT="${PROVISION_TOOLS_TMP_PARENT:-${WORKSPACE:-$(pwd)}/.tmp/server-provision-tools}"
TMP_DIR_TO_CLEAN=""
OTELCOL_SOURCE_DESCRIPTION="skipped"
SPACETIME_SOURCE_DESCRIPTION="unset"
cleanup_tmp_dir() {
if [[ -n "${TMP_DIR_TO_CLEAN}" ]]; then
rm -rf "${TMP_DIR_TO_CLEAN}"
fi
}
require_cmd() {
local name="$1"
if ! command -v "${name}" >/dev/null 2>&1; then
echo "[prepare-provision-tools] 缺少命令: ${name}" >&2
exit 1
fi
}
configure_download_proxy() {
if [[ -z "${PROVISION_DOWNLOAD_PROXY}" ]]; then
return
fi
export HTTP_PROXY="${PROVISION_DOWNLOAD_PROXY}"
export HTTPS_PROXY="${PROVISION_DOWNLOAD_PROXY}"
export ALL_PROXY="${PROVISION_DOWNLOAD_PROXY}"
export http_proxy="${PROVISION_DOWNLOAD_PROXY}"
export https_proxy="${PROVISION_DOWNLOAD_PROXY}"
export all_proxy="${PROVISION_DOWNLOAD_PROXY}"
export NO_PROXY="${PROVISION_NO_PROXY}"
export no_proxy="${PROVISION_NO_PROXY}"
echo "[prepare-provision-tools] 已配置下载代理: ${PROVISION_DOWNLOAD_PROXY%%://*}://***"
}
download_file() {
local url="$1"
local output="$2"
if command -v curl >/dev/null 2>&1; then
curl -fsSL --retry 3 --retry-delay 2 "${url}" -o "${output}"
elif command -v wget >/dev/null 2>&1; then
wget -O "${output}" "${url}"
else
echo "[prepare-provision-tools] 需要 curl 或 wget 下载: ${url}" >&2
exit 1
fi
}
validate_relative_dir() {
local label="$1"
local path="$2"
if [[ -z "${path}" ]]; then
return
fi
if [[ "${path}" == /* || "${path}" == *..* || "${path}" == "." ]]; then
echo "[prepare-provision-tools] ${label} 只能是工作区内的相对路径: ${path}" >&2
exit 1
fi
}
make_spacetime_wrapper() {
local target="$1"
cat >"${target}" <<'EOF'
#!/usr/bin/env sh
set -eu
SELF_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
exec "$SELF_DIR/bin/current/spacetimedb-cli" "$@"
EOF
chmod 0755 "${target}"
}
prepare_otelcol() {
local tmp_dir="$1"
local archive="${tmp_dir}/otelcol-contrib.tar.gz"
local extract_dir="${tmp_dir}/otelcol-contrib"
local url="${OTELCOL_DOWNLOAD_ROOT}/v${OTELCOL_VERSION}/otelcol-contrib_${OTELCOL_VERSION}_linux_amd64.tar.gz"
local downloaded_archive="${PROVISION_DOWNLOADS_DIR}/otelcol-contrib_${OTELCOL_VERSION}_linux_amd64.tar.gz"
local source_archive=""
local target="${PROVISION_TOOLS_DIR}/otelcol-contrib"
require_cmd tar
if [[ -n "${OTELCOL_ARCHIVE_PATH}" && -f "${OTELCOL_ARCHIVE_PATH}" ]]; then
source_archive="${OTELCOL_ARCHIVE_PATH}"
elif [[ -n "${PROVISION_DOWNLOADS_DIR}" && -f "${downloaded_archive}" ]]; then
source_archive="${downloaded_archive}"
fi
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_archive}" ]]; then
echo "[prepare-provision-tools] 要求使用 Windows 已下载的 otelcol-contrib 包,但未找到: ${downloaded_archive}" >&2
exit 1
fi
mkdir -p "${extract_dir}"
if [[ -n "${source_archive}" ]]; then
echo "[prepare-provision-tools] 使用已下载的 otelcol-contrib 包: ${source_archive}"
cp "${source_archive}" "${archive}"
OTELCOL_SOURCE_DESCRIPTION="local ${source_archive}"
else
echo "[prepare-provision-tools] 下载 otelcol-contrib: ${url}"
download_file "${url}" "${archive}"
OTELCOL_SOURCE_DESCRIPTION="download ${url}"
fi
tar -xzf "${archive}" -C "${extract_dir}"
if [[ ! -x "${extract_dir}/otelcol-contrib" ]]; then
echo "[prepare-provision-tools] otelcol-contrib 包中缺少可执行文件。" >&2
exit 1
fi
install -m 0755 "${extract_dir}/otelcol-contrib" "${target}"
"${target}" --version >/dev/null
}
prepare_spacetime() {
local tmp_dir="$1"
local install_root="${tmp_dir}/spacetime-root"
local target_dir="${PROVISION_TOOLS_DIR}/spacetime"
local archive_name="spacetime-${SPACETIME_TARGET_HOST}.tar.gz"
local downloaded_archive="${PROVISION_DOWNLOADS_DIR}/${archive_name}"
local source_archive=""
local update_name="spacetimedb-update-${SPACETIME_TARGET_HOST}"
local downloaded_update="${PROVISION_DOWNLOADS_DIR}/${update_name}"
local source_update=""
local prepared_update="${tmp_dir}/spacetimedb-update"
local downloaded_installer="${PROVISION_DOWNLOADS_DIR}/spacetime-install.sh"
local source_installer=""
mkdir -p "${install_root}"
if [[ -n "${SPACETIME_ARCHIVE_PATH}" && -f "${SPACETIME_ARCHIVE_PATH}" ]]; then
source_archive="${SPACETIME_ARCHIVE_PATH}"
elif [[ -n "${PROVISION_DOWNLOADS_DIR}" && -f "${downloaded_archive}" ]]; then
source_archive="${downloaded_archive}"
fi
if [[ -n "${source_archive}" ]]; then
echo "[prepare-provision-tools] 使用已下载的 SpacetimeDB release tarball: ${source_archive}"
mkdir -p "${install_root}/bin/current"
tar -xzf "${source_archive}" -C "${install_root}/bin/current"
chmod 0755 "${install_root}/bin/current/spacetimedb-cli" "${install_root}/bin/current/spacetimedb-standalone"
SPACETIME_SOURCE_DESCRIPTION="local archive ${source_archive}"
elif [[ -n "${SPACETIME_UPDATE_INSTALLER_PATH}" && -f "${SPACETIME_UPDATE_INSTALLER_PATH}" ]]; then
source_update="${SPACETIME_UPDATE_INSTALLER_PATH}"
elif [[ -n "${PROVISION_DOWNLOADS_DIR}" && -f "${downloaded_update}" ]]; then
source_update="${downloaded_update}"
fi
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_archive}" ]]; then
echo "[prepare-provision-tools] 要求使用 Windows 已下载的 SpacetimeDB release tarball但未找到: ${downloaded_archive}" >&2
exit 1
fi
if [[ -n "${source_archive}" ]]; then
:
elif [[ -n "${source_update}" ]]; then
echo "[prepare-provision-tools] 使用已下载的 SpacetimeDB Linux update installer: ${source_update}"
cp "${source_update}" "${prepared_update}"
chmod 0755 "${prepared_update}"
TMPDIR="${tmp_dir}" "${prepared_update}" --root-dir "${install_root}" -y
SPACETIME_SOURCE_DESCRIPTION="local update ${source_update}"
else
if [[ -n "${SPACETIME_INSTALLER_PATH}" && -f "${SPACETIME_INSTALLER_PATH}" ]]; then
source_installer="${SPACETIME_INSTALLER_PATH}"
elif [[ -n "${PROVISION_DOWNLOADS_DIR}" && -f "${downloaded_installer}" ]]; then
source_installer="${downloaded_installer}"
fi
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_installer}" ]]; then
echo "[prepare-provision-tools] 要求使用 Windows 已下载的 SpacetimeDB 官方安装器脚本,但未找到: ${downloaded_installer}" >&2
exit 1
elif [[ -n "${source_installer}" ]]; then
echo "[prepare-provision-tools] 使用已下载的 SpacetimeDB 官方安装器脚本: ${source_installer}"
cp "${source_installer}" "${tmp_dir}/spacetime-install.sh"
else
echo "[prepare-provision-tools] 下载 SpacetimeDB 官方安装器脚本: ${SPACETIME_INSTALLER_URL}"
download_file "${SPACETIME_INSTALLER_URL}" "${tmp_dir}/spacetime-install.sh"
fi
chmod 0755 "${tmp_dir}/spacetime-install.sh"
TMPDIR="${tmp_dir}" SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT}" sh "${tmp_dir}/spacetime-install.sh" --root-dir "${install_root}" -y
SPACETIME_SOURCE_DESCRIPTION="installer ${SPACETIME_INSTALLER_URL}; download root ${SPACETIME_DOWNLOAD_ROOT}"
fi
if [[ ! -x "${install_root}/bin/current/spacetimedb-cli" ]]; then
echo "[prepare-provision-tools] SpacetimeDB 安装结果缺少 bin/current/spacetimedb-cli。" >&2
exit 1
fi
if [[ ! -x "${install_root}/bin/current/spacetimedb-standalone" ]]; then
echo "[prepare-provision-tools] SpacetimeDB 安装结果缺少 bin/current/spacetimedb-standalone。" >&2
exit 1
fi
mkdir -p "${target_dir}"
cp -a "${install_root}/bin" "${target_dir}/bin"
make_spacetime_wrapper "${target_dir}/spacetime"
"${target_dir}/spacetime" --version >/dev/null
}
main() {
local tmp_dir
require_cmd chmod
require_cmd cp
require_cmd install
require_cmd mktemp
require_cmd rm
require_cmd tar
validate_relative_dir "PROVISION_TOOLS_DIR" "${PROVISION_TOOLS_DIR}"
validate_relative_dir "PROVISION_DOWNLOADS_DIR" "${PROVISION_DOWNLOADS_DIR}"
if [[ -n "${PROVISION_DOWNLOADS_DIR}" && "${PROVISION_DOWNLOADS_DIR%/}" == "${PROVISION_TOOLS_DIR%/}" ]]; then
echo "[prepare-provision-tools] PROVISION_DOWNLOADS_DIR 不能等于 PROVISION_TOOLS_DIR否则会被清理: ${PROVISION_DOWNLOADS_DIR}" >&2
exit 1
fi
configure_download_proxy
mkdir -p "${PROVISION_TOOLS_TMP_PARENT}"
tmp_dir="$(mktemp -d "${PROVISION_TOOLS_TMP_PARENT%/}/run.XXXXXX")"
TMP_DIR_TO_CLEAN="${tmp_dir}"
trap cleanup_tmp_dir EXIT
rm -rf "${PROVISION_TOOLS_DIR}"
mkdir -p "${PROVISION_TOOLS_DIR}"
if [[ "${PREPARE_OTELCOL}" == "true" ]]; then
prepare_otelcol "${tmp_dir}"
else
echo "[prepare-provision-tools] PREPARE_OTELCOL=${PREPARE_OTELCOL},跳过 otelcol-contrib 工具包准备。"
fi
prepare_spacetime "${tmp_dir}"
cat >"${PROVISION_TOOLS_DIR}/MANIFEST.txt" <<EOF
otelcol-contrib ${OTELCOL_VERSION} ${OTELCOL_SOURCE_DESCRIPTION}
spacetime ${SPACETIME_SOURCE_DESCRIPTION}
spacetime target host ${SPACETIME_TARGET_HOST}
require local downloads ${PROVISION_REQUIRE_LOCAL_DOWNLOADS}
EOF
echo "[prepare-provision-tools] 工具包已准备: ${PROVISION_TOOLS_DIR}"
find "${PROVISION_TOOLS_DIR}" -maxdepth 5 \( -type f -o -type l \) | sort
}
main "$@"