Files
cozystack/hack/cozyreport-summary.sh
Myasnikov Daniil a98b717acd feat(cozyreport): add summary.txt at archive root
A 50MB tarball with 200 directories is opaque on first contact.
summary.txt at the root surfaces 'what is broken right now' — non-Ready
HRs, ImagePullBackOff pods, OOMKilled events, cert-manager state,
Flux Source health, storage binding, node pressure — so triage starts
with one file instead of a directory tree dive.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-27 23:14:40 +05:00

67 lines
2.3 KiB
Bash
Executable File

#!/bin/sh
# Emit a human-readable summary of "what is broken" to a single file.
# Reads the live cluster (not the report dir) so it can use kubectl JSONPath.
# Usage: cozyreport-summary.sh > summary.txt
set -eu
echo "# Cozystack E2E Diagnostic Summary"
echo "Generated: $(date -Iseconds)"
echo
echo "## HelmReleases not Ready"
echo
kubectl get hr -A --no-headers 2>/dev/null \
| awk '$4 != "True" {printf " %s/%s — %s\n", $1, $2, $5}' \
| head -40
echo
echo "## Pods not Running/Succeeded"
echo
kubectl get pod -A --no-headers 2>/dev/null \
| awk '$4 !~ /Running|Succeeded|Completed/ {printf " %s/%s — %s (restarts=%s, age=%s)\n", $1, $2, $4, $5, $6}' \
| head -40
echo
echo "## ImagePullBackOff / ErrImagePull"
echo
kubectl get pod -A --no-headers 2>/dev/null \
| awk '$4 ~ /ImagePullBackOff|ErrImagePull/ {printf " %s/%s — %s\n", $1, $2, $4}'
echo
echo "## OOMKilled in last 30 min"
echo
kubectl get events -A --field-selector reason=OOMKilling --sort-by=.lastTimestamp 2>/dev/null \
| tail -20
echo
echo "## Recent Warning events (top 30)"
echo
kubectl get events -A --field-selector type=Warning --sort-by=.lastTimestamp 2>/dev/null \
| tail -30
echo
echo "## cert-manager: Certificates not Ready"
echo
if kubectl get crd certificates.cert-manager.io >/dev/null 2>&1; then
kubectl get certificates.cert-manager.io -A --no-headers 2>/dev/null \
| awk '$3 != "True" {printf " %s/%s — Ready=%s\n", $1, $2, $3}'
fi
echo
echo "## Flux Sources not Ready"
echo
for kind in helmrepositories.source.toolkit.fluxcd.io ocirepositories.source.toolkit.fluxcd.io gitrepositories.source.toolkit.fluxcd.io; do
kubectl get $kind -A --no-headers 2>/dev/null \
| awk -v k="${kind%%.*}" '$4 != "True" {printf " %s %s/%s — Ready=%s\n", k, $1, $2, $4}'
done
echo
echo "## Storage: PVCs not Bound, PVs not Bound"
echo
kubectl get pvc -A --no-headers 2>/dev/null | awk '$3 != "Bound" {printf " PVC %s/%s — %s\n", $1, $2, $3}'
kubectl get pv --no-headers 2>/dev/null | awk '$5 != "Bound" {printf " PV %s — %s\n", $1, $5}'
echo
echo "## Node Conditions"
kubectl get nodes -o custom-columns=NAME:.metadata.name,READY:.status.conditions[?\(@.type==\"Ready\"\)].status,DISK:.status.conditions[?\(@.type==\"DiskPressure\"\)].status,MEM:.status.conditions[?\(@.type==\"MemoryPressure\"\)].status 2>/dev/null