Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

157 строки
4.0 KiB

  1. #!/usr/bin/env bash
  2. set -Eeuo pipefail
  3. # Apply an incremental image update on the target runtime server.
  4. # Usage:
  5. # bash apply-update.sh
  6. # bash apply-update.sh emp-admin emp-monitor
  7. # DEPLOY_ENV=emp-uat ENV_FILE=.env COMPOSE_FILE=docker-compose.yml bash apply-update.sh
  8. # COMPOSE_FILES="/path/docker-compose.yml:/path/docker-compose.logs.yml" bash apply-update.sh
  9. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  10. cd "$SCRIPT_DIR"
  11. DEPLOY_ENV="${DEPLOY_ENV:-emp-test}"
  12. PROJECT_NAME="${PROJECT_NAME:-$DEPLOY_ENV}"
  13. DEPLOY_HOME="${DEPLOY_HOME:-/home/admin-x99/$DEPLOY_ENV}"
  14. ENV_FILE="${ENV_FILE:-.env}"
  15. COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
  16. COMPOSE_FILES="${COMPOSE_FILES:-}"
  17. IMAGE_TAR="${IMAGE_TAR:-images.tar}"
  18. SERVICE_FILE="${SERVICE_FILE:-services.txt}"
  19. log() {
  20. echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
  21. }
  22. die() {
  23. echo "ERROR: $*" >&2
  24. exit 1
  25. }
  26. need_cmd() {
  27. command -v "$1" >/dev/null 2>&1 || die "Missing command: $1"
  28. }
  29. normalize_service() {
  30. case "$1" in
  31. gateway|emp-gateway) echo "emp-gateway" ;;
  32. auth|emp-auth) echo "emp-auth" ;;
  33. monitor|emp-monitor) echo "emp-monitor" ;;
  34. data|emp-data) echo "emp-data" ;;
  35. pdf|emp-pdf) echo "emp-pdf" ;;
  36. ws|emp-ws) echo "emp-ws" ;;
  37. admin|emp-admin) echo "emp-admin" ;;
  38. *) die "Unknown service: $1. Allowed: gateway auth monitor data pdf ws admin" ;;
  39. esac
  40. }
  41. resolve_compose_cmd() {
  42. if docker compose version >/dev/null 2>&1; then
  43. echo "docker compose"
  44. elif command -v docker-compose >/dev/null 2>&1; then
  45. echo "docker-compose"
  46. else
  47. die "Missing docker compose"
  48. fi
  49. }
  50. resolve_runtime_file() {
  51. local requested="$1"
  52. local default_name="$2"
  53. if [[ -f "$requested" ]]; then
  54. echo "$requested"
  55. return
  56. fi
  57. if [[ "$requested" != "$default_name" ]]; then
  58. echo "$requested"
  59. return
  60. fi
  61. local candidates=(
  62. "../runtime/$default_name"
  63. "$DEPLOY_HOME/runtime/$default_name"
  64. "$DEPLOY_HOME/$default_name"
  65. "/opt/$DEPLOY_ENV/$default_name"
  66. )
  67. local candidate
  68. for candidate in "${candidates[@]}"; do
  69. if [[ -f "$candidate" ]]; then
  70. echo "$candidate"
  71. return
  72. fi
  73. done
  74. echo "$requested"
  75. }
  76. resolve_compose_files() {
  77. local raw_files=()
  78. local file resolved
  79. if [[ -n "$COMPOSE_FILES" ]]; then
  80. IFS=':' read -r -a raw_files <<< "$COMPOSE_FILES"
  81. else
  82. raw_files=("$COMPOSE_FILE")
  83. fi
  84. COMPOSE_ARGS=()
  85. RESOLVED_COMPOSE_FILES=()
  86. for file in "${raw_files[@]}"; do
  87. [[ -n "$file" ]] || continue
  88. resolved="$(resolve_runtime_file "$file" "docker-compose.yml")"
  89. [[ -f "$resolved" ]] || die "Missing compose file: $resolved"
  90. RESOLVED_COMPOSE_FILES+=("$resolved")
  91. COMPOSE_ARGS+=("-f" "$resolved")
  92. done
  93. [[ "${#COMPOSE_ARGS[@]}" -gt 0 ]] || die "No compose files resolved."
  94. }
  95. read_services() {
  96. local raw_services=()
  97. if [[ "$#" -gt 0 ]]; then
  98. raw_services=("$@")
  99. elif [[ -f "$SERVICE_FILE" ]]; then
  100. mapfile -t raw_services < "$SERVICE_FILE"
  101. else
  102. die "No services specified. Pass services as args or provide $SERVICE_FILE."
  103. fi
  104. local service
  105. for service in "${raw_services[@]}"; do
  106. [[ -n "$service" ]] || continue
  107. normalize_service "$service"
  108. done
  109. }
  110. need_cmd docker
  111. ENV_FILE="$(resolve_runtime_file "$ENV_FILE" ".env")"
  112. resolve_compose_files
  113. [[ -f "$ENV_FILE" ]] || die "Missing env file: $ENV_FILE"
  114. [[ -f "$IMAGE_TAR" ]] || die "Missing image tar: $IMAGE_TAR"
  115. mapfile -t UPDATE_SERVICES < <(read_services "$@")
  116. [[ "${#UPDATE_SERVICES[@]}" -gt 0 ]] || die "No services to update."
  117. COMPOSE_CMD="$(resolve_compose_cmd)"
  118. log "Compose files: ${RESOLVED_COMPOSE_FILES[*]}"
  119. log "Load images: $IMAGE_TAR"
  120. docker load -i "$IMAGE_TAR"
  121. log "Recreate services: ${UPDATE_SERVICES[*]}"
  122. # shellcheck disable=SC2086
  123. $COMPOSE_CMD \
  124. --env-file "$ENV_FILE" \
  125. "${COMPOSE_ARGS[@]}" \
  126. -p "$PROJECT_NAME" \
  127. up -d --no-deps --force-recreate "${UPDATE_SERVICES[@]}"
  128. log "Current service status"
  129. # shellcheck disable=SC2086
  130. $COMPOSE_CMD \
  131. --env-file "$ENV_FILE" \
  132. "${COMPOSE_ARGS[@]}" \
  133. -p "$PROJECT_NAME" \
  134. ps "${UPDATE_SERVICES[@]}"