Improve Doris service inventory health classification

This commit is contained in:
Fizzlepoof
2026-05-21 04:49:21 +00:00
parent 6d033eaaca
commit e3d2710ce5
4 changed files with 27 additions and 14 deletions

View File

@@ -2,7 +2,7 @@
All homelab services, their hosts, ports, and current status. All homelab services, their hosts, ports, and current status.
*Last updated: 2026-05-20* *Last updated: 2026-05-21*
## Shared Databases (PD) ## Shared Databases (PD)
@@ -19,7 +19,7 @@ All homelab services, their hosts, ports, and current status.
| Homepage | 3300 | http://pd:3300 | ✅ Active | | Homepage | 3300 | http://pd:3300 | ✅ Active |
| Dockhand | 3230 | http://pd:3230 | ✅ Active | | Dockhand | 3230 | http://pd:3230 | ✅ Active |
| Uptime Kuma | 3001 | http://pd:3001 | ✅ Active | | Uptime Kuma | 3001 | http://pd:3001 | ✅ Active |
| Gotify | 8443 | https://pd:8443 | ✅ Active | | Gotify | 8443 | https://gotify.paccoco.com | ✅ Active |
| Gitea | 3002 / 2222 | http://pd:3002 / http://10.5.1.6:3002 (SSH: `ssh://git@10.5.1.6:2222/<owner>/<repo>.git`) | ✅ Active | | Gitea | 3002 / 2222 | http://pd:3002 / http://10.5.1.6:3002 (SSH: `ssh://git@10.5.1.6:2222/<owner>/<repo>.git`) | ✅ Active |
| Shlink | 8087 | http://pd:8087 | ✅ Active | | Shlink | 8087 | http://pd:8087 | ✅ Active |
| Shlink Web Client | 8088 | http://pd:8088 | ✅ Active | | Shlink Web Client | 8088 | http://pd:8088 | ✅ Active |
@@ -34,13 +34,14 @@ All homelab services, their hosts, ports, and current status.
| OpenWebUI | PD | 8282 | ✅ Active | | OpenWebUI | PD | 8282 | ✅ Active |
| Qdrant | PD | 6333 (HTTP) / 6334 (gRPC) | ✅ Active | | Qdrant | PD | 6333 (HTTP) / 6334 (gRPC) | ✅ Active |
| Whisper (faster-whisper, CPU) | N.O.M.A.D. (10.5.1.16) | 8786 | ✅ Active | | Whisper (faster-whisper, CPU) | N.O.M.A.D. (10.5.1.16) | 8786 | ✅ Active |
| Whisper (faster-whisper, CUDA large-v3) | Rocinante (10.5.1.112) | 8787 | ✅ Active | | Whisper (faster-whisper, CUDA large-v3) | Rocinante (10.5.1.112) | 8787 | ⚠️ Unreachable from N.O.M.A.D. during 2026-05-21 Doris validation |
| SearXNG | PD | 8888 | ✅ Active | | SearXNG | PD | 8888 | ✅ Active |
| OpenClaw | PD | 18789 | ✅ Active |
| Ollama — light tier | PD (10.5.1.6) | 11434 | ✅ Active | | Ollama — light tier | PD (10.5.1.6) | 11434 | ✅ Active |
| Ollama — heavy tier | Rocinante (10.5.1.112) | 11434 | ✅ Active | | Ollama — heavy tier | Rocinante (10.5.1.112) | 11434 | ⚠️ Unreachable from N.O.M.A.D. during 2026-05-21 Doris validation |
| Reranker (TEI) | Serenity (10.5.1.5) | 9787 | ✅ Active | | Reranker (TEI) | Serenity (10.5.1.5) | 9787 | ✅ Active |
OpenClaw is no longer treated as an active PD service in the operator inventory. Only helper-artifact references remain under the school-intake planning docs.
## Media (PD) ## Media (PD)
| Service | Port | Status | | Service | Port | Status |
@@ -68,7 +69,7 @@ All homelab services, their hosts, ports, and current status.
| Service | Port | Status | | Service | Port | Status |
|---------|------|--------| |---------|------|--------|
| Home Assistant | 8123 | ✅ Active | | Home Assistant | 8123 | ✅ Active; Doris still treats this as manual until a stable operator-safe route exists from N.O.M.A.D. |
| Kima Hub | 3333 | ✅ Active | | Kima Hub | 3333 | ✅ Active |
## Monitoring (PD) ## Monitoring (PD)
@@ -96,7 +97,9 @@ All homelab services, their hosts, ports, and current status.
## Game Servers (N.O.M.A.D. — 10.5.1.16) ## Game Servers (N.O.M.A.D. — 10.5.1.16)
| Service | Notes | | Service | Port | URL | Status | Notes |
|---------|-------| |---------|------|-----|--------|-------|
| Pelican / Wings | Game server management panel | | Pelican Panel | 80 / 443 | https://panel.paccoco.com | ✅ Active | For local health/probe use `http://10.5.1.16:8080`; local TLS path is self-signed and `panel.paccoco.com` resolves to `127.0.0.1` on N.O.M.A.D. |
| Minecraft | Managed via Pelican | | Wings Node API | 8443 / 443 | https://node1.paccoco.com | ✅ Active | `401` from the public endpoint is expected and means the daemon is reachable/auth-protected |
| Minecraft Server 25565 | 25565/tcp+udp | managed via Pelican | ✅ Active | Wings-managed Java server |
| Minecraft Server 25566 | 25566/tcp+udp | managed via Pelican | ✅ Active | Wings-managed Java/NeoForge server |

