#!/usr/bin/env bash set -euo pipefail NAMESPACE=${KUBE_NAMESPACE:-magistr} BACKEND_REF=${1:-} FRONTEND_REF=${2:-} log() { printf '[CI/CD] %s\n' "$1" } fail() { printf '[CI/CD] Ошибка: %s\n' "$1" >&2 exit 1 } require_digest() { local image_ref=$1 local component=$2 if [[ ! "$image_ref" =~ ^[^[:space:]@]+@sha256:[0-9a-f]{64}$ ]]; then fail "для ${component} требуется полный immutable image digest" fi } require_digest "$BACKEND_REF" "backend" require_digest "$FRONTEND_REF" "frontend" previous_backend=$(kubectl get deployment backend -n "$NAMESPACE" \ -o 'jsonpath={.spec.template.spec.containers[?(@.name=="backend")].image}') previous_frontend=$(kubectl get deployment frontend -n "$NAMESPACE" \ -o 'jsonpath={.spec.template.spec.containers[?(@.name=="frontend")].image}') [[ -n "$previous_backend" ]] || fail "не удалось определить текущий образ backend" [[ -n "$previous_frontend" ]] || fail "не удалось определить текущий образ frontend" rollback() { local failed=0 log "Rollout завершился ошибкой, возвращаем предыдущие образы" kubectl set image deployment/backend backend="$previous_backend" -n "$NAMESPACE" || failed=1 kubectl set image deployment/frontend frontend="$previous_frontend" -n "$NAMESPACE" || failed=1 kubectl rollout status deployment/frontend -n "$NAMESPACE" --timeout=120s || failed=1 kubectl rollout status deployment/backend -n "$NAMESPACE" --timeout=300s || failed=1 if [[ "$failed" -ne 0 ]]; then printf '[CI/CD] Ошибка: автоматический rollback требует вмешательства оператора\n' >&2 return 1 fi log "Предыдущие образы восстановлены" } log "Применяем проверенные image digests" if ! kubectl set image deployment/backend backend="$BACKEND_REF" -n "$NAMESPACE" \ || ! kubectl set image deployment/frontend frontend="$FRONTEND_REF" -n "$NAMESPACE"; then rollback || true fail "не удалось обновить Deployment" fi if ! kubectl rollout status deployment/frontend -n "$NAMESPACE" --timeout=120s \ || ! kubectl rollout status deployment/backend -n "$NAMESPACE" --timeout=300s; then rollback || true fail "новая ревизия не достигла состояния Ready" fi log "Immutable rollout успешно завершён"