Files
ccs/docker/host/ccs-cliproxy-reconcile.sh
T

103 lines
2.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
container_name="${CCS_CLIPROXY_CONTAINER:-ccs-cliproxy}"
compose_dir="${CCS_CLIPROXY_COMPOSE_DIR:-/root/.ccs/docker}"
compose_file="${CCS_CLIPROXY_COMPOSE_FILE:-$compose_dir/docker-compose.integrated.yml}"
compose_project="${CCS_CLIPROXY_COMPOSE_PROJECT:-docker}"
lock_file="${CCS_CLIPROXY_LOCK_FILE:-/run/lock/ccs-cliproxy-maintenance.lock}"
log_file="${CCS_CLIPROXY_RECONCILE_LOG:-/var/log/ccs-cliproxy-reconcile.log}"
log() {
printf '[%s] %s\n' "$(date -Is)" "$*" | tee -a "$log_file"
}
exec 9>"$lock_file"
if ! flock -n 9; then
exit 0
fi
probe() {
docker exec "$container_name" sh -c \
'curl -fsS --max-time 2 http://127.0.0.1:3000/ >/dev/null && curl -fsS --max-time 2 http://127.0.0.1:8317/ >/dev/null' \
>/dev/null 2>&1
}
wait_for_health() {
attempts=0
while [ "$attempts" -lt 30 ]; do
if probe; then
return 0
fi
attempts=$((attempts + 1))
sleep 2
done
return 1
}
compose_up() {
cd "$compose_dir"
docker compose --project-name "$compose_project" --project-directory "$compose_dir" \
-f "$compose_file" up -d --no-build || \
docker compose --project-name "$compose_project" --project-directory "$compose_dir" \
-f "$compose_file" up -d --build
}
compose_recreate() {
cd "$compose_dir"
docker compose --project-name "$compose_project" --project-directory "$compose_dir" \
-f "$compose_file" up -d --force-recreate --no-build || \
docker compose --project-name "$compose_project" --project-directory "$compose_dir" \
-f "$compose_file" up -d --force-recreate --build
}
running_state="$(docker inspect --format '{{.State.Running}}' "$container_name" 2>/dev/null || true)"
if [ -z "$running_state" ]; then
log "Container $container_name is missing; recreating from $compose_file"
compose_up
wait_for_health
log "Container $container_name was recreated and passed both health probes"
exit 0
fi
if [ "$running_state" != 'true' ]; then
log "Container $container_name is stopped; restoring the Compose service"
compose_up
wait_for_health
log "Container $container_name is running and passed both health probes"
exit 0
fi
if probe; then
exit 0
fi
sleep 10
if probe; then
exit 0
fi
log 'Dashboard or proxy failed two consecutive probes; restarting supervised processes'
if docker exec "$container_name" \
supervisorctl -c /etc/supervisord.conf restart ccs-dashboard cliproxy; then
if wait_for_health; then
log 'Supervised processes recovered and passed both health probes'
exit 0
fi
fi
log 'Supervisor recovery failed; restarting the container'
if docker restart "$container_name" >/dev/null; then
if wait_for_health; then
log "Container $container_name recovered and passed both health probes"
exit 0
fi
fi
log "Container $container_name is still unhealthy; recreating it from $compose_file"
compose_recreate
wait_for_health
log "Container $container_name was recreated and passed both health probes"