View File

@@ -309,6 +309,7 @@ Removing them should not be treated as a Project N.O.M.A.D. change or a Wings/Pe
- `panel.paccoco.com` → `127.0.0.1` in `/etc/hosts` for NAT loopback - `panel.paccoco.com` → `127.0.0.1` in `/etc/hosts` for NAT loopback
- nginx on 80 and 443 (self-signed cert) for local Wings → Panel - nginx on 80 and 443 (self-signed cert) for local Wings → Panel
- Wings uses `--ignore-certificate-errors` for self-signed cert - Wings uses `--ignore-certificate-errors` for self-signed cert
- For local operator-safe Pelican health checks, use `http://10.5.1.16:8080` instead of the self-signed TLS path; it redirects cleanly to `/home` without tripping certificate validation.
- Pangolin resource `node1.paccoco.com` has auth disabled - Pangolin resource `node1.paccoco.com` has auth disabled
## Known Quirks ## Known Quirks

View File

@@ -25,6 +25,12 @@ Ollama runs on port `11434` and hosts the large-model ("heavy") tier.
> **LiteLLM tier:** Rocinante is the **"heavy"** tier in LiteLLM `config.yaml`. > **LiteLLM tier:** Rocinante is the **"heavy"** tier in LiteLLM `config.yaml`.
> Heavy-tier requests from OpenWebUI and n8n route to `http://10.5.1.112:11434`. > Heavy-tier requests from OpenWebUI and n8n route to `http://10.5.1.112:11434`.
## Current operational note
- During Doris validation from N.O.M.A.D. on 2026-05-21, `10.5.1.112` did not answer ping and did not accept connections on `11434` or `8787`.
- Treat Rocinante-hosted Ollama heavy-tier traffic and CUDA Whisper as currently unreachable from N.O.M.A.D. until host/network reachability is restored.
- Re-validate from N.O.M.A.D. with `curl http://10.5.1.112:11434/api/tags` and `curl http://10.5.1.112:8787/health` after recovery.
## Notes ## Notes
- No SSH config needed for routine use — Ollama API is accessed over LAN only - No SSH config needed for routine use — Ollama API is accessed over LAN only

View File

