fix: same - idempotent apply, vm_wait_binary, extra sanity checks
This commit is contained in:
parent
bad38aa62a
commit
dc71622fb8
@ -201,6 +201,20 @@ vm_check_binary() {
|
||||
vm_ssh "$ip" "command -v $bin" &>/dev/null
|
||||
}
|
||||
|
||||
# vm_wait_binary: ждать пока бинарник появится на VM (sless_job работает асинхронно).
|
||||
# Нужен потому что sless_job запускает kubernetes Job, который сначала собирает образ,
|
||||
# затем стартует pod, и только потом SSH-устанавливает пакеты на VM — это занимает 1-3 мин.
|
||||
vm_wait_binary() {
|
||||
local ip="$1" bin="$2" timeout_sec="${3:-180}"
|
||||
local deadline=$((SECONDS + timeout_sec))
|
||||
info "жду появления '$bin' на VM (до ${timeout_sec}s)..."
|
||||
while [[ $SECONDS -lt $deadline ]]; do
|
||||
if vm_check_binary "$ip" "$bin"; then return 0; fi
|
||||
sleep 15
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# vm_purge_all: удалить все установленные пакеты с VM.
|
||||
vm_purge_all() {
|
||||
local ip="$1"
|
||||
@ -277,26 +291,31 @@ phase_1_baseline() {
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# ФАЗА 2: IDEMPOTENT — повторный plan без изменений
|
||||
# Передаём тот же run_id → ничего не изменилось → "No changes".
|
||||
# ФАЗА 2: IDEMPOTENT — повторный apply с теми же аргументами → 0 changed
|
||||
# Используем apply (не plan) — это надёжнее: некоторые sless-провайдеры показывают
|
||||
# ложный drift в plan, но apply при этом возвращает 0 changed. Apply — canonical way.
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
phase_2_idempotent() {
|
||||
phase_header 2 "IDEMPOTENT — повторный plan без изменений"
|
||||
phase_header 2 "IDEMPOTENT — повторный apply без изменений"
|
||||
|
||||
# Тот же run_id что в предыдущей фазе → "No changes"
|
||||
if tf_plan_no_changes \
|
||||
# Тот же run_id что применялся в фазе 1 → apply должен вернуть 0 changed
|
||||
if tf_apply \
|
||||
-var "install_packages=true" \
|
||||
-var "install_nginx=true" \
|
||||
-var "install_docker=true" \
|
||||
-var "install_run_id=$RUN_ID"; then
|
||||
pass "2.1 terraform plan → No changes"
|
||||
if grep -q '0 added, 0 changed, 0 destroyed' /tmp/vm_tf_apply.log; then
|
||||
pass "2.1 повторный apply → 0 added, 0 changed, 0 destroyed"
|
||||
else
|
||||
fail "2.1 terraform plan показывает изменения (ожидали No changes)"
|
||||
grep -E 'will be|must be' /tmp/vm_tf_plan.log 2>/dev/null | head -5 | while read -r line; do
|
||||
fail "2.1 повторный apply изменил ресурсы (ожидали 0 changed)"
|
||||
grep -E 'added|changed|destroyed' /tmp/vm_tf_apply.log | tail -3 | while read -r line; do
|
||||
info " $line"
|
||||
done
|
||||
fi
|
||||
else
|
||||
fail "2.1 повторный apply упал"
|
||||
fi
|
||||
|
||||
phase_result "IDEMPOTENT" "PASS"
|
||||
}
|
||||
@ -498,19 +517,18 @@ phase_6_manual_purge() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Подождать и проверить что пакеты вернулись
|
||||
sleep 5
|
||||
|
||||
if vm_check_binary "$ip" "docker"; then
|
||||
# Ждать пока sless_job отработает: docker самый долгий (k8s Job + apt-install).
|
||||
# vm_wait_binary полит каждые 15s до 180s вместо sleep 5.
|
||||
if vm_wait_binary "$ip" "docker" 180; then
|
||||
pass "6.5 docker установлен заново"
|
||||
else
|
||||
fail "6.5 docker НЕ установлен после re-apply"
|
||||
fail "6.5 docker НЕ установлен после re-apply (таймаут 180s)"
|
||||
fi
|
||||
|
||||
if vm_check_binary "$ip" "nginx"; then
|
||||
if vm_wait_binary "$ip" "nginx" 120; then
|
||||
pass "6.6 nginx установлен заново"
|
||||
else
|
||||
fail "6.6 nginx НЕ установлен после re-apply"
|
||||
fail "6.6 nginx НЕ установлен после re-apply (таймаут 120s)"
|
||||
fi
|
||||
|
||||
if vm_check_binary "$ip" "jq"; then
|
||||
@ -702,15 +720,22 @@ phase_10_final() {
|
||||
-var "install_run_id=$rid" || warn "восстановление не удалось"
|
||||
fi
|
||||
|
||||
# Plan = no changes (с тем же run_id что и последний apply)
|
||||
if tf_plan_no_changes \
|
||||
# Idempotency финально: повторный apply → 0 changed
|
||||
if tf_apply \
|
||||
-var "install_packages=true" \
|
||||
-var "install_nginx=true" \
|
||||
-var "install_docker=true" \
|
||||
-var "install_run_id=$RUN_ID"; then
|
||||
pass "10.2 terraform plan → No changes"
|
||||
if grep -q '0 added, 0 changed, 0 destroyed' /tmp/vm_tf_apply.log; then
|
||||
pass "10.2 финальный apply → 0 added, 0 changed, 0 destroyed"
|
||||
else
|
||||
fail "10.2 terraform plan показывает изменения"
|
||||
fail "10.2 финальный apply изменил ресурсы (ожидали 0 changed)"
|
||||
grep -E 'added|changed|destroyed' /tmp/vm_tf_apply.log | tail -3 | while read -r line; do
|
||||
info " $line"
|
||||
done
|
||||
fi
|
||||
else
|
||||
fail "10.2 финальный apply упал"
|
||||
fi
|
||||
|
||||
# VM доступна
|
||||
@ -739,6 +764,54 @@ phase_10_final() {
|
||||
else
|
||||
fail "10.6 docker НЕ найден"
|
||||
fi
|
||||
|
||||
# nginx service активен (не просто бинарник, а именно демон)
|
||||
if vm_ssh "$ip" "systemctl is-active nginx 2>/dev/null" 2>/dev/null | grep -q '^active$'; then
|
||||
pass "10.7 nginx service активен (systemctl)"
|
||||
else
|
||||
fail "10.7 nginx service не активен"
|
||||
fi
|
||||
|
||||
# docker daemon активен
|
||||
if vm_ssh "$ip" "systemctl is-active docker 2>/dev/null" 2>/dev/null | grep -q '^active$'; then
|
||||
pass "10.8 docker daemon активен (systemctl)"
|
||||
else
|
||||
fail "10.8 docker daemon не активен"
|
||||
fi
|
||||
|
||||
# HTTP probe: nginx отвечает на localhost:80
|
||||
local http_code
|
||||
http_code=$(vm_ssh "$ip" "curl -sS -o /dev/null -w '%{http_code}' http://localhost 2>/dev/null" 2>/dev/null)
|
||||
if [[ "$http_code" == "200" ]]; then
|
||||
pass "10.9 nginx отвечает HTTP 200"
|
||||
else
|
||||
fail "10.9 nginx не отвечает HTTP 200 (code='$http_code')"
|
||||
fi
|
||||
|
||||
# python3 доступен
|
||||
local py_ver
|
||||
py_ver=$(vm_ssh "$ip" "python3 --version 2>&1" 2>/dev/null)
|
||||
if echo "$py_ver" | grep -q 'Python 3'; then
|
||||
pass "10.10 python3 доступен ($py_ver)"
|
||||
else
|
||||
fail "10.10 python3 недоступен"
|
||||
fi
|
||||
|
||||
# docker smoke: запустить контейнер и проверить вывод
|
||||
if vm_ssh "$ip" "docker run --rm hello-world 2>&1 | grep -q 'Hello from Docker'" 2>/dev/null; then
|
||||
pass "10.11 docker run hello-world → успешно"
|
||||
else
|
||||
fail "10.11 docker run hello-world → не прошёл"
|
||||
fi
|
||||
|
||||
# disk space: убедиться что на VM есть место (>500MB free)
|
||||
local free_mb
|
||||
free_mb=$(vm_ssh "$ip" "df -m / 2>/dev/null | awk 'NR==2{print \$4}'" 2>/dev/null)
|
||||
if [[ -n "$free_mb" && "$free_mb" -gt 500 ]]; then
|
||||
pass "10.12 свободное место на / = ${free_mb}MB (>500MB)"
|
||||
else
|
||||
fail "10.12 мало места на / = ${free_mb}MB (ожидали >500MB)"
|
||||
fi
|
||||
else
|
||||
fail "10.3 VM не доступна по SSH"
|
||||
fi
|
||||
|
||||
Loading…
Reference in New Issue
Block a user