fix: expand playground diagnostics and compose fallback
This commit is contained in:
174
planet.sh
174
planet.sh
@@ -59,6 +59,10 @@ DEFAULT_AI_PROVIDER_PORT="${DEFAULT_AI_PROVIDER_PORT:-8010}"
|
||||
FRONTEND_RUNTIME_BIN="${FRONTEND_RUNTIME_BIN:-}"
|
||||
FRONTEND_RUNTIME_SOURCE="${FRONTEND_RUNTIME_SOURCE:-}"
|
||||
FRONTEND_PID_FILE="/tmp/planet_frontend.pid"
|
||||
AI_PROVIDER_BUILD_STAMP_FILE="/tmp/planet_aiprovider_build.sha256"
|
||||
AI_PROVIDER_IMAGE_NAME="${AI_PROVIDER_IMAGE_NAME:-planet_aiprovider:latest}"
|
||||
AI_PROVIDER_CONTAINER_NAME="${AI_PROVIDER_CONTAINER_NAME:-planet_aiprovider}"
|
||||
AI_PROVIDER_RECREATE_REQUIRED=0
|
||||
|
||||
prepend_path_once() {
|
||||
local path_entry="$1"
|
||||
@@ -79,12 +83,55 @@ ensure_local_runtime_bins_on_path() {
|
||||
ensure_local_runtime_bins_on_path
|
||||
|
||||
# Shell / Docker helpers
|
||||
compose_v2_available() {
|
||||
docker compose version >/dev/null 2>&1
|
||||
}
|
||||
|
||||
compose_v1_available() {
|
||||
command -v docker-compose >/dev/null 2>&1
|
||||
}
|
||||
|
||||
report_missing_compose() {
|
||||
clear_wait_spinner
|
||||
log_error "未检测到可用的 Docker Compose"
|
||||
log_note "优先需要 Docker Compose v2 (`docker compose`)"
|
||||
log_note "如果当前机器仍只装有旧版 `docker-compose`,也请确认该命令可执行"
|
||||
log_note "推荐安装 Docker Compose v2 插件:"
|
||||
log_note ' mkdir -p ~/.docker/cli-plugins'
|
||||
log_note ' curl -SL https://github.com/docker/compose/releases/download/v2.40.3/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose'
|
||||
log_note ' chmod +x ~/.docker/cli-plugins/docker-compose'
|
||||
log_note ' docker compose version'
|
||||
return 1
|
||||
}
|
||||
|
||||
compose_up() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose "$@"
|
||||
else
|
||||
docker-compose "$@"
|
||||
local args=("$@")
|
||||
local arg_text="$*"
|
||||
|
||||
if compose_v2_available; then
|
||||
set_wait_detail "正在用 docker compose v2 执行: ${arg_text}"
|
||||
if docker compose "${args[@]}"; then
|
||||
return 0
|
||||
fi
|
||||
log_warn "docker compose v2 执行失败,回退到 docker-compose v1"
|
||||
fi
|
||||
|
||||
if compose_v1_available; then
|
||||
set_wait_detail "正在用 docker-compose v1 执行: ${arg_text}"
|
||||
if docker-compose "${args[@]}"; then
|
||||
return 0
|
||||
fi
|
||||
clear_wait_spinner
|
||||
log_error "docker compose v2 与 docker-compose v1 均执行失败"
|
||||
log_note "最后尝试的命令: docker-compose ${arg_text}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
report_missing_compose
|
||||
}
|
||||
|
||||
compose_supports_build() {
|
||||
compose_up build --help >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Terminal rendering helpers
|
||||
@@ -338,6 +385,102 @@ run_with_retry() {
|
||||
return 1
|
||||
}
|
||||
|
||||
compute_ai_provider_build_fingerprint() {
|
||||
(
|
||||
cd "$SCRIPT_DIR" || exit 1
|
||||
tar -cf - \
|
||||
aiprovider \
|
||||
pyproject.toml \
|
||||
uv.lock \
|
||||
docker-compose.yml \
|
||||
docker-compose.simple.yml 2>/dev/null
|
||||
) | sha256sum | awk '{print $1}'
|
||||
}
|
||||
|
||||
read_ai_provider_build_stamp() {
|
||||
[ -f "$AI_PROVIDER_BUILD_STAMP_FILE" ] || return 1
|
||||
tr -d '[:space:]' < "$AI_PROVIDER_BUILD_STAMP_FILE"
|
||||
}
|
||||
|
||||
write_ai_provider_build_stamp() {
|
||||
local fingerprint="$1"
|
||||
printf "%s\n" "$fingerprint" > "$AI_PROVIDER_BUILD_STAMP_FILE"
|
||||
}
|
||||
|
||||
ai_provider_image_exists() {
|
||||
docker image inspect "$AI_PROVIDER_IMAGE_NAME" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
list_ai_provider_containers() {
|
||||
docker ps -aq --filter "name=planet_aiprovider" 2>/dev/null || true
|
||||
}
|
||||
|
||||
remove_ai_provider_containers() {
|
||||
local container_ids
|
||||
container_ids="$(list_ai_provider_containers)"
|
||||
[ -n "$container_ids" ] || return 0
|
||||
echo "$container_ids" | xargs -r docker rm -f >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
run_ai_provider_container_manually() {
|
||||
local ai_provider_port="${1:-$DEFAULT_AI_PROVIDER_PORT}"
|
||||
local env_file_args=()
|
||||
|
||||
if [ -f "$SCRIPT_DIR/aiprovider/.env" ]; then
|
||||
env_file_args=(--env-file "$SCRIPT_DIR/aiprovider/.env")
|
||||
fi
|
||||
|
||||
docker run -d \
|
||||
--name "$AI_PROVIDER_CONTAINER_NAME" \
|
||||
"${env_file_args[@]}" \
|
||||
-p "${ai_provider_port}:8010" \
|
||||
"$AI_PROVIDER_IMAGE_NAME" >/dev/null
|
||||
}
|
||||
|
||||
recreate_ai_provider_container() {
|
||||
local ai_provider_port="${1:-$DEFAULT_AI_PROVIDER_PORT}"
|
||||
|
||||
remove_ai_provider_containers
|
||||
|
||||
if compose_up up -d aiprovider >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
run_ai_provider_container_manually "$ai_provider_port"
|
||||
}
|
||||
|
||||
ensure_ai_provider_image_current() {
|
||||
local current_fingerprint=""
|
||||
local previous_fingerprint=""
|
||||
|
||||
current_fingerprint="$(compute_ai_provider_build_fingerprint)"
|
||||
previous_fingerprint="$(read_ai_provider_build_stamp || true)"
|
||||
|
||||
if ai_provider_image_exists && [ -n "$previous_fingerprint" ] && [ "$current_fingerprint" = "$previous_fingerprint" ]; then
|
||||
AI_PROVIDER_RECREATE_REQUIRED=0
|
||||
return 0
|
||||
fi
|
||||
|
||||
set_wait_detail "检测到 AI Provider 代码或配置变化,重建镜像"
|
||||
|
||||
if ! compose_supports_build; then
|
||||
log_error "当前 docker compose 不支持 build,请检查 Docker / Compose 环境"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! run_with_retry \
|
||||
"$AI_PROVIDER_START_MAX_RETRIES" \
|
||||
"$AI_PROVIDER_RETRY_INTERVAL" \
|
||||
"AI Provider 镜像构建失败,已重试 ${AI_PROVIDER_START_MAX_RETRIES} 次" \
|
||||
"构建 AI Provider 镜像" \
|
||||
compose_up build aiprovider; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
write_ai_provider_build_stamp "$current_fingerprint"
|
||||
AI_PROVIDER_RECREATE_REQUIRED=1
|
||||
}
|
||||
|
||||
install_uv_if_needed() {
|
||||
if command -v uv >/dev/null 2>&1; then
|
||||
return 0
|
||||
@@ -753,9 +896,19 @@ start_ai_provider_service() {
|
||||
local retry=1
|
||||
set_wait_detail "启动 AI Provider"
|
||||
|
||||
ensure_ai_provider_image_current
|
||||
|
||||
while [ "$retry" -le "$AI_PROVIDER_START_MAX_RETRIES" ]; do
|
||||
if docker start planet_aiprovider >/dev/null 2>&1 || compose_up up -d aiprovider >/dev/null 2>&1; then
|
||||
if wait_for_container_health "planet_aiprovider" "$AI_PROVIDER_HEALTH_CHECK_ATTEMPTS" "$AI_PROVIDER_HEALTH_CHECK_INTERVAL" "AI Provider" &&
|
||||
if [ "$AI_PROVIDER_RECREATE_REQUIRED" -eq 1 ]; then
|
||||
if recreate_ai_provider_container "$ai_provider_port"; then
|
||||
AI_PROVIDER_RECREATE_REQUIRED=0
|
||||
if wait_for_container_health "$AI_PROVIDER_CONTAINER_NAME" "$AI_PROVIDER_HEALTH_CHECK_ATTEMPTS" "$AI_PROVIDER_HEALTH_CHECK_INTERVAL" "AI Provider" &&
|
||||
wait_for_http "http://localhost:${ai_provider_port}/health" "$AI_PROVIDER_HEALTH_CHECK_ATTEMPTS" "$AI_PROVIDER_HEALTH_CHECK_INTERVAL" "AI Provider"; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
elif docker start "$AI_PROVIDER_CONTAINER_NAME" >/dev/null 2>&1 || compose_up up -d aiprovider >/dev/null 2>&1; then
|
||||
if wait_for_container_health "$AI_PROVIDER_CONTAINER_NAME" "$AI_PROVIDER_HEALTH_CHECK_ATTEMPTS" "$AI_PROVIDER_HEALTH_CHECK_INTERVAL" "AI Provider" &&
|
||||
wait_for_http "http://localhost:${ai_provider_port}/health" "$AI_PROVIDER_HEALTH_CHECK_ATTEMPTS" "$AI_PROVIDER_HEALTH_CHECK_INTERVAL" "AI Provider"; then
|
||||
return 0
|
||||
fi
|
||||
@@ -763,17 +916,18 @@ start_ai_provider_service() {
|
||||
|
||||
if [ "$retry" -eq "$AI_PROVIDER_START_MAX_RETRIES" ]; then
|
||||
log_error "AI Provider 启动失败,已重试 ${AI_PROVIDER_START_MAX_RETRIES} 次"
|
||||
docker logs --tail 20 planet_aiprovider 2>/dev/null || true
|
||||
docker logs --tail 20 "$AI_PROVIDER_CONTAINER_NAME" 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker restart planet_aiprovider >/dev/null 2>&1 || true
|
||||
remove_ai_provider_containers
|
||||
AI_PROVIDER_RECREATE_REQUIRED=1
|
||||
animate_wait_spinner "AI Provider 第 ${retry}/${AI_PROVIDER_START_MAX_RETRIES} 次启动后仍未健康,正在重启容器" "$AI_PROVIDER_RETRY_INTERVAL"
|
||||
retry=$((retry + 1))
|
||||
done
|
||||
|
||||
log_error "AI Provider 启动失败"
|
||||
docker logs --tail 20 planet_aiprovider 2>/dev/null || true
|
||||
docker logs --tail 20 "$AI_PROVIDER_CONTAINER_NAME" 2>/dev/null || true
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -1179,7 +1333,7 @@ stop_backend_service() {
|
||||
}
|
||||
|
||||
stop_ai_provider_service() {
|
||||
stop_container_if_running "planet_aiprovider" "AI Provider"
|
||||
stop_container_if_running "$AI_PROVIDER_CONTAINER_NAME" "AI Provider"
|
||||
}
|
||||
|
||||
stop_frontend_service() {
|
||||
|
||||
Reference in New Issue
Block a user