All checks were successful
CD Pipeline / workflow-shape (push) Successful in 2s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m31s
CD Pipeline / build-and-deploy (push) Successful in 15m18s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 22s
CD Pipeline / post-deploy-checks (push) Successful in 5m35s
420 lines
15 KiB
Bash
Executable File
420 lines
15 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Bounded Prometheus scrape-source convergence for Alertmanager delivery truth.
|
|
|
|
set -euo pipefail
|
|
|
|
TRACE_ID="${TRACE_ID:?TRACE_ID is required}"
|
|
RUN_ID="${RUN_ID:?RUN_ID is required}"
|
|
WORK_ITEM_ID="${WORK_ITEM_ID:?WORK_ITEM_ID is required}"
|
|
TARGET_HOST="${TARGET_HOST:-wooo@192.168.0.110}"
|
|
PROMETHEUS_URL="${PROMETHEUS_URL:-http://192.168.0.110:9090}"
|
|
ALERTMANAGER_METRICS_URL="${ALERTMANAGER_METRICS_URL:-http://127.0.0.1:9093/metrics}"
|
|
PROMETHEUS_CONTAINER="${PROMETHEUS_CONTAINER:-prometheus}"
|
|
REMOTE_CONFIG="${REMOTE_CONFIG:-/home/wooo/monitoring/prometheus.yml}"
|
|
MODE="${1:---dry-run}"
|
|
|
|
case "${MODE}" in
|
|
apply|--dry-run) ;;
|
|
*) printf 'usage: %s [--dry-run|apply]\n' "$0" >&2; exit 64 ;;
|
|
esac
|
|
|
|
for value in "${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}"; do
|
|
case "${value}" in
|
|
*[!A-Za-z0-9._-]*|'')
|
|
printf 'trace/run/work item identifiers must be non-empty and shell-safe\n' >&2
|
|
exit 64
|
|
;;
|
|
esac
|
|
done
|
|
|
|
ssh -o BatchMode=yes -o ConnectTimeout=8 "${TARGET_HOST}" \
|
|
bash -s -- "${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" "${MODE}" \
|
|
"${PROMETHEUS_URL}" "${ALERTMANAGER_METRICS_URL}" \
|
|
"${PROMETHEUS_CONTAINER}" "${REMOTE_CONFIG}" <<'REMOTE'
|
|
set -euo pipefail
|
|
|
|
TRACE_ID="$1"
|
|
RUN_ID="$2"
|
|
WORK_ITEM_ID="$3"
|
|
MODE="$4"
|
|
PROMETHEUS_URL="$5"
|
|
ALERTMANAGER_METRICS_URL="$6"
|
|
PROMETHEUS_CONTAINER="$7"
|
|
REMOTE_CONFIG="$8"
|
|
REMOTE_CANDIDATE="/tmp/awoooi-prometheus-alertmanager-runtime.${RUN_ID}.yml"
|
|
CONTAINER_CANDIDATE="/etc/prometheus/.awoooi-alertmanager-runtime.${RUN_ID}.yml"
|
|
BACKUP_CONFIG="${REMOTE_CONFIG}.bak.${RUN_ID}"
|
|
APPLY_STARTED=0
|
|
DEPLOY_VERIFIED=0
|
|
SOURCE_SHA=""
|
|
CANDIDATE_SHA=""
|
|
|
|
exec 9>/tmp/awoooi-prometheus-config.lock
|
|
if ! flock -n 9; then
|
|
printf 'terminal trace_id=%s run_id=%s work_item_id=%s status=blocked_with_safe_next_action reason=prometheus_config_apply_in_progress\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" >&2
|
|
exit 75
|
|
fi
|
|
|
|
cleanup() {
|
|
rm -f "${REMOTE_CANDIDATE}"
|
|
docker exec -u 0 "${PROMETHEUS_CONTAINER}" \
|
|
rm -f "${CONTAINER_CANDIDATE}" >/dev/null 2>&1 || true
|
|
}
|
|
|
|
rollback() {
|
|
local rollback_rc=0
|
|
local current_sha backup_sha restored_sha
|
|
current_sha="$(sha256sum "${REMOTE_CONFIG}" | awk '{print $1}')" || rollback_rc=1
|
|
backup_sha="$(sha256sum "${BACKUP_CONFIG}" | awk '{print $1}')" || rollback_rc=1
|
|
if [ "${rollback_rc}" -eq 0 ] && [ "${current_sha}" = "${SOURCE_SHA}" ]; then
|
|
printf 'rollback_receipt trace_id=%s run_id=%s work_item_id=%s terminal=no_write_source_intact source_sha=%s\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" "${SOURCE_SHA}"
|
|
return 0
|
|
fi
|
|
if [ "${rollback_rc}" -ne 0 ] \
|
|
|| [ "${current_sha}" != "${CANDIDATE_SHA}" ] \
|
|
|| [ "${backup_sha}" != "${SOURCE_SHA}" ]; then
|
|
rollback_rc=1
|
|
else
|
|
cp "${BACKUP_CONFIG}" "${REMOTE_CONFIG}" || rollback_rc=1
|
|
restored_sha="$(sha256sum "${REMOTE_CONFIG}" | awk '{print $1}')" || rollback_rc=1
|
|
[ "${restored_sha}" = "${SOURCE_SHA}" ] || rollback_rc=1
|
|
fi
|
|
if [ "${rollback_rc}" -eq 0 ]; then
|
|
curl -fsS -X POST "${PROMETHEUS_URL}/-/reload" >/dev/null \
|
|
|| rollback_rc=1
|
|
fi
|
|
if [ "${rollback_rc}" -eq 0 ]; then
|
|
curl -fsS "${PROMETHEUS_URL}/-/ready" >/dev/null || rollback_rc=1
|
|
fi
|
|
if [ "${rollback_rc}" -eq 0 ]; then
|
|
printf 'rollback_receipt trace_id=%s run_id=%s work_item_id=%s terminal=rolled_back ready=true backup=%s\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" "${BACKUP_CONFIG}"
|
|
return 0
|
|
fi
|
|
printf 'rollback_receipt trace_id=%s run_id=%s work_item_id=%s terminal=rollback_failed ready=false backup=%s\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" "${BACKUP_CONFIG}" >&2
|
|
return 1
|
|
}
|
|
|
|
on_exit() {
|
|
rc=$?
|
|
trap - EXIT
|
|
set +e
|
|
cleanup
|
|
rollback_rc=0
|
|
if [ "${rc}" -ne 0 ] && [ "${APPLY_STARTED}" -eq 1 ] \
|
|
&& [ "${DEPLOY_VERIFIED}" -eq 0 ]; then
|
|
rollback || rollback_rc=$?
|
|
fi
|
|
if [ "${rollback_rc}" -ne 0 ]; then
|
|
exit 70
|
|
fi
|
|
exit "${rc}"
|
|
}
|
|
trap on_exit EXIT
|
|
|
|
test -f "${REMOTE_CONFIG}"
|
|
test "$(docker inspect --format '{{.State.Running}}' "${PROMETHEUS_CONTAINER}")" = true
|
|
curl -fsS "${PROMETHEUS_URL}/-/ready" >/dev/null
|
|
METRICS_SNAPSHOT="$(curl -fsS "${ALERTMANAGER_METRICS_URL}")"
|
|
grep -Eq '^alertmanager_notification_requests_total\{[^}]*integration="webhook"' <<<"${METRICS_SNAPSHOT}"
|
|
grep -Eq '^alertmanager_notification_requests_failed_total\{[^}]*integration="webhook"' <<<"${METRICS_SNAPSHOT}"
|
|
SOURCE_SHA="$(sha256sum "${REMOTE_CONFIG}" | awk '{print $1}')"
|
|
|
|
python3 - "${REMOTE_CONFIG}" "${REMOTE_CANDIDATE}" <<'PY'
|
|
from pathlib import Path
|
|
import re
|
|
import sys
|
|
|
|
source = Path(sys.argv[1])
|
|
candidate = Path(sys.argv[2])
|
|
text = source.read_text(encoding="utf-8")
|
|
|
|
begin = " # BEGIN AWOOOI ALERTMANAGER RUNTIME DELIVERY TRUTH\n"
|
|
end = " # END AWOOOI ALERTMANAGER RUNTIME DELIVERY TRUTH\n"
|
|
block = """ # BEGIN AWOOOI ALERTMANAGER RUNTIME DELIVERY TRUTH
|
|
- job_name: 'alertmanager-runtime'
|
|
scrape_interval: 30s
|
|
metrics_path: /metrics
|
|
static_configs:
|
|
- targets: ['alertmanager:9093']
|
|
labels:
|
|
host: '110'
|
|
service: 'alertmanager'
|
|
env: 'prod'
|
|
metric_relabel_configs:
|
|
- source_labels: [__name__, integration]
|
|
separator: ';'
|
|
regex: 'alertmanager_notification_requests(_failed)?_total;webhook'
|
|
target_label: receiver_contract
|
|
replacement: 'awoooi-webhook'
|
|
# END AWOOOI ALERTMANAGER RUNTIME DELIVERY TRUTH
|
|
|
|
"""
|
|
|
|
if text.count(begin) != text.count(end) or text.count(begin) > 1:
|
|
raise SystemExit("alertmanager runtime managed block is ambiguous")
|
|
if begin in text:
|
|
pattern = re.escape(begin) + r".*?" + re.escape(end) + r"\n?"
|
|
text, count = re.subn(pattern, block, text, count=1, flags=re.S)
|
|
if count != 1:
|
|
raise SystemExit("managed block replacement failed")
|
|
else:
|
|
legacy_pattern = (
|
|
r"(?ms)^ - job_name: ['\"]alertmanager-runtime['\"]\n"
|
|
r".*?(?=^ - job_name:|\Z)"
|
|
)
|
|
legacy_matches = list(re.finditer(legacy_pattern, text))
|
|
if len(legacy_matches) == 1:
|
|
text = re.sub(legacy_pattern, block, text, count=1)
|
|
elif legacy_matches:
|
|
raise SystemExit("legacy alertmanager runtime job is ambiguous")
|
|
else:
|
|
anchors = (
|
|
" # === AWOOOI API Metrics",
|
|
" - job_name: 'awoooi-api'\n",
|
|
)
|
|
anchor = next((value for value in anchors if value in text), None)
|
|
if anchor is None or text.count(anchor) != 1:
|
|
raise SystemExit("awoooi-api insertion anchor missing or ambiguous")
|
|
text = text.replace(anchor, block + anchor, 1)
|
|
|
|
provider_begin = " # BEGIN AWOOOI OLLAMA CLOUD EDGE PROBES\n"
|
|
provider_end = " # END AWOOOI OLLAMA CLOUD EDGE PROBES\n"
|
|
provider_block = """ # BEGIN AWOOOI OLLAMA CLOUD EDGE PROBES
|
|
- targets:
|
|
- http://34.143.170.20:11434/api/tags
|
|
labels:
|
|
service: ollama-cloud-edge
|
|
provider: ollama_gcp_a
|
|
probe_origin: host110
|
|
boundary: cloud_edge_availability_only
|
|
- targets:
|
|
- http://34.21.145.224:11434/api/tags
|
|
labels:
|
|
service: ollama-cloud-edge
|
|
provider: ollama_gcp_b
|
|
probe_origin: host110
|
|
boundary: cloud_edge_availability_only
|
|
# END AWOOOI OLLAMA CLOUD EDGE PROBES
|
|
"""
|
|
if (
|
|
text.count(provider_begin) != text.count(provider_end)
|
|
or text.count(provider_begin) > 1
|
|
):
|
|
raise SystemExit("Ollama cloud edge managed block is ambiguous")
|
|
if provider_begin in text:
|
|
provider_pattern = (
|
|
re.escape(provider_begin)
|
|
+ r".*?"
|
|
+ re.escape(provider_end)
|
|
)
|
|
text, count = re.subn(
|
|
provider_pattern,
|
|
provider_block,
|
|
text,
|
|
count=1,
|
|
flags=re.S,
|
|
)
|
|
if count != 1:
|
|
raise SystemExit("Ollama cloud edge managed block replacement failed")
|
|
else:
|
|
blackbox_match = re.search(
|
|
r"(?ms)^ - job_name: ['\"]blackbox-http['\"]\n"
|
|
r".*?(?=^ - job_name:|\Z)",
|
|
text,
|
|
)
|
|
if blackbox_match is None:
|
|
raise SystemExit("blackbox-http job missing")
|
|
blackbox_job = blackbox_match.group(0)
|
|
if "provider: ollama_gcp_" in blackbox_job:
|
|
raise SystemExit("unmanaged Ollama cloud edge targets are ambiguous")
|
|
relabel_anchor = " relabel_configs:\n"
|
|
if blackbox_job.count(relabel_anchor) != 1:
|
|
raise SystemExit("blackbox-http relabel anchor missing or ambiguous")
|
|
patched_job = blackbox_job.replace(
|
|
relabel_anchor,
|
|
provider_block + relabel_anchor,
|
|
1,
|
|
)
|
|
text = text[: blackbox_match.start()] + patched_job + text[blackbox_match.end() :]
|
|
|
|
if text.count("job_name: 'alertmanager-runtime'") != 1:
|
|
raise SystemExit("alertmanager runtime job must exist exactly once")
|
|
if "targets: ['alertmanager:9093']" not in text:
|
|
raise SystemExit("canonical Alertmanager target missing")
|
|
if text.count("provider: ollama_gcp_a") != 1:
|
|
raise SystemExit("canonical GCP-A cloud edge target missing or ambiguous")
|
|
if text.count("provider: ollama_gcp_b") != 1:
|
|
raise SystemExit("canonical GCP-B cloud edge target missing or ambiguous")
|
|
if "192.168.0.111:11434" in text:
|
|
raise SystemExit("host111 must not be probed from retired host110 boundary")
|
|
candidate.write_text(text, encoding="utf-8")
|
|
PY
|
|
|
|
docker cp "${REMOTE_CANDIDATE}" \
|
|
"${PROMETHEUS_CONTAINER}:${CONTAINER_CANDIDATE}" >/dev/null
|
|
docker exec "${PROMETHEUS_CONTAINER}" promtool check config "${CONTAINER_CANDIDATE}"
|
|
|
|
CANDIDATE_SHA="$(sha256sum "${REMOTE_CANDIDATE}" | awk '{print $1}')"
|
|
test "$(sha256sum "${REMOTE_CONFIG}" | awk '{print $1}')" = "${SOURCE_SHA}"
|
|
printf 'check_receipt trace_id=%s run_id=%s work_item_id=%s mode=%s source_sha=%s candidate_sha=%s promtool=pass persistent_writes_performed=0 temporary_validation_artifact=true\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" "${MODE}" \
|
|
"${SOURCE_SHA}" "${CANDIDATE_SHA}"
|
|
|
|
if [ "${MODE}" = "--dry-run" ]; then
|
|
printf 'terminal trace_id=%s run_id=%s work_item_id=%s status=check_pass_no_persistent_write\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}"
|
|
exit 0
|
|
fi
|
|
|
|
cp -p "${REMOTE_CONFIG}" "${BACKUP_CONFIG}"
|
|
test "$(sha256sum "${BACKUP_CONFIG}" | awk '{print $1}')" = "${SOURCE_SHA}"
|
|
test "$(sha256sum "${REMOTE_CONFIG}" | awk '{print $1}')" = "${SOURCE_SHA}"
|
|
APPLY_STARTED=1
|
|
cp "${REMOTE_CANDIDATE}" "${REMOTE_CONFIG}"
|
|
test "$(sha256sum "${REMOTE_CONFIG}" | awk '{print $1}')" = "${CANDIDATE_SHA}"
|
|
curl -fsS -X POST "${PROMETHEUS_URL}/-/reload" >/dev/null
|
|
curl -fsS "${PROMETHEUS_URL}/-/ready" >/dev/null
|
|
printf 'execution_receipt trace_id=%s run_id=%s work_item_id=%s action=alertmanager_runtime_scrape_converged active_sha=%s backup=%s\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" "${CANDIDATE_SHA}" \
|
|
"${BACKUP_CONFIG}"
|
|
|
|
target_readback() {
|
|
curl -fsS "${PROMETHEUS_URL}/api/v1/targets?state=active" | python3 -c '
|
|
import json
|
|
import sys
|
|
|
|
targets = json.load(sys.stdin)["data"]["activeTargets"]
|
|
matches = [
|
|
target for target in targets
|
|
if target.get("labels", {}).get("job") == "alertmanager-runtime"
|
|
]
|
|
if len(matches) != 1:
|
|
print(f"{len(matches)}|missing|never")
|
|
else:
|
|
target = matches[0]
|
|
print("{}|{}|{}".format(
|
|
len(matches),
|
|
target.get("health", "unknown"),
|
|
target.get("lastScrape", "never"),
|
|
))
|
|
'
|
|
}
|
|
|
|
provider_target_readback() {
|
|
curl -fsS "${PROMETHEUS_URL}/api/v1/targets?state=active" | python3 -c '
|
|
import json
|
|
import sys
|
|
|
|
targets = json.load(sys.stdin)["data"]["activeTargets"]
|
|
providers = ("ollama_gcp_a", "ollama_gcp_b")
|
|
matches = {
|
|
provider: [
|
|
target
|
|
for target in targets
|
|
if target.get("labels", {}).get("job") == "blackbox-http"
|
|
and target.get("labels", {}).get("provider") == provider
|
|
and target.get("labels", {}).get("probe_origin") == "host110"
|
|
]
|
|
for provider in providers
|
|
}
|
|
ready = all(
|
|
len(matches[provider]) == 1
|
|
and matches[provider][0].get("lastScrape", "never") != "never"
|
|
for provider in providers
|
|
)
|
|
values = []
|
|
for provider in providers:
|
|
target = matches[provider][0] if len(matches[provider]) == 1 else {}
|
|
values.extend([
|
|
target.get("lastScrape", "never"),
|
|
target.get("health", "missing"),
|
|
])
|
|
print("|".join(["1" if ready else "0", *values]))
|
|
'
|
|
}
|
|
|
|
FIRST_SCRAPE=""
|
|
for attempt in $(seq 1 9); do
|
|
IFS='|' read -r count health last_scrape <<<"$(target_readback)"
|
|
printf 'target_probe trace_id=%s run_id=%s attempt=%s count=%s health=%s last_scrape=%s\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${attempt}" "${count}" "${health}" \
|
|
"${last_scrape}"
|
|
if [ "${count}" = 1 ] && [ "${health}" = up ] \
|
|
&& [ "${last_scrape}" != never ]; then
|
|
FIRST_SCRAPE="${last_scrape}"
|
|
break
|
|
fi
|
|
sleep 10
|
|
done
|
|
test -n "${FIRST_SCRAPE}"
|
|
|
|
FIRST_GCP_A_SCRAPE=""
|
|
FIRST_GCP_B_SCRAPE=""
|
|
for attempt in $(seq 1 9); do
|
|
IFS='|' read -r providers_ready gcp_a_scrape gcp_a_health \
|
|
gcp_b_scrape gcp_b_health <<<"$(provider_target_readback)"
|
|
printf 'provider_target_probe trace_id=%s run_id=%s attempt=%s ready=%s gcp_a_health=%s gcp_b_health=%s\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${attempt}" "${providers_ready}" \
|
|
"${gcp_a_health}" "${gcp_b_health}"
|
|
if [ "${providers_ready}" = 1 ]; then
|
|
FIRST_GCP_A_SCRAPE="${gcp_a_scrape}"
|
|
FIRST_GCP_B_SCRAPE="${gcp_b_scrape}"
|
|
break
|
|
fi
|
|
sleep 10
|
|
done
|
|
test -n "${FIRST_GCP_A_SCRAPE}"
|
|
test -n "${FIRST_GCP_B_SCRAPE}"
|
|
|
|
sleep 31
|
|
IFS='|' read -r count health SECOND_SCRAPE <<<"$(target_readback)"
|
|
test "${count}" = 1
|
|
test "${health}" = up
|
|
test "${SECOND_SCRAPE}" != "${FIRST_SCRAPE}"
|
|
IFS='|' read -r providers_ready SECOND_GCP_A_SCRAPE gcp_a_health \
|
|
SECOND_GCP_B_SCRAPE gcp_b_health <<<"$(provider_target_readback)"
|
|
test "${providers_ready}" = 1
|
|
test "${SECOND_GCP_A_SCRAPE}" != "${FIRST_GCP_A_SCRAPE}"
|
|
test "${SECOND_GCP_B_SCRAPE}" != "${FIRST_GCP_B_SCRAPE}"
|
|
|
|
SERIES_COUNT="$(curl -fsS --get \
|
|
--data-urlencode 'query=alertmanager_notification_requests_total{job="alertmanager-runtime",integration="webhook",receiver_contract="awoooi-webhook"}' \
|
|
"${PROMETHEUS_URL}/api/v1/query" | python3 -c '
|
|
import json
|
|
import sys
|
|
print(len(json.load(sys.stdin)["data"]["result"]))
|
|
')"
|
|
test "${SERIES_COUNT}" = 1
|
|
|
|
FAILED_SERIES_COUNT="$(curl -fsS --get \
|
|
--data-urlencode 'query=alertmanager_notification_requests_failed_total{job="alertmanager-runtime",integration="webhook",receiver_contract="awoooi-webhook"}' \
|
|
"${PROMETHEUS_URL}/api/v1/query" | python3 -c '
|
|
import json
|
|
import sys
|
|
print(len(json.load(sys.stdin)["data"]["result"]))
|
|
')"
|
|
test "${FAILED_SERIES_COUNT}" = 1
|
|
|
|
PROVIDER_SERIES_COUNT="$(curl -fsS --get \
|
|
--data-urlencode 'query=probe_success{job="blackbox-http",provider=~"ollama_gcp_a|ollama_gcp_b",probe_origin="host110"}' \
|
|
"${PROMETHEUS_URL}/api/v1/query" | python3 -c '
|
|
import json
|
|
import sys
|
|
print(len(json.load(sys.stdin)["data"]["result"]))
|
|
')"
|
|
test "${PROVIDER_SERIES_COUNT}" = 2
|
|
test "$(sha256sum "${REMOTE_CONFIG}" | awk '{print $1}')" = "${CANDIDATE_SHA}"
|
|
|
|
DEPLOY_VERIFIED=1
|
|
printf 'post_verifier trace_id=%s run_id=%s work_item_id=%s terminal=two_scrapes_up first=%s second=%s delivery_series_count=%s failed_series_count=%s provider_series_count=%s gcp_a_health=%s gcp_b_health=%s\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" "${FIRST_SCRAPE}" \
|
|
"${SECOND_SCRAPE}" "${SERIES_COUNT}" "${FAILED_SERIES_COUNT}" \
|
|
"${PROVIDER_SERIES_COUNT}" "${gcp_a_health}" "${gcp_b_health}"
|
|
printf 'terminal trace_id=%s run_id=%s work_item_id=%s status=completed backup=%s\n' \
|
|
"${TRACE_ID}" "${RUN_ID}" "${WORK_ITEM_ID}" "${BACKUP_CONFIG}"
|
|
REMOTE
|