diff --git a/testbox/scripts/auto-pull-restart.sh b/testbox/scripts/auto-pull-restart.sh index dec845d..0d2ba29 100755 --- a/testbox/scripts/auto-pull-restart.sh +++ b/testbox/scripts/auto-pull-restart.sh @@ -21,6 +21,57 @@ compose() { docker compose --env-file .env -f docker-compose.infra.yml -f docker-compose.apps.yml "$@" } +deployment_config_hash() { + { + sha256sum .env docker-compose.infra.yml docker-compose.apps.yml + compose config + } | sha256sum | awk '{print $1}' +} + +ensure_config_unchanged() { + local expected="$1" + local phase="$2" + local actual + + actual="$(deployment_config_hash)" + if [ "$actual" != "$expected" ]; then + log "deploy config changed during $phase expected=$expected actual=$actual" + return 1 + fi +} + +image_ref_for_service() { + case "$1" in + chatapp-cron) echo "chatapp-test/chatapp-cron:testbox" ;; + *) echo "chatapp-test/$1:testbox" ;; + esac +} + +service_image_id() { + docker image inspect -f '{{.Id}}' "$(image_ref_for_service "$1")" +} + +verify_running_service_image() { + local service="$1" + local expected_image="$2" + local container_id + local actual_image + + container_id="$(compose ps -q "$service")" + if [ -z "$container_id" ]; then + log "service container missing after restart service=$service" + return 1 + fi + + actual_image="$(docker inspect -f '{{.Image}}' "$container_id")" + if [ "$actual_image" != "$expected_image" ]; then + log "service image mismatch service=$service expected=$expected_image actual=$actual_image" + return 1 + fi + + log "service image verified service=$service image=$actual_image" +} + repo_changed() { local dir="$1" local url="$2" @@ -170,7 +221,10 @@ build_and_restart_java() { local services=("$@") local modules="" local compose_services="" + local config_hash + local image_manifest local service + local image_id [ "${#services[@]}" -gt 0 ] || return 0 @@ -179,6 +233,7 @@ build_and_restart_java() { compose_services="$compose_services $service" done + config_hash="$(deployment_config_hash)" log "java build services=${services[*]} modules=$modules" cd "$java_dir" if [ -x ./ci/install-private-maven.sh ]; then @@ -191,25 +246,56 @@ build_and_restart_java() { python3 scripts/import-nacos-configs.py >>"$LOG_FILE" 2>&1 TESTBOX_APPLY_JAVA_SQL=1 scripts/apply-mysql-baseline.sh >>"$LOG_FILE" 2>&1 compose build "${services[@]}" >>"$LOG_FILE" 2>&1 + ensure_config_unchanged "$config_hash" "java image build" + image_manifest="$ROOT_DIR/run/deploy-images-java-$$.txt" + : >"$image_manifest" + for service in "${services[@]}"; do + image_id="$(service_image_id "$service")" + printf '%s %s\n' "$service" "$image_id" >>"$image_manifest" + log "java image built service=$service image=$image_id" + done for service in "${services[@]}"; do log "java restart service=$service" compose up -d --no-deps --force-recreate "$service" >>"$LOG_FILE" 2>&1 done + ensure_config_unchanged "$config_hash" "java service restart" + while read -r service image_id; do + verify_running_service_image "$service" "$image_id" + done <"$image_manifest" + rm -f "$image_manifest" compose ps "${services[@]}" | tee -a "$LOG_FILE" } build_and_restart_golang() { + local config_hash + local image_id + + config_hash="$(deployment_config_hash)" log "golang build/restart" scripts/apply-mysql-baseline.sh >>"$LOG_FILE" 2>&1 compose build golang >>"$LOG_FILE" 2>&1 + ensure_config_unchanged "$config_hash" "golang image build" + image_id="$(service_image_id golang)" + log "golang image built image=$image_id" compose up -d --no-deps --force-recreate golang >>"$LOG_FILE" 2>&1 + ensure_config_unchanged "$config_hash" "golang service restart" + verify_running_service_image golang "$image_id" compose ps golang | tee -a "$LOG_FILE" } build_and_restart_cron() { + local config_hash + local image_id + + config_hash="$(deployment_config_hash)" log "cron build/restart" compose build chatapp-cron >>"$LOG_FILE" 2>&1 + ensure_config_unchanged "$config_hash" "cron image build" + image_id="$(service_image_id chatapp-cron)" + log "cron image built image=$image_id" compose up -d --no-deps --force-recreate chatapp-cron >>"$LOG_FILE" 2>&1 + ensure_config_unchanged "$config_hash" "cron service restart" + verify_running_service_image chatapp-cron "$image_id" compose ps chatapp-cron | tee -a "$LOG_FILE" } @@ -217,7 +303,10 @@ build_and_restart_admin() { local admin_dir="$1" local admin_api_base_url local admin_oss_url + local config_hash + local image_id + config_hash="$(deployment_config_hash)" admin_api_base_url="$(env_value TESTBOX_ADMIN_API_BASE_URL "https://yumi-test-admin.haiyihy.com/console")" admin_oss_url="$(env_value TESTBOX_ADMIN_OSS_URL "")" @@ -228,7 +317,12 @@ build_and_restart_admin() { --build-arg "ADMIN_OSS_URL=$admin_oss_url" \ -t chatapp-test/admin:testbox \ "$admin_dir" >>"$LOG_FILE" 2>&1 + ensure_config_unchanged "$config_hash" "admin image build" + image_id="$(service_image_id admin)" + log "admin image built image=$image_id" compose up -d --no-deps --force-recreate admin >>"$LOG_FILE" 2>&1 + ensure_config_unchanged "$config_hash" "admin service restart" + verify_running_service_image admin "$image_id" compose ps admin | tee -a "$LOG_FILE" }