| @@ -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 | |||