| @@ -0,0 +1,162 @@ | |||||
| #!/usr/bin/env bash | |||||
| set -Eeuo pipefail | |||||
| # Package the Kafka middleware image, upload it to Tencent COS, and print | |||||
| # commands for loading it on the target server. | |||||
| # | |||||
| # Required when COSCLI is not preconfigured: | |||||
| # COS_SECRET_ID, COS_SECRET_KEY, COS_REGION, COS_BUCKET | |||||
| # | |||||
| # Optional: | |||||
| # KAFKA_IMAGE=bitnami/kafka:3.7.0 | |||||
| # DEPLOY_ENV=emp-test | |||||
| # DIST_DIR=deploy/isolated/dist | |||||
| # COS_PREFIX=deploy/emp-test/middleware/kafka | |||||
| # COS_SIGN_EXPIRE=604800 | |||||
| # COS_CONFIG_PATH=/path/to/.cos.yaml | |||||
| # COSCLI_BIN=coscli | |||||
| # SKIP_PULL=1 | |||||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |||||
| DIST_DIR="${DIST_DIR:-$SCRIPT_DIR/dist}" | |||||
| KAFKA_IMAGE="${KAFKA_IMAGE:-bitnami/kafka:3.7.0}" | |||||
| DEPLOY_ENV="${DEPLOY_ENV:-emp-test}" | |||||
| COSCLI_BIN="${COSCLI_BIN:-coscli}" | |||||
| COS_SIGN_EXPIRE="${COS_SIGN_EXPIRE:-604800}" | |||||
| TARGET_BASE_DIR="${TARGET_BASE_DIR:-/home/admin-x99/emp}" | |||||
| RUN_ID="$(date '+%Y%m%d%H%M%S')" | |||||
| SAFE_IMAGE_NAME="$(echo "$KAFKA_IMAGE" | tr '/:' '--')" | |||||
| PACKAGE_NAME="${PACKAGE_NAME:-${DEPLOY_ENV}-${SAFE_IMAGE_NAME}-${RUN_ID}}" | |||||
| PACKAGE_DIR="$DIST_DIR/$PACKAGE_NAME" | |||||
| PACKAGE_ARCHIVE="$DIST_DIR/${PACKAGE_NAME}.tar.gz" | |||||
| 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 | |||||
| } | |||||
| build_coscli_opts() { | |||||
| COSCLI_OPTS=() | |||||
| if [[ -n "${COS_CONFIG_PATH:-}" ]]; then | |||||
| COSCLI_OPTS+=("-c" "$COS_CONFIG_PATH") | |||||
| return | |||||
| fi | |||||
| [[ -n "${COS_SECRET_ID:-}" ]] || die "Missing COS_SECRET_ID or COS_CONFIG_PATH" | |||||
| [[ -n "${COS_SECRET_KEY:-}" ]] || die "Missing COS_SECRET_KEY or COS_CONFIG_PATH" | |||||
| [[ -n "${COS_REGION:-}" ]] || die "Missing COS_REGION" | |||||
| COSCLI_OPTS+=( | |||||
| "--init-skip=true" | |||||
| "-i" "$COS_SECRET_ID" | |||||
| "-k" "$COS_SECRET_KEY" | |||||
| "-e" "cos.$COS_REGION.myqcloud.com" | |||||
| ) | |||||
| if [[ -n "${COS_TOKEN:-}" ]]; then | |||||
| COSCLI_OPTS+=("--token" "$COS_TOKEN") | |||||
| fi | |||||
| } | |||||
| write_load_script() { | |||||
| cat > "$PACKAGE_DIR/load-kafka-image.sh" <<EOF | |||||
| #!/usr/bin/env bash | |||||
| set -Eeuo pipefail | |||||
| SCRIPT_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)" | |||||
| echo "[load] docker load: \$SCRIPT_DIR/images.tar" | |||||
| docker load -i "\$SCRIPT_DIR/images.tar" | |||||
| echo "[load] done: $KAFKA_IMAGE" | |||||
| EOF | |||||
| chmod +x "$PACKAGE_DIR/load-kafka-image.sh" | |||||
| } | |||||
| print_target_commands() { | |||||
| local target_runtime="$TARGET_BASE_DIR/$DEPLOY_ENV/runtime" | |||||
| cat <<EOF | |||||
| Target commands: | |||||
| mkdir -p /tmp/emp-kafka-image && \\ | |||||
| curl -fL '$SIGNED_URL' -o /tmp/emp-kafka-image/package.tar.gz && \\ | |||||
| tar -xzf /tmp/emp-kafka-image/package.tar.gz -C /tmp/emp-kafka-image --strip-components=1 && \\ | |||||
| bash /tmp/emp-kafka-image/load-kafka-image.sh | |||||
| Then start Kafka and data: | |||||
| cd "$target_runtime" && docker compose --profile local-kafka up -d kafka kafka-init | |||||
| docker restart $DEPLOY_ENV-emp-data-1 | |||||
| Verify: | |||||
| docker ps -a | grep -E 'kafka|$DEPLOY_ENV-emp-data' | |||||
| EOF | |||||
| } | |||||
| need_cmd docker | |||||
| need_cmd tar | |||||
| need_cmd "$COSCLI_BIN" | |||||
| [[ -n "${COS_BUCKET:-}" ]] || die "Missing COS_BUCKET" | |||||
| build_coscli_opts | |||||
| mkdir -p "$DIST_DIR" | |||||
| rm -rf "$PACKAGE_DIR" | |||||
| mkdir -p "$PACKAGE_DIR" | |||||
| if [[ "${SKIP_PULL:-0}" != "1" ]]; then | |||||
| log "Pull Kafka image: $KAFKA_IMAGE" | |||||
| docker pull "$KAFKA_IMAGE" | |||||
| else | |||||
| log "Skip pull, use local image: $KAFKA_IMAGE" | |||||
| fi | |||||
| log "Save Kafka image" | |||||
| docker save -o "$PACKAGE_DIR/images.tar" "$KAFKA_IMAGE" | |||||
| write_load_script | |||||
| log "Archive package: $PACKAGE_ARCHIVE" | |||||
| rm -f "$PACKAGE_ARCHIVE" | |||||
| tar -czf "$PACKAGE_ARCHIVE" -C "$DIST_DIR" "$PACKAGE_NAME" | |||||
| SHA256="$(calc_sha256 "$PACKAGE_ARCHIVE")" | |||||
| COS_PREFIX="${COS_PREFIX:-deploy/$DEPLOY_ENV/middleware/kafka/$RUN_ID}" | |||||
| COS_PREFIX="${COS_PREFIX#/}" | |||||
| COS_PREFIX="${COS_PREFIX%/}" | |||||
| COS_KEY="${COS_KEY:-$COS_PREFIX/$(basename "$PACKAGE_ARCHIVE")}" | |||||
| COS_KEY="${COS_KEY#/}" | |||||
| COS_URI="cos://$COS_BUCKET/$COS_KEY" | |||||
| log "Upload package: $PACKAGE_ARCHIVE" | |||||
| log "COS object: $COS_URI" | |||||
| "$COSCLI_BIN" cp "$PACKAGE_ARCHIVE" "$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 <<EOF | |||||
| Package: $PACKAGE_ARCHIVE | |||||
| Image: $KAFKA_IMAGE | |||||
| COS Key: $COS_KEY | |||||
| SHA256: $SHA256 | |||||
| URL: $SIGNED_URL | |||||
| EOF | |||||
| print_target_commands | |||||