- #!/usr/bin/env bash
- set -Eeuo pipefail
-
- # Apply an incremental image update on the target runtime server.
- # Usage:
- # bash apply-update.sh
- # bash apply-update.sh emp-admin emp-monitor
- # PROJECT_NAME=emp-test ENV_FILE=.env COMPOSE_FILE=docker-compose.yml bash apply-update.sh
-
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
- cd "$SCRIPT_DIR"
-
- PROJECT_NAME="${PROJECT_NAME:-emp-test}"
- ENV_FILE="${ENV_FILE:-.env}"
- COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
- IMAGE_TAR="${IMAGE_TAR:-images.tar}"
- SERVICE_FILE="${SERVICE_FILE:-services.txt}"
-
- 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"
- }
-
- normalize_service() {
- case "$1" in
- gateway|emp-gateway) echo "emp-gateway" ;;
- auth|emp-auth) echo "emp-auth" ;;
- monitor|emp-monitor) echo "emp-monitor" ;;
- data|emp-data) echo "emp-data" ;;
- pdf|emp-pdf) echo "emp-pdf" ;;
- ws|emp-ws) echo "emp-ws" ;;
- admin|emp-admin) echo "emp-admin" ;;
- *) die "Unknown service: $1. Allowed: gateway auth monitor data pdf ws admin" ;;
- esac
- }
-
- resolve_compose_cmd() {
- if docker compose version >/dev/null 2>&1; then
- echo "docker compose"
- elif command -v docker-compose >/dev/null 2>&1; then
- echo "docker-compose"
- else
- die "Missing docker compose"
- fi
- }
-
- resolve_runtime_file() {
- local requested="$1"
- local default_name="$2"
- if [[ -f "$requested" ]]; then
- echo "$requested"
- return
- fi
- if [[ "$requested" != "$default_name" ]]; then
- echo "$requested"
- return
- fi
-
- local candidates=(
- "../runtime/$default_name"
- "/home/admin-x99/emp-test/runtime/$default_name"
- )
- local candidate
- for candidate in "${candidates[@]}"; do
- if [[ -f "$candidate" ]]; then
- echo "$candidate"
- return
- fi
- done
-
- echo "$requested"
- }
-
- read_services() {
- local raw_services=()
- if [[ "$#" -gt 0 ]]; then
- raw_services=("$@")
- elif [[ -f "$SERVICE_FILE" ]]; then
- mapfile -t raw_services < "$SERVICE_FILE"
- else
- die "No services specified. Pass services as args or provide $SERVICE_FILE."
- fi
-
- local service
- for service in "${raw_services[@]}"; do
- [[ -n "$service" ]] || continue
- normalize_service "$service"
- done
- }
-
- need_cmd docker
- ENV_FILE="$(resolve_runtime_file "$ENV_FILE" ".env")"
- COMPOSE_FILE="$(resolve_runtime_file "$COMPOSE_FILE" "docker-compose.yml")"
- [[ -f "$ENV_FILE" ]] || die "Missing env file: $ENV_FILE"
- [[ -f "$COMPOSE_FILE" ]] || die "Missing compose file: $COMPOSE_FILE"
- [[ -f "$IMAGE_TAR" ]] || die "Missing image tar: $IMAGE_TAR"
-
- mapfile -t UPDATE_SERVICES < <(read_services "$@")
- [[ "${#UPDATE_SERVICES[@]}" -gt 0 ]] || die "No services to update."
-
- COMPOSE_CMD="$(resolve_compose_cmd)"
-
- log "Load images: $IMAGE_TAR"
- docker load -i "$IMAGE_TAR"
-
- log "Recreate services: ${UPDATE_SERVICES[*]}"
- # shellcheck disable=SC2086
- $COMPOSE_CMD \
- --env-file "$ENV_FILE" \
- -f "$COMPOSE_FILE" \
- -p "$PROJECT_NAME" \
- up -d --no-deps --force-recreate "${UPDATE_SERVICES[@]}"
-
- log "Current service status"
- # shellcheck disable=SC2086
- $COMPOSE_CMD \
- --env-file "$ENV_FILE" \
- -f "$COMPOSE_FILE" \
- -p "$PROJECT_NAME" \
- ps "${UPDATE_SERVICES[@]}"
|