#!/usr/bin/env bash set -Eeuo pipefail # Upload a runtime/update package to Tencent COS and print a deployable URL. # Required when COSCLI is not preconfigured: # COS_SECRET_ID, COS_SECRET_KEY, COS_REGION, COS_BUCKET # # Optional: # DEPLOY_ENV=emp-uat # PACKAGE_KIND=runtime|update|bootstrap # COS_PREFIX=deploy/emp-uat/update/20260611120000 # COS_KEY=deploy/emp-uat/update/package.tar.gz # COS_SIGN_EXPIRE=604800 # COS_CONFIG_PATH=/path/to/.cos.yaml # TARGET_BASE_DIR=/home/admin-x99/emp SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Keep COS credentials outside the repository. A local .cos.env file is ignored # by Git and lets operators keep using the short build command. COS_ENV_FILE="${COS_ENV_FILE:-$SCRIPT_DIR/.cos.env}" if [[ -f "$COS_ENV_FILE" ]]; then set -a # shellcheck disable=SC1090 . "$COS_ENV_FILE" set +a fi DEPLOY_ENV="${DEPLOY_ENV:-emp-test}" PACKAGE_KIND="${PACKAGE_KIND:-}" COSCLI_BIN="${COSCLI_BIN:-coscli}" COS_SIGN_EXPIRE="${COS_SIGN_EXPIRE:-604800}" TARGET_BASE_DIR="${TARGET_BASE_DIR:-/home/admin-x99/emp}" COS_SECRET_ID="${COS_SECRET_ID:-}" COS_SECRET_KEY="${COS_SECRET_KEY:-}" COS_REGION="${COS_REGION:-ap-chengdu}" COS_BUCKET="${COS_BUCKET:-emp-1258090764}" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" } die() { echo "ERROR: $*" >&2 exit 1 } need_cmd() { command -v "$1" >/dev/null 2>&1 || die "Missing command: $1" } calc_sha256() { local file="$1" if command -v sha256sum >/dev/null 2>&1; then sha256sum "$file" | awk '{print $1}' elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "$file" | awk '{print $1}' else echo "" fi } infer_package_kind() { local name="$1" if [[ -n "$PACKAGE_KIND" ]]; then echo "$PACKAGE_KIND" elif [[ "$name" == *"-update-"* ]]; then echo "update" else echo "runtime" fi } print_target_deploy_command() { local target_deploy_home target_script_dir if [[ "$DEPLOY_ENV" == "emp-shunfeng" ]]; then target_deploy_home="${TARGET_DEPLOY_HOME:-/home/emp-shunfeng}" else target_deploy_home="${TARGET_DEPLOY_HOME:-$TARGET_BASE_DIR/$DEPLOY_ENV}" fi if [[ "$PACKAGE_KIND" == "bootstrap" ]]; then cat </dev/null 2>&1; then curl -fL --retry 3 --connect-timeout 20 -o "\$BOOTSTRAP_FILE" "\$BOOTSTRAP_URL" elif command -v wget >/dev/null 2>&1; then wget -O "\$BOOTSTRAP_FILE" "\$BOOTSTRAP_URL" else echo "ERROR: missing curl or wget" >&2 exit 1 fi if command -v sha256sum >/dev/null 2>&1; then echo "\$BOOTSTRAP_SHA256 \$BOOTSTRAP_FILE" | sha256sum -c - elif command -v shasum >/dev/null 2>&1; then test "\$(shasum -a 256 "\$BOOTSTRAP_FILE" | awk '{print \$1}')" = "\$BOOTSTRAP_SHA256" else echo "ERROR: missing sha256sum or shasum" >&2 exit 1 fi tar -xzf "\$BOOTSTRAP_FILE" -C "\$BOOTSTRAP_DIR" --strip-components=1 OLD_EMP_DIR="\$(docker inspect emp-gateway --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}')" test -n "\$OLD_EMP_DIR" && test -f "\$OLD_EMP_DIR/.env" || { echo "ERROR: existing emp_server/.env not found" >&2 exit 1 } DEPLOY_HOME=$target_deploy_home \\ EXISTING_ENV_FILE="\$OLD_EMP_DIR/.env" \\ bash "\$BOOTSTRAP_DIR/install-runtime.sh" EOF return fi if [[ "$PACKAGE_KIND" == "update" ]]; then target_script_dir="${TARGET_SCRIPT_DIR:-$target_deploy_home/runtime}" else target_script_dir="${TARGET_SCRIPT_DIR:-$TARGET_BASE_DIR}" fi cat <" PACKAGE_FILE="$1" [[ -f "$PACKAGE_FILE" ]] || die "Package not found: $PACKAGE_FILE" [[ -n "${COS_BUCKET:-}" ]] || die "Missing COS_BUCKET" need_cmd "$COSCLI_BIN" build_coscli_opts PACKAGE_FILE="$(cd "$(dirname "$PACKAGE_FILE")" && pwd)/$(basename "$PACKAGE_FILE")" PACKAGE_BASE="$(basename "$PACKAGE_FILE")" PACKAGE_KIND="$(infer_package_kind "$PACKAGE_BASE")" RUN_ID="$(date '+%Y%m%d%H%M%S')" DEFAULT_PREFIX="deploy/$DEPLOY_ENV/$PACKAGE_KIND/$RUN_ID" COS_PREFIX="${COS_PREFIX:-$DEFAULT_PREFIX}" COS_PREFIX="${COS_PREFIX#/}" COS_PREFIX="${COS_PREFIX%/}" COS_KEY="${COS_KEY:-$COS_PREFIX/$PACKAGE_BASE}" COS_KEY="${COS_KEY#/}" COS_URI="cos://$COS_BUCKET/$COS_KEY" SHA256="$(calc_sha256 "$PACKAGE_FILE")" log "Upload package: $PACKAGE_FILE" log "COS object: $COS_URI" "$COSCLI_BIN" cp "$PACKAGE_FILE" "$COS_URI" "${COSCLI_OPTS[@]}" log "Generate signed URL, expire seconds: $COS_SIGN_EXPIRE" SIGNED_URL="$("$COSCLI_BIN" signurl "$COS_URI" --time "$COS_SIGN_EXPIRE" --simple-output "${COSCLI_OPTS[@]}")" cat <