#!/usr/bin/env bash
# Pre-checks, backup, install.sh --upgrade, then verification of Cilium + apps + smoke.
#   ./upgrade.sh final12 final11      (step A: Cilium 1.19.8, rollback target final11)
#   ./upgrade.sh final13 final12      (step B: Cilium 1.20.2, rollback target final12)
# Site runs firewalld ON: plain --upgrade, no --no-firewall, no --skip-preflight.
set -euo pipefail
NAME="${1:?usage: upgrade.sh <bundle-name> <rollback-name>}"; PREV="${2:?rollback bundle name}"
B="${B:-/data}"; K="/usr/local/bin/k3s kubectl"; D="$B/vodafone-idnow-$NAME"
step() { printf '\n==> %s  [%s]\n' "$*" "$(date -u +%H:%M:%S)"; }
[ -d "$D" ] || { echo "no $D - run ./download.sh $NAME first"; exit 1; }
[ -d "$B/vodafone-idnow-$PREV" ] || echo "!! rollback dir $B/vodafone-idnow-$PREV is missing - rollback would need ./download.sh $PREV first (or the final11-bootstrap.yaml fallback, see command.txt)"
cd "$D"
step "state BEFORE (all 14 must be Synced Healthy)"
$K -n argocd get applications
$K get netpol,cnp,ccnp -A 2>&1 | tail -1
$K -n default get secret website-license website-sodium emteria-tls customer-ca-bundle
echo "   cilium now: $($K -n kube-system get ds cilium -o jsonpath='{.spec.template.spec.containers[0].image}' | cut -d@ -f1)"
echo "   repo-server restarts (baseline): $($K -n argocd get pods -l app.kubernetes.io/name=argocd-repo-server --no-headers | awk '{print $4}')"
step "backup to /var/tmp (copy it off the node afterwards)"
./backup.sh /var/tmp | tail -3
step "preflight by hand (install.sh's own preflight dies on NTPSynchronized=no: this box syncs from the hypervisor clock)"
chronyc tracking 2>/dev/null | grep -E 'Reference ID|Stratum|System time|Leap status' | sed 's/^/   /'
echo "   NTPSynchronized=$(timedatectl show -p NTPSynchronized --value 2>/dev/null)   node clock: $(date -u +%FT%TZ)  <- compare with your laptop"
( sha256sum --quiet -c SHA256SUMS ) && echo "   - bundle SHA256SUMS ok"
# install.sh wants 2x the bundle under /var/lib, but on this box the registry blob store
# (/var/lib/emteria/registry) is a bind mount onto /data. Check each target on its own filesystem.
REG=/var/lib/emteria/registry; IMG=/var/lib/rancher/k3s/agent/images
reg_need=$(du -sm registry | cut -f1); reg_free=$(df -m "$REG" | awk 'NR==2{print $4}'); reg_fs=$(df "$REG" | awk 'NR==2{print $6}')
echo "   - registry blobs -> $REG (filesystem $reg_fs): free ${reg_free} MiB, copy needs up to ${reg_need} MiB (most blobs already exist)"
[ "$reg_free" -gt "$reg_need" ] || { echo "!! not enough space on $reg_fs for the blob copy"; exit 1; }
var_need=$(( $(du -sm k3s images | awk '{s+=$1} END{print s}') + 3072 )); var_free=$(df -m /var/lib | awk 'NR==2{print $4}')
echo "   - k3s images + containerd unpack of the new images -> /var/lib: free ${var_free} MiB, needs ~${var_need} MiB"
[ "$var_free" -gt "$var_need" ] || { echo "!! not enough space under /var/lib"; exit 1; }
echo "   - what uses the root disk:"; du -xsm /var/lib/rancher /var/lib/emteria /var/tmp /opt/local-path-provisioner /var/log 2>/dev/null | sort -n | awk '{printf "       %6d MiB  %s\n",$1,$2}'
systemctl is-active firewalld >/dev/null && echo "   - firewalld active" || echo "   - firewalld NOT active"
ip -4 route show default | grep -q default && echo "   - IPv4 default route present"
FLAGS="--skip-preflight"
step "about to run: ./install.sh --upgrade $FLAGS  (bundle $NAME, $(grep -oE 'cilium/cilium:v[0-9.]+' BUNDLE.txt))"
read -r -p "    proceed? [y/N] " a </dev/tty; [ "$a" = y ] || { echo "aborted"; exit 1; }
./install.sh --upgrade $FLAGS
step "waiting for k3s + Cilium rollout (1-3 min)"
sleep 45
for r in ds/cilium ds/cilium-envoy deploy/cilium-operator; do $K -n kube-system rollout status "$r" --timeout=300s; done
step "cilium-dbg status (expect version from bundle, KubeProxyReplacement True, Masquerading BPF, N/N controllers)"
$K -n kube-system exec ds/cilium -c cilium-agent -- cilium-dbg status | grep -E '^(Cilium:|KubeProxyReplacement|Masquerading|Controller Status|Cluster health|Modules Health|Proxy Status)'
$K -n kube-system exec ds/cilium -c cilium-agent -- cilium-dbg status --verbose | grep -iE '^\s*Socket LB:|NodePort:' | head -2
step "applications (want 14/14 Synced Healthy; waits up to 5 min)"
for i in $(seq 1 30); do n=$($K -n argocd get applications --no-headers | grep -cE 'Synced\s+Healthy' || true); [ "$n" -ge 14 ] && break; sleep 10; done
$K -n argocd get applications
step "smoke test (expected noise: one *-db-migrate Error WARN, repo-server restarts == baseline, mdm app restart = the k3s restart)"
$K -n default get secret customer-ca-bundle -o jsonpath='{.data.ca-certificates\.crt}' | base64 -d > /tmp/ca-bundle.pem
[ -s /tmp/ca-bundle.pem ] && CA=/tmp/ca-bundle.pem || CA=/var/lib/emteria/selfsigned/tls.crt
./smoke.sh --ca "$CA" || true
step "done. Rollback if needed:  $D/install.sh --rollback $B/vodafone-idnow-$PREV"
