fix(deploy): 修复组件版本解析和安装升级验收流程
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
# Shared installation/update checks. Never print compose config or credentials.
|
||||
init_deployment_docker_config() {
|
||||
local file="$1" configured fallback
|
||||
configured="$(read_env_value "$file" DOCKER_CONFIG_FILE)"
|
||||
if [ -n "$configured" ] && [ -f "$configured" ]; then return 0; fi
|
||||
if [ -n "$configured" ] && [ "$configured" != /root/.docker/config.json ]; then
|
||||
echo '❌ DOCKER_CONFIG_FILE 不是可读取的配置文件;未启动服务' >&2
|
||||
return 1
|
||||
fi
|
||||
if [ -f "${DOCKER_CONFIG:-$HOME/.docker}/config.json" ]; then
|
||||
write_env_value "$file" DOCKER_CONFIG_FILE "${DOCKER_CONFIG:-$HOME/.docker}/config.json"
|
||||
return 0
|
||||
fi
|
||||
# Anonymous installations have no ~/.docker/config.json. A missing short
|
||||
# bind source would otherwise be created by Docker as a DIRECTORY.
|
||||
fallback="$PWD/data/docker-auth/config.json"
|
||||
mkdir -p "$(dirname "$fallback")"
|
||||
chmod 700 "$(dirname "$fallback")"
|
||||
if [ ! -e "$fallback" ]; then (umask 077; printf '{}\n' > "$fallback"); fi
|
||||
[ -f "$fallback" ] || { echo '❌ 安装目录的镜像认证配置不是文件' >&2; return 1; }
|
||||
write_env_value "$file" DOCKER_CONFIG_FILE "$fallback"
|
||||
}
|
||||
|
||||
verify_deployment_images() {
|
||||
local compose="$1" configuration
|
||||
shift
|
||||
configuration="$(sudo $compose config --format json)" || return 1
|
||||
printf '%s' "$configuration" | python3 ./scripts/verify-deployment-images.py --sudo --services "$@"
|
||||
}
|
||||
|
||||
check_deployment_storage() {
|
||||
local compose="$1" configuration
|
||||
shift
|
||||
configuration="$(sudo $compose config --format json)" || return 1
|
||||
printf '%s' "$configuration" | python3 ./scripts/check-deployment-storage.py --sudo --services "$@"
|
||||
}
|
||||
|
||||
verify_pulled_release() {
|
||||
local compose="$1" configuration
|
||||
shift
|
||||
configuration="$(sudo $compose config --format json)" || return 1
|
||||
printf '%s' "$configuration" | python3 ./scripts/verify-pulled-release.py --sudo --services "$@"
|
||||
}
|
||||
|
||||
wait_for_deployment_services() {
|
||||
local compose="$1" timeout="$2" deadline service container_id state running health all_ready passes=0
|
||||
shift 2
|
||||
local services=("$@")
|
||||
[[ "$timeout" =~ ^[1-9][0-9]*$ ]] || { echo '❌ 健康检查等待秒数必须为正整数' >&2; return 1; }
|
||||
if [ "${#services[@]}" -eq 0 ]; then
|
||||
while IFS= read -r service; do [ -z "$service" ] || services+=("$service"); done < <(sudo $compose config --services)
|
||||
fi
|
||||
[ "${#services[@]}" -gt 0 ] || return 1
|
||||
deadline=$((SECONDS + timeout))
|
||||
echo "⏳ 等待 ${#services[@]} 个服务恢复可用(最长 ${timeout} 秒)..."
|
||||
while (( SECONDS < deadline )); do
|
||||
all_ready=true
|
||||
for service in "${services[@]}"; do
|
||||
container_id="$(sudo $compose ps -q "$service" 2>/dev/null || true)"
|
||||
if [ -z "$container_id" ]; then all_ready=false; continue; fi
|
||||
state="$(sudo docker inspect --format '{{.State.Running}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' "$container_id" 2>/dev/null || true)"
|
||||
running="${state%%|*}"; health="${state#*|}"
|
||||
if [ "$running" != true ] || { [ "$health" != none ] && [ "$health" != healthy ]; }; then
|
||||
all_ready=false
|
||||
elif [ "$service" = watchtower ] && [ "$health" = none ]; then
|
||||
sudo docker exec "$container_id" /watchtower --health-check >/dev/null 2>&1 || all_ready=false
|
||||
fi
|
||||
done
|
||||
if [ "$all_ready" = true ]; then
|
||||
passes=$((passes + 1))
|
||||
if [ "$passes" -ge 2 ]; then echo '✅ 所选服务已恢复可用'; return 0; fi
|
||||
sleep 2
|
||||
else
|
||||
passes=0
|
||||
sleep 5
|
||||
fi
|
||||
done
|
||||
echo '❌ 服务未在规定时间内恢复可用,部署未完成' >&2
|
||||
sudo $compose ps "${services[@]}" || true
|
||||
echo "请运行:$compose logs --tail=100 ${services[*]}" >&2
|
||||
return 1
|
||||
}
|
||||
Reference in New Issue
Block a user