@@ -69,7 +69,6 @@ SERVICE_DIRECTORY = [
{'name': 'Qdrant', 'url': 'http://10.5.1.6:6333/dashboard', 'health_url': 'http://10.5.1.6:6333/healthz', 'purpose': 'Vector store for Project NOMAD and local retrieval systems.', 'exposure': 'LAN', 'state': 'ok', 'host': 'PD', 'port': '6333/6334'}, {'name': 'Qdrant', 'url': 'http://10.5.1.6:6333/dashboard', 'health_url': 'http://10.5.1.6:6333/healthz', 'purpose': 'Vector store for Project NOMAD and local retrieval systems.', 'exposure': 'LAN', 'state': 'ok', 'host': 'PD', 'port': '6333/6334'},
{'name': 'Whisper (CPU)', 'url': 'http://10.5.1.16:8786/docs', 'health_url': 'http://10.5.1.16:8786/health', 'purpose': 'Fast local CPU transcription endpoint on NOMAD.', 'exposure': 'LAN', 'state': 'ok', 'host': 'NOMAD', 'port': '8786'}, {'name': 'Whisper (CPU)', 'url': 'http://10.5.1.16:8786/docs', 'health_url': 'http://10.5.1.16:8786/health', 'purpose': 'Fast local CPU transcription endpoint on NOMAD.', 'exposure': 'LAN', 'state': 'ok', 'host': 'NOMAD', 'port': '8786'},
{'name': 'Whisper (CUDA)', 'url': 'http://10.5.1.112:8787/docs', 'health_url': 'http://10.5.1.112:8787/health', 'purpose': 'Heavy GPU transcription endpoint on Rocinante.', 'exposure': 'LAN', 'state': 'ok', 'host': 'ROCINANTE', 'port': '8787'}, {'name': 'Whisper (CUDA)', 'url': 'http://10.5.1.112:8787/docs', 'health_url': 'http://10.5.1.112:8787/health', 'purpose': 'Heavy GPU transcription endpoint on Rocinante.', 'exposure': 'LAN', 'state': 'ok', 'host': 'ROCINANTE', 'port': '8787'},
{'name': 'OpenClaw', 'url': 'http://10.5.1.6:18789', 'health_url': 'http://10.5.1.6:18789', 'purpose': 'Legacy local helper/web surface documented in the AI stack.', 'exposure': 'LAN', 'state': 'attention', 'host': 'PD', 'port': '18789'},
{'name': 'SearXNG', 'url': 'http://10.5.1.6:8888', 'health_url': 'http://10.5.1.6:8888', 'purpose': 'Private metasearch box for research and agent-side browsing.', 'exposure': 'LAN', 'state': 'ok', 'host': 'PD', 'port': '8888'}, {'name': 'SearXNG', 'url': 'http://10.5.1.6:8888', 'health_url': 'http://10.5.1.6:8888', 'purpose': 'Private metasearch box for research and agent-side browsing.', 'exposure': 'LAN', 'state': 'ok', 'host': 'PD', 'port': '8888'},
{'name': 'Ollama — light tier', 'url': 'http://10.5.1.6:11434/api/tags', 'health_url': 'http://10.5.1.6:11434/api/tags', 'purpose': 'PD light-tier Ollama runtime backing cheaper/default model paths.', 'exposure': 'LAN', 'state': 'ok', 'host': 'PD', 'port': '11434'}, {'name': 'Ollama — light tier', 'url': 'http://10.5.1.6:11434/api/tags', 'health_url': 'http://10.5.1.6:11434/api/tags', 'purpose': 'PD light-tier Ollama runtime backing cheaper/default model paths.', 'exposure': 'LAN', 'state': 'ok', 'host': 'PD', 'port': '11434'},
{'name': 'Ollama — heavy tier', 'url': 'http://10.5.1.112:11434/api/tags', 'health_url': 'http://10.5.1.112:11434/api/tags', 'purpose': 'Rocinante heavy-tier Ollama runtime for larger model requests.', 'exposure': 'LAN', 'state': 'ok', 'host': 'ROCINANTE', 'port': '11434'}, {'name': 'Ollama — heavy tier', 'url': 'http://10.5.1.112:11434/api/tags', 'health_url': 'http://10.5.1.112:11434/api/tags', 'purpose': 'Rocinante heavy-tier Ollama runtime for larger model requests.', 'exposure': 'LAN', 'state': 'ok', 'host': 'ROCINANTE', 'port': '11434'},
@@ -125,7 +124,7 @@ SERVICE_DIRECTORY = [
{ {
'group': 'Game Servers', 'group': 'Game Servers',
'items': [ 'items': [
{'name': 'Pelican Panel', 'url': 'https://panel.paccoco.com', 'health_url': 'https://panel.paccoco.com', 'purpose': 'Game-server management panel for the NOMAD Wings stack.', 'exposure': 'PUBLIC', 'state': 'ok', 'host': 'NOMAD', 'port': '443'}, {'name': 'Pelican Panel', 'url': 'https://panel.paccoco.com', 'health_url': 'http://10.5.1.16:8080', 'purpose': 'Game-server management panel for the NOMAD Wings stack.', 'exposure': 'PUBLIC', 'state': 'ok', 'host': 'NOMAD', 'port': '443'},
{'name': 'Wings Node API', 'url': 'https://node1.paccoco.com', 'health_url': 'https://node1.paccoco.com', 'purpose': 'Public-facing Wings node endpoint; 401 means the daemon is reachable and auth-protected.', 'exposure': 'PUBLIC', 'state': 'ok', 'host': 'NOMAD', 'port': '8443 / 443'}, {'name': 'Wings Node API', 'url': 'https://node1.paccoco.com', 'health_url': 'https://node1.paccoco.com', 'purpose': 'Public-facing Wings node endpoint; 401 means the daemon is reachable and auth-protected.', 'exposure': 'PUBLIC', 'state': 'ok', 'host': 'NOMAD', 'port': '8443 / 443'},
{'name': 'Minecraft Server 25565', 'url': '', 'purpose': 'First Wings-managed Java server on NOMAD.', 'exposure': 'PUBLIC', 'state': 'ok', 'host': 'NOMAD', 'port': '25565/tcp+udp', 'tcp_host': '10.5.1.16', 'tcp_port': 25565, 'badge': 'Healthy'}, {'name': 'Minecraft Server 25565', 'url': '', 'purpose': 'First Wings-managed Java server on NOMAD.', 'exposure': 'PUBLIC', 'state': 'ok', 'host': 'NOMAD', 'port': '25565/tcp+udp', 'tcp_host': '10.5.1.16', 'tcp_port': 25565, 'badge': 'Healthy'},
{'name': 'Minecraft Server 25566', 'url': '', 'purpose': 'Second Wings-managed Java/NeoForge server on NOMAD.', 'exposure': 'PUBLIC', 'state': 'ok', 'host': 'NOMAD', 'port': '25566/tcp+udp', 'tcp_host': '10.5.1.16', 'tcp_port': 25566, 'badge': 'Healthy'}, {'name': 'Minecraft Server 25566', 'url': '', 'purpose': 'Second Wings-managed Java/NeoForge server on NOMAD.', 'exposure': 'PUBLIC', 'state': 'ok', 'host': 'NOMAD', 'port': '25566/tcp+udp', 'tcp_host': '10.5.1.16', 'tcp_port': 25566, 'badge': 'Healthy'},
@@ -1621,7 +1620,9 @@ def check_service_health(item:dict[str,Any])->dict[str,str]:
return {'state':'ok','badge':str(item.get('badge') or 'Healthy'),'detail':f'tcp {int(tcp_port)} open · {elapsed} ms'} return {'state':'ok','badge':str(item.get('badge') or 'Healthy'),'detail':f'tcp {int(tcp_port)} open · {elapsed} ms'}
except Exception as e: except Exception as e:
elapsed=max(1,int((time.time()-started)*1000)) elapsed=max(1,int((time.time()-started)*1000))
return {'state':'warn','badge':'Down','detail':f'tcp {int(tcp_port)} {type(e).__name__} · {elapsed} ms'} detail=str(e).strip()
suffix=f' · {detail}' if detail else ''
return {'state':'warn','badge':'Down','detail':f'tcp {int(tcp_port)} {type(e).__name__} · {elapsed} ms{suffix}'}
finally: finally:
sock.close() sock.close()
target=str(item.get('health_url') or item.get('url') or '').strip() target=str(item.get('health_url') or item.get('url') or '').strip()
@@ -1654,7 +1655,9 @@ def check_service_health(item:dict[str,Any])->dict[str,str]:
return {'state':'attention','badge':'Degraded','detail':f'{code} · {elapsed} ms'} return {'state':'attention','badge':'Degraded','detail':f'{code} · {elapsed} ms'}
except Exception as e: except Exception as e:
elapsed=max(1,int((time.time()-started)*1000)) elapsed=max(1,int((time.time()-started)*1000))
return {'state':'warn','badge':'Down','detail':f'{type(e).__name__} · {elapsed} ms'} detail=str(e).strip()
suffix=f' · {detail}' if detail else ''
return {'state':'warn','badge':'Down','detail':f'{type(e).__name__} · {elapsed} ms{suffix}'}
def service_group_state(items:list[dict[str,Any]])->str: def service_group_state(items:list[dict[str,Any]])->str: