alexandrev-tibco 2025-08-30 10:07:41 +02:00
parent da1082077e
commit dae66c2040
1 changed files with 127 additions and 2 deletions

View File

@ -2,6 +2,90 @@
set -e
SUMMARY_LINES=()
check_lxc_tailscale_issue() {
local vmid="$1"
pct exec "$vmid" -- sh -c '
if ! command -v tailscale >/dev/null 2>&1; then
echo tailscale-not-installed
exit 0
fi
if command -v systemctl >/dev/null 2>&1; then
systemctl is-active --quiet tailscaled || echo tailscale-down
elif command -v rc-service >/dev/null 2>&1 || [ -e /etc/init.d/tailscaled ]; then
rc-service tailscaled status >/dev/null 2>&1 || echo tailscale-down
fi
' 2>/dev/null | tr -d '\r' | head -n1
}
check_lxc_docker_issue() {
local vmid="$1"
pct exec "$vmid" -- sh -c '
DAEMON_JSON="/etc/docker/daemon.json"
if [ ! -f "$DAEMON_JSON" ]; then
echo docker-missing:daemon.json
exit 0
fi
if ! command -v jq >/dev/null 2>&1; then
echo docker-check-skipped-no-jq
exit 0
fi
missing=""
# metrics-addr
metrics=$(jq -r '."metrics-addr" // empty' "$DAEMON_JSON")
[ "$metrics" = "0.0.0.0:9023" ] || missing="${missing},metrics-addr"
# experimental
exp=$(jq -r '.experimental // false' "$DAEMON_JSON")
[ "$exp" = "true" ] || missing="${missing},experimental"
# hosts
has_unix=$(jq -r '.hosts // [] | index("unix:///var/run/docker.sock") | type' "$DAEMON_JSON" 2>/dev/null || echo null)
[ "$has_unix" = "number" ] || missing="${missing},hosts-unix"
has_tcp=$(jq -r '.hosts // [] | index("tcp://0.0.0.0:2375") | type' "$DAEMON_JSON" 2>/dev/null || echo null)
[ "$has_tcp" = "number" ] || missing="${missing},hosts-tcp"
if [ -z "$missing" ]; then
echo OK
else
echo docker-missing:${missing#,}
fi
' 2>/dev/null | tr -d '\r' | head -n1
}
collect_lxc_summary() {
local vmid="$1"
local name ip issues=""
name=$(pct exec "$vmid" -- sh -c "hostname -s 2>/dev/null || cat /etc/hostname 2>/dev/null || echo lxc-$vmid" 2>/dev/null | head -n1 | tr -d '\r')
ip=$(pct exec "$vmid" -- sh -c "(hostname -I 2>/dev/null || ip -4 -o addr show | awk '{print \\\$4}' | cut -d/ -f1) | tr ' ' '\n' | grep '^192\\.168\\.1\\.' | tr '\n' ' ' | sed 's/ *$//'" 2>/dev/null || true)
# Tailcale check
ts_issue=$(check_lxc_tailscale_issue "$vmid")
if [ -n "$ts_issue" ]; then
issues="${issues}${ts_issue}"
fi
# Docker config check
dk_issue=$(check_lxc_docker_issue "$vmid")
if [ -n "$dk_issue" ] && [ "$dk_issue" != "OK" ]; then
issues="${issues}${issues:+;}${dk_issue}"
fi
if [ -n "$issues" ]; then
SUMMARY_LINES+=("LXC $vmid | ${name:-lxc-$vmid} | ${ip:-no-ip-in-range} | ${issues}")
else
SUMMARY_LINES+=("LXC $vmid | ${name:-lxc-$vmid} | ${ip:-no-ip-in-range}")
fi
}
collect_vm_summary() {
local vmid="$1"
local name ip
name=$(qm config "$vmid" 2>/dev/null | awk '/^name:/{ $1=""; sub(/^ /,"",$0); print; exit }')
# Try modern guest cmd first
ip=$(qm guest cmd "$vmid" network-get-interfaces 2>/dev/null | awk -F '"' '/"ip-address"/ {print $4}' | grep '^192\\.168\\.1\\.' | tr '\n' ' ' | sed 's/ *$//' || true)
# Fallback to older agent command
if [ -z "$ip" ]; then
ip=$(qm agent "$vmid" network-get-interfaces 2>/dev/null | awk -F '"' '/"ip-address"/ {print $4}' | grep '^192\\.168\\.1\\.' | tr '\n' ' ' | sed 's/ *$//' || true)
fi
SUMMARY_LINES+=("VM $vmid | ${name:-vm-$vmid} | ${ip:-no-ip-in-range/agent-off}")
}
update_notes() {
local vmid="$1"
local type="$2"
@ -153,6 +237,39 @@ OVR
fi
}
wait_for_docker_ready() {
echo "[INFO] Esperando a que Docker esté operativo..."
READY=0
for i in $(seq 1 30); do
if docker info >/dev/null 2>&1; then
READY=1; break
fi
sleep 1
done
if [ $READY -eq 1 ]; then
echo "[INFO] Docker respondió a 'docker info'."
else
echo "[WARN] Docker no respondió tras el tiempo de espera."
fi
}
wait_for_endpoints() {
echo "[INFO] Esperando endpoints 0.0.0.0:2375 y 0.0.0.0:9023..."
EP=0
for i in $(seq 1 30); do
API_OK=0; MET_OK=0
if ss -lnt 2>/dev/null | grep -q ":2375 "; then API_OK=1; fi
if ss -lnt 2>/dev/null | grep -q ":9023 "; then MET_OK=1; fi
if [ $API_OK -eq 1 ] && [ $MET_OK -eq 1 ]; then EP=1; break; fi
sleep 1
done
if [ $EP -eq 1 ]; then
echo "[INFO] Endpoints confirmados."
else
echo "[WARN] Endpoints no confirmados tras el tiempo de espera."
fi
}
check_listeners() {
echo "[INFO] Comprobando puertos en escucha para Docker..."
if command -v ss >/dev/null 2>&1; then
@ -176,6 +293,8 @@ OVR
apply_systemd_override_if_needed
if [ ${JSON_CHANGED:-0} -eq 1 ] || [ ${OVERRIDE_APPLIED:-0} -eq 1 ]; then
restart_docker
wait_for_docker_ready
wait_for_endpoints
else
echo "[INFO] Configuración de Docker ya presente; no se requiere reinicio."
fi
@ -217,11 +336,17 @@ echo "[INFO] Iniciando gestión automática de LXC..."
# Iterar sobre LXC activos
for vmid in $(pct list | awk 'NR>1 {print $1}'); do
update_notes "$vmid" "LXC"
collect_lxc_summary "$vmid"
done
# VMs (sin integración por ahora)
# VMs: intentar obtener IPs vía QEMU Guest Agent (si disponible)
for vmid in $(qm list | awk 'NR>1 && $2 == "running" {print $1}'); do
echo "[INFO] Saltando VM $vmid (se requiere integración SSH para gestionar desde el host)"
collect_vm_summary "$vmid"
done
echo "[INFO] Resumen final (nombre e IP 192.168.1.*):"
for line in "${SUMMARY_LINES[@]}"; do
echo "$line"
done
echo "[INFO] Script completado."