Files
clawdbot/scripts/homelab-status
William Valentin 2c3d6afcdd Add workspace utility scripts
- llm: Local LLM wrapper for llama-swap
- homelab-status: Quick K8s/cluster health check
- calc: Python/JS REPL for quick calculations
- transcribe: Whisper audio transcription wrapper

Added to fish PATH.
2026-01-26 22:53:52 -08:00

136 lines
4.6 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Quick homelab status check
# Usage: homelab-status [--full]
set -e
FULL=false
[[ "$1" == "--full" || "$1" == "-f" ]] && FULL=true
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
ok() { echo -e "${GREEN}${NC} $1"; }
warn() { echo -e "${YELLOW}${NC} $1"; }
fail() { echo -e "${RED}${NC} $1"; }
info() { echo -e "${BLUE}${NC} $1"; }
echo "═══════════════════════════════════════"
echo " 🏠 HOMELAB STATUS"
echo "═══════════════════════════════════════"
echo ""
# K8s Cluster
echo "☸️ KUBERNETES"
echo "───────────────────────────────────────"
if ! kubectl cluster-info &>/dev/null; then
fail "Cluster unreachable"
else
# Nodes
NODES_TOTAL=$(kubectl get nodes --no-headers 2>/dev/null | wc -l)
NODES_READY=$(kubectl get nodes --no-headers 2>/dev/null | grep -c " Ready" || echo 0)
if [[ "$NODES_READY" == "$NODES_TOTAL" ]]; then
ok "Nodes: $NODES_READY/$NODES_TOTAL Ready"
else
warn "Nodes: $NODES_READY/$NODES_TOTAL Ready"
fi
# Pods
PODS_RUNNING=$(kubectl get pods -A --no-headers 2>/dev/null | grep -c "Running" || echo 0)
PODS_NOT_RUNNING=$(kubectl get pods -A --no-headers 2>/dev/null | grep -cvE "Running|Completed" || echo 0)
if [[ "$PODS_NOT_RUNNING" == "0" ]]; then
ok "Pods: $PODS_RUNNING Running"
else
warn "Pods: $PODS_RUNNING Running, $PODS_NOT_RUNNING not ready"
fi
# Show failed pods if any
if [[ "$PODS_FAILED" != "0" ]] || $FULL; then
kubectl get pods -A --no-headers 2>/dev/null | grep -E "(Error|CrashLoop|Failed|Pending)" | head -5 | while read -r line; do
echo " $line"
done
fi
fi
echo ""
# Alertmanager
echo "🚨 ALERTS"
echo "───────────────────────────────────────"
ALERTMANAGER_URL="http://alertmanager.monitoring.192.168.153.240.nip.io"
ALERTS=$(curl -sf "$ALERTMANAGER_URL/api/v2/alerts?active=true&silenced=false" 2>/dev/null || echo "[]")
ALERT_COUNT=$(echo "$ALERTS" | jq 'length' 2>/dev/null || echo "?")
if [[ "$ALERT_COUNT" == "0" ]]; then
ok "No active alerts"
elif [[ "$ALERT_COUNT" == "?" ]]; then
warn "Alertmanager unreachable"
else
warn "$ALERT_COUNT active alert(s)"
echo "$ALERTS" | jq -r '.[].labels.alertname' 2>/dev/null | head -5 | while read -r alert; do
echo " - $alert"
done
fi
echo ""
# Key Services
echo "🔌 SERVICES"
echo "───────────────────────────────────────"
check_service() {
local name="$1"
local url="$2"
if curl -sf --max-time 3 "$url" >/dev/null 2>&1; then
ok "$name"
else
fail "$name"
fi
}
check_service "Grafana" "http://grafana.monitoring.192.168.153.240.nip.io/api/health"
check_service "ArgoCD" "https://argocd.taildb3494.ts.net" 2>/dev/null || check_service "ArgoCD" "http://argocd-server.argocd.svc:80" 2>/dev/null || warn "ArgoCD (via Tailscale only)"
check_service "Longhorn" "http://ui.longhorn-system.192.168.153.240.nip.io"
# Ollama (homelab)
if curl -sf --max-time 3 "http://100.85.116.57:11434/api/tags" >/dev/null 2>&1; then
ok "Ollama (homelab)"
else
warn "Ollama (homelab) - unreachable"
fi
echo ""
# Local LLM
echo "🤖 LOCAL LLM"
echo "───────────────────────────────────────"
if curl -sf "http://127.0.0.1:8080/health" >/dev/null 2>&1; then
ok "llama-swap running"
MODELS=$(curl -s "http://127.0.0.1:8080/v1/models" | jq -r '.data[].id' 2>/dev/null | tr '\n' ', ' | sed 's/,$//')
info "Models: $MODELS"
else
warn "llama-swap not running"
info "Start: systemctl --user start llama-swap"
fi
echo ""
# Storage (if full)
if $FULL; then
echo "💾 STORAGE"
echo "───────────────────────────────────────"
kubectl get pvc -A --no-headers 2>/dev/null | head -10 | while read -r ns name status vol cap mode class age; do
if [[ "$status" == "Bound" ]]; then
ok "$ns/$name ($cap)"
else
warn "$ns/$name - $status"
fi
done
echo ""
fi
echo "═══════════════════════════════════════"
echo " $(date '+%Y-%m-%d %H:%M:%S %Z')"
echo "═══════════════════════════════════════"