Add server hardware/network detail view with Proxmox sync and agent reporting
Servers & Tasks only tracked scheduled tasks — there was no overview of the servers themselves and no way to see CPU/RAM/disk/IP info. Add a clickable server overview (visible to every role, not just admins) that opens a per-server detail page. - servers table gains an agent-reported hardware/network snapshot (IPs, CPU model/cores/load, memory, disks) and an optional link to a Proxmox VM/LXC (integration + node + guest type + vmid). - Proxmox adapter gains getGuestDetail(): live cores/memory/disk from /config, live cpu/mem/uptime from /status/current, and IPs (LXC net config directly, QEMU via a best-effort guest-agent call that degrades gracefully when the agent isn't installed). - New GET /api/servers/:id/detail combines whichever hardware source applies (live Proxmox vs. last agent report) with a DNS reverse-lookup against the DNS module's own record cache, so matching hostnames show up next to each IP. New PATCH /api/servers/:id manages the Proxmox link. - agent/linux/report-tasks.sh now also collects and reports IPs, CPU/memory/disk info on every check-in (load-average-based CPU number, not instantaneous, to keep the agent a cheap oneshot). - Extracted the per-server task table into a shared ServerTaskTable component so the all-servers view and the new detail page render tasks identically. Verified server-side end-to-end against the real dev server (agent report -> detail endpoint -> DNS match) and the Proxmox adapter against a mock HTTPS server covering LXC/QEMU config parsing and the guest-agent-unavailable fallback. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1f0e6a9d4c
commit
b9409d3095
15 files changed
+2206
-140
No files matched your search
@@ -173,16 +173,67 @@ collect_systemd_timers() {
|
||||
done < <(jq -c '.[]' <<<"$timers_json")
|
||||
}
|
||||
|
||||
collect_system_info() {
|
||||
local ip_json="[]"
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
ip_json=$(ip -4 -o addr show scope global 2>/dev/null \
|
||||
| awk '{print $4}' | cut -d/ -f1 \
|
||||
| jq -R -s -c 'split("\n") | map(select(length > 0))')
|
||||
fi
|
||||
|
||||
local cpu_model="" cpu_cores=0 cpu_load_percent="null"
|
||||
cpu_model=$(grep -m1 "model name" /proc/cpuinfo 2>/dev/null | cut -d: -f2- | sed 's/^ *//')
|
||||
cpu_cores=$(nproc 2>/dev/null || echo 0)
|
||||
if [[ -r /proc/loadavg && "$cpu_cores" -gt 0 ]]; then
|
||||
local load1
|
||||
load1=$(awk '{print $1}' /proc/loadavg)
|
||||
cpu_load_percent=$(awk -v l="$load1" -v c="$cpu_cores" 'BEGIN { printf "%.1f", (l/c)*100 }')
|
||||
fi
|
||||
|
||||
local mem_total=0 mem_used=0
|
||||
if command -v free >/dev/null 2>&1; then
|
||||
read -r mem_total mem_used < <(free -b | awk '/^Mem:/ {print $2, $3}')
|
||||
fi
|
||||
|
||||
local disks_json="[]"
|
||||
if command -v df >/dev/null 2>&1; then
|
||||
disks_json=$(df -B1 --output=target,size,used -x tmpfs -x devtmpfs -x squashfs -x overlay 2>/dev/null \
|
||||
| tail -n +2 \
|
||||
| awk '{print $1"\t"$2"\t"$3}' \
|
||||
| jq -R -s -c '
|
||||
split("\n") | map(select(length > 0) | split("\t")) |
|
||||
map({mount: .[0], size_bytes: (.[1]|tonumber), used_bytes: (.[2]|tonumber)})
|
||||
')
|
||||
fi
|
||||
|
||||
SYSTEM_JSON=$(jq -n \
|
||||
--argjson ip_addresses "$ip_json" \
|
||||
--arg cpu_model "$cpu_model" \
|
||||
--argjson cpu_cores "${cpu_cores:-0}" \
|
||||
--argjson cpu_load_percent "$cpu_load_percent" \
|
||||
--argjson mem_total_bytes "${mem_total:-0}" \
|
||||
--argjson mem_used_bytes "${mem_used:-0}" \
|
||||
--argjson disks "$disks_json" \
|
||||
'{
|
||||
ip_addresses: $ip_addresses,
|
||||
cpu: { model: $cpu_model, cores: $cpu_cores, load_percent: $cpu_load_percent },
|
||||
memory: { total_bytes: $mem_total_bytes, used_bytes: $mem_used_bytes },
|
||||
disks: $disks
|
||||
}')
|
||||
}
|
||||
|
||||
collect_cron
|
||||
collect_systemd_timers
|
||||
collect_system_info
|
||||
|
||||
HOSTNAME_VALUE=$(hostname -f 2>/dev/null || hostname)
|
||||
PAYLOAD=$(jq -n \
|
||||
--arg hostname "$HOSTNAME_VALUE" \
|
||||
--arg os_type "linux" \
|
||||
--arg reported_at "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
|
||||
--argjson system "$SYSTEM_JSON" \
|
||||
--argjson tasks "$TASKS_JSON" \
|
||||
'{hostname: $hostname, os_type: $os_type, reported_at: $reported_at, tasks: $tasks}')
|
||||
'{hostname: $hostname, os_type: $os_type, reported_at: $reported_at, system: $system, tasks: $tasks}')
|
||||
|
||||
if [[ "$DRY_RUN" == "1" ]]; then
|
||||
echo "$PAYLOAD" | jq .
|
||||
|
||||
Reference in new issue
Block a user