diff --git a/decnet/web/db/models.py b/decnet/web/db/models.py index 2dbf7f7..44dd384 100644 --- a/decnet/web/db/models.py +++ b/decnet/web/db/models.py @@ -333,6 +333,7 @@ class SwarmHostView(BaseModel): class DeckyShardView(BaseModel): """One decky → host mapping, enriched with the host's identity for display.""" decky_name: str + decky_ip: Optional[str] = None # resolved from the stored DecnetConfig at read time host_uuid: str host_name: str host_address: str diff --git a/decnet/web/router/swarm_mgmt/api_list_deckies.py b/decnet/web/router/swarm_mgmt/api_list_deckies.py index 9ef9a48..2fe4b90 100644 --- a/decnet/web/router/swarm_mgmt/api_list_deckies.py +++ b/decnet/web/router/swarm_mgmt/api_list_deckies.py @@ -22,6 +22,15 @@ async def list_deckies( shards = await repo.list_decky_shards(host_uuid) hosts = {h["uuid"]: h for h in await repo.list_swarm_hosts()} + # IPs live on the stored DecnetConfig, not on the shard row. Resolve by + # decky_name — if the master rebooted without a config, the column falls + # back to "—" rather than blocking the list. + deploy_state = await repo.get_state("deployment") or {} + cfg_deckies = (deploy_state.get("config") or {}).get("deckies") or [] + ip_by_name: dict[str, str] = { + d.get("name"): d.get("ip") for d in cfg_deckies if d.get("name") + } + out: list[DeckyShardView] = [] for s in shards: if state and s.get("state") != state: @@ -29,6 +38,7 @@ async def list_deckies( host = hosts.get(s["host_uuid"], {}) out.append(DeckyShardView( decky_name=s["decky_name"], + decky_ip=ip_by_name.get(s["decky_name"]), host_uuid=s["host_uuid"], host_name=host.get("name") or "", host_address=host.get("address") or "", diff --git a/decnet_web/src/components/SwarmDeckies.tsx b/decnet_web/src/components/SwarmDeckies.tsx index 8ace856..4b49181 100644 --- a/decnet_web/src/components/SwarmDeckies.tsx +++ b/decnet_web/src/components/SwarmDeckies.tsx @@ -6,6 +6,7 @@ import { Boxes, PowerOff, RefreshCw } from 'lucide-react'; interface DeckyShard { decky_name: string; + decky_ip: string | null; host_uuid: string; host_name: string; host_address: string; @@ -87,9 +88,9 @@ const SwarmDeckies: React.FC = () => { Decky + IP State Services - Compose Updated @@ -98,9 +99,9 @@ const SwarmDeckies: React.FC = () => { {h.shards.map((s) => ( {s.decky_name} + {s.decky_ip || '—'} {s.state}{s.last_error ? ` — ${s.last_error}` : ''} {s.services.join(', ')} - {s.compose_hash ? s.compose_hash.slice(0, 8) : '—'} {new Date(s.updated_at).toLocaleString()}