From 36a686d9534de79f51d1cc8f2c29f525a3a6a444 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 20 May 2026 21:28:03 +0200 Subject: [PATCH] inventory: real mesh state per host (no more placeholder netbird FQDNs) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit against actual netbird+tailscale peer lists: - hubris is the only LXC-host on Netbird; only workstations + hubris have netbird entries - 10 LXCs+VMs have real Tailscale FQDNs: apps, jellyfin, paperless, gitea, nextcloud, elementsynapse, sophia, mule-images→muleimage, arriman→arr, haos→homeassistant - 7 hosts are LAN-only (no mesh block): nfs-export, caddy, claudio-bot, authentik, plato, mule-photos-new, zimaos - mac-mini's netbird FQDN corrected to the actual peer name (mac-mini-234-17.netbird.selfhosted) Also: bin/homelab host_address() now prefers lan_ip first — universally reachable from any LAN client and from any Netbird peer via the 192.168.8.0/24 network resource routed through hubris. Mesh FQDNs are fallbacks for roaming workstations without a fixed lan_ip. This makes 'homelab status' from republic show all backends 'ok' instead of falsely reporting them 'down' against unresolvable netbird FQDNs. Co-Authored-By: Claude Opus 4.7 (1M context) --- bin/homelab | 25 +++++++++----- hosts/apps.yaml | 3 +- hosts/arriman.yaml | 4 +-- hosts/authentik.yaml | 3 -- hosts/caddy.yaml | 3 -- hosts/claudio-bot.yaml | 3 -- hosts/elementsynapse.yaml | 4 +-- hosts/gitea.yaml | 4 +-- hosts/haos.yaml | 4 +-- hosts/jellyfin.yaml | 4 +-- hosts/mac-mini.yaml | 2 +- hosts/mule-images.yaml | 4 +-- hosts/mule-photos-new.yaml | 3 -- hosts/nextcloud.yaml | 4 +-- hosts/nfs-export.yaml | 3 -- hosts/paperless.yaml | 4 +-- hosts/plato.yaml | 3 -- hosts/republic-laptop.yaml | 1 - hosts/sophia.yaml | 4 +-- hosts/zimaos.yaml | 3 -- inventory.yaml | 71 +++++++++++--------------------------- 21 files changed, 56 insertions(+), 103 deletions(-) diff --git a/bin/homelab b/bin/homelab index 9ac9a8a..48d6c9f 100755 --- a/bin/homelab +++ b/bin/homelab @@ -55,18 +55,25 @@ def host(name: str) -> dict: def host_address(name: str, prefer_lan: bool = False) -> str: + """Best-effort single address for `name`. + + Preference order is lan_ip first because: + - From any LAN client it's a direct route. + - From any Netbird peer it's routed through hubris's + 192.168.8.0/24 network resource. + - From any Tailscale peer with subnet routing it works too. + Mesh FQDNs are fallbacks for hosts without a lan_ip (e.g. roaming + workstations). + """ h = host(name) mesh = h.get("mesh", {}) - candidates = [] - if prefer_lan and h.get("lan_ip"): - candidates.append(h["lan_ip"]) - candidates.extend([ - mesh.get("netbird", {}).get("fqdn") if isinstance(mesh.get("netbird"), dict) else None, - mesh.get("netbird", {}).get("ip") if isinstance(mesh.get("netbird"), dict) else None, + nb = mesh.get("netbird") if isinstance(mesh.get("netbird"), dict) else {} + ts = mesh.get("tailscale") if isinstance(mesh.get("tailscale"), dict) else {} + candidates = [ h.get("lan_ip"), - mesh.get("tailscale", {}).get("fqdn") if isinstance(mesh.get("tailscale"), dict) else None, - mesh.get("tailscale", {}).get("ip") if isinstance(mesh.get("tailscale"), dict) else None, - ]) + nb.get("fqdn"), nb.get("ip"), + ts.get("fqdn"), ts.get("ip"), + ] for c in candidates: if c: return c diff --git a/hosts/apps.yaml b/hosts/apps.yaml index 0a64cc3..4a47624 100644 --- a/hosts/apps.yaml +++ b/hosts/apps.yaml @@ -9,10 +9,9 @@ host: hubris pve_id: 105 lan_ip: 192.168.8.205 mesh: - netbird: - fqdn: apps.netbird.selfhosted tailscale: ip: 100.121.171.122 + fqdn: apps mesh_globals: primary: netbird accepted: diff --git a/hosts/arriman.yaml b/hosts/arriman.yaml index 40c53e8..8f5df9a 100644 --- a/hosts/arriman.yaml +++ b/hosts/arriman.yaml @@ -9,8 +9,8 @@ host: hubris pve_id: 122 lan_ip: 192.168.8.132 mesh: - netbird: - fqdn: arriman.netbird.selfhosted + tailscale: + fqdn: arr mesh_globals: primary: netbird accepted: diff --git a/hosts/authentik.yaml b/hosts/authentik.yaml index 4ca8e92..9329b85 100644 --- a/hosts/authentik.yaml +++ b/hosts/authentik.yaml @@ -8,9 +8,6 @@ role: idp host: hubris pve_id: 124 lan_ip: 192.168.8.180 -mesh: - netbird: - fqdn: authentik.netbird.selfhosted mesh_globals: primary: netbird accepted: diff --git a/hosts/caddy.yaml b/hosts/caddy.yaml index 5e4ab77..76780e8 100644 --- a/hosts/caddy.yaml +++ b/hosts/caddy.yaml @@ -8,9 +8,6 @@ role: reverse-proxy host: hubris pve_id: 121 lan_ip: 192.168.8.175 -mesh: - netbird: - fqdn: caddy.netbird.selfhosted mesh_globals: primary: netbird accepted: diff --git a/hosts/claudio-bot.yaml b/hosts/claudio-bot.yaml index 05cc839..e463c33 100644 --- a/hosts/claudio-bot.yaml +++ b/hosts/claudio-bot.yaml @@ -8,9 +8,6 @@ role: matrix-agent host: hubris pve_id: 123 lan_ip: 192.168.8.230 -mesh: - netbird: - fqdn: claudio-bot.netbird.selfhosted mesh_globals: primary: netbird accepted: diff --git a/hosts/elementsynapse.yaml b/hosts/elementsynapse.yaml index 62d6aba..32838b4 100644 --- a/hosts/elementsynapse.yaml +++ b/hosts/elementsynapse.yaml @@ -9,8 +9,8 @@ host: hubris pve_id: 118 lan_ip: 192.168.8.239 mesh: - netbird: - fqdn: elementsynapse.netbird.selfhosted + tailscale: + fqdn: elementsynapse mesh_globals: primary: netbird accepted: diff --git a/hosts/gitea.yaml b/hosts/gitea.yaml index 0e8c372..49ee4bf 100644 --- a/hosts/gitea.yaml +++ b/hosts/gitea.yaml @@ -9,8 +9,8 @@ host: hubris pve_id: 104 lan_ip: 192.168.8.121 mesh: - netbird: - fqdn: gitea.netbird.selfhosted + tailscale: + fqdn: gitea mesh_globals: primary: netbird accepted: diff --git a/hosts/haos.yaml b/hosts/haos.yaml index e467f5d..01a7dab 100644 --- a/hosts/haos.yaml +++ b/hosts/haos.yaml @@ -8,8 +8,8 @@ role: home-automation host: hubris pve_id: 108 mesh: - netbird: - fqdn: haos.netbird.selfhosted + tailscale: + fqdn: homeassistant mesh_globals: primary: netbird accepted: diff --git a/hosts/jellyfin.yaml b/hosts/jellyfin.yaml index 5f5b85e..f77a5e1 100644 --- a/hosts/jellyfin.yaml +++ b/hosts/jellyfin.yaml @@ -9,8 +9,8 @@ host: hubris pve_id: 101 lan_ip: 192.168.8.206 mesh: - netbird: - fqdn: jellyfin.netbird.selfhosted + tailscale: + fqdn: jellyfin mesh_globals: primary: netbird accepted: diff --git a/hosts/mac-mini.yaml b/hosts/mac-mini.yaml index e70cb33..5bd6cf8 100644 --- a/hosts/mac-mini.yaml +++ b/hosts/mac-mini.yaml @@ -7,7 +7,7 @@ os: macos role: dev mesh: netbird: - fqdn: mac-mini.netbird.selfhosted + fqdn: mac-mini-234-17.netbird.selfhosted mesh_globals: primary: netbird accepted: diff --git a/hosts/mule-images.yaml b/hosts/mule-images.yaml index 2a04a59..d402715 100644 --- a/hosts/mule-images.yaml +++ b/hosts/mule-images.yaml @@ -9,8 +9,8 @@ host: hubris pve_id: 120 lan_ip: 192.168.8.136 mesh: - netbird: - fqdn: mule-images.netbird.selfhosted + tailscale: + fqdn: muleimage mesh_globals: primary: netbird accepted: diff --git a/hosts/mule-photos-new.yaml b/hosts/mule-photos-new.yaml index f0e0927..bb890b0 100644 --- a/hosts/mule-photos-new.yaml +++ b/hosts/mule-photos-new.yaml @@ -8,9 +8,6 @@ role: photo-management host: hubris pve_id: 127 lan_ip: 192.168.8.181 -mesh: - netbird: - fqdn: mule-photos-new.netbird.selfhosted mesh_globals: primary: netbird accepted: diff --git a/hosts/nextcloud.yaml b/hosts/nextcloud.yaml index bab8610..d8782cb 100644 --- a/hosts/nextcloud.yaml +++ b/hosts/nextcloud.yaml @@ -9,8 +9,8 @@ host: hubris pve_id: 114 lan_ip: 192.168.8.224 mesh: - netbird: - fqdn: nextcloud.netbird.selfhosted + tailscale: + fqdn: nextcloud mesh_globals: primary: netbird accepted: diff --git a/hosts/nfs-export.yaml b/hosts/nfs-export.yaml index cc4e7f3..8381943 100644 --- a/hosts/nfs-export.yaml +++ b/hosts/nfs-export.yaml @@ -8,9 +8,6 @@ role: storage-export host: hubris pve_id: 102 lan_ip: 192.168.8.200 -mesh: - netbird: - fqdn: nfs-export.netbird.selfhosted mesh_globals: primary: netbird accepted: diff --git a/hosts/paperless.yaml b/hosts/paperless.yaml index 8c4f789..43a8fa4 100644 --- a/hosts/paperless.yaml +++ b/hosts/paperless.yaml @@ -9,8 +9,8 @@ host: hubris pve_id: 103 lan_ip: 192.168.8.130 mesh: - netbird: - fqdn: paperless.netbird.selfhosted + tailscale: + fqdn: paperless mesh_globals: primary: netbird accepted: diff --git a/hosts/plato.yaml b/hosts/plato.yaml index c7995b3..318da3a 100644 --- a/hosts/plato.yaml +++ b/hosts/plato.yaml @@ -8,9 +8,6 @@ role: app host: hubris pve_id: 126 lan_ip: 192.168.8.190 -mesh: - netbird: - fqdn: plato.netbird.selfhosted mesh_globals: primary: netbird accepted: diff --git a/hosts/republic-laptop.yaml b/hosts/republic-laptop.yaml index deffb6f..ad4be76 100644 --- a/hosts/republic-laptop.yaml +++ b/hosts/republic-laptop.yaml @@ -13,6 +13,5 @@ mesh_globals: accepted: - netbird - tailscale -age_pubkey: age1vf8h7s8mqsn2q5eadgpdupsj4mwn8zguc77d85ws3xj40sl9rgksx2rxw6 mcp_endpoint: https://mcp.hubris.network/sse secrets_issuance_endpoint: https://secrets.hubris.network/issue diff --git a/hosts/sophia.yaml b/hosts/sophia.yaml index 0f45f3f..62d08c0 100644 --- a/hosts/sophia.yaml +++ b/hosts/sophia.yaml @@ -9,8 +9,8 @@ host: hubris pve_id: 119 lan_ip: 192.168.8.157 mesh: - netbird: - fqdn: sophia.netbird.selfhosted + tailscale: + fqdn: sophia mesh_globals: primary: netbird accepted: diff --git a/hosts/zimaos.yaml b/hosts/zimaos.yaml index bf85440..7f86e12 100644 --- a/hosts/zimaos.yaml +++ b/hosts/zimaos.yaml @@ -7,9 +7,6 @@ os: linux role: nas-frontend-eval host: hubris pve_id: 100 -mesh: - netbird: - fqdn: zimaos.netbird.selfhosted mesh_globals: primary: netbird accepted: diff --git a/inventory.yaml b/inventory.yaml index 18e0781..f818942 100644 --- a/inventory.yaml +++ b/inventory.yaml @@ -119,8 +119,8 @@ hosts: lan_ip: 192.168.8.206 public_host: media.hubris.network mesh: - netbird: - fqdn: jellyfin.netbird.selfhosted + tailscale: + fqdn: jellyfin mounts: - /mnt/library age_pubkey: '' @@ -131,10 +131,6 @@ hosts: os: linux role: storage-export lan_ip: 192.168.8.200 - mesh: - netbird: - fqdn: nfs-export.netbird.selfhosted - age_pubkey: '' paperless: kind: lxc pve_id: 103 @@ -144,8 +140,8 @@ hosts: lan_ip: 192.168.8.130 public_host: paperless.hubris.network mesh: - netbird: - fqdn: paperless.netbird.selfhosted + tailscale: + fqdn: paperless mounts: - /mnt/library age_pubkey: '' @@ -159,8 +155,8 @@ hosts: public_host: git.hubris.network backend_port: 3000 mesh: - netbird: - fqdn: gitea.netbird.selfhosted + tailscale: + fqdn: gitea mounts: - /mnt/library notes: @@ -176,10 +172,9 @@ hosts: public_hosts: - artifacto.hubris.network mesh: - netbird: - fqdn: apps.netbird.selfhosted tailscale: ip: 100.121.171.122 + fqdn: apps mounts: - /mnt/library runs: @@ -197,8 +192,8 @@ hosts: lan_ip: 192.168.8.224 public_host: cloud.hubris.network mesh: - netbird: - fqdn: nextcloud.netbird.selfhosted + tailscale: + fqdn: nextcloud mounts: - /mnt/library age_pubkey: '' @@ -211,9 +206,8 @@ hosts: lan_ip: 192.168.8.239 public_host: matrix.hubris.network mesh: - netbird: - fqdn: elementsynapse.netbird.selfhosted - age_pubkey: '' + tailscale: + fqdn: elementsynapse sophia: kind: lxc pve_id: 119 @@ -222,8 +216,8 @@ hosts: role: workshop lan_ip: 192.168.8.157 mesh: - netbird: - fqdn: sophia.netbird.selfhosted + tailscale: + fqdn: sophia mounts: - /mnt/library age_pubkey: '' @@ -236,8 +230,8 @@ hosts: lan_ip: 192.168.8.136 public_host: photos.hubris.network mesh: - netbird: - fqdn: mule-images.netbird.selfhosted + tailscale: + fqdn: muleimage mounts: - /mnt/library age_pubkey: '' @@ -254,10 +248,6 @@ hosts: peers: - authentik - gitea - mesh: - netbird: - fqdn: caddy.netbird.selfhosted - age_pubkey: '' arriman: kind: lxc pve_id: 122 @@ -270,8 +260,8 @@ hosts: - qbit.hubris.network - sab.hubris.network mesh: - netbird: - fqdn: arriman.netbird.selfhosted + tailscale: + fqdn: arr mounts: - /mnt/library age_pubkey: '' @@ -282,9 +272,6 @@ hosts: os: linux role: matrix-agent lan_ip: 192.168.8.230 - mesh: - netbird: - fqdn: claudio-bot.netbird.selfhosted notes: - Reads /opt/homelab-context/ on startup age_pubkey: age1xmkeq968areza2necqyq0065dpeegngzyr6dhagh0n6pl33lccfqe5mqn9 @@ -298,10 +285,6 @@ hosts: public_host: auth.hubris.network notes: - 'Also hosts split-horizon dnsmasq: /etc/dnsmasq.d/hubris-split.conf' - mesh: - netbird: - fqdn: authentik.netbird.selfhosted - age_pubkey: '' plato: kind: lxc pve_id: 126 @@ -310,9 +293,6 @@ hosts: role: app lan_ip: 192.168.8.190 public_host: plato.hubris.network - mesh: - netbird: - fqdn: plato.netbird.selfhosted mounts: - /mnt/library/documents/plato age_pubkey: '' @@ -324,10 +304,6 @@ hosts: role: photo-management lan_ip: 192.168.8.181 public_host: photos-new.hubris.network - mesh: - netbird: - fqdn: mule-photos-new.netbird.selfhosted - age_pubkey: '' zimaos: kind: vm pve_id: 100 @@ -335,10 +311,6 @@ hosts: os: linux role: nas-frontend-eval public_host: zimaos.hubris.network - mesh: - netbird: - fqdn: zimaos.netbird.selfhosted - age_pubkey: '' haos: kind: vm pve_id: 108 @@ -346,9 +318,8 @@ hosts: os: linux role: home-automation mesh: - netbird: - fqdn: haos.netbird.selfhosted - age_pubkey: '' + tailscale: + fqdn: homeassistant republic-laptop: kind: workstation os: linux @@ -356,14 +327,13 @@ hosts: mesh: netbird: fqdn: republic-laptop.netbird.selfhosted - age_pubkey: age1vf8h7s8mqsn2q5eadgpdupsj4mwn8zguc77d85ws3xj40sl9rgksx2rxw6 mac-mini: kind: workstation os: macos role: dev mesh: netbird: - fqdn: mac-mini.netbird.selfhosted + fqdn: mac-mini-234-17.netbird.selfhosted notes: - Only macOS in the fleet. Bootstrap uses launchd. age_pubkey: '' @@ -374,4 +344,3 @@ hosts: mesh: netbird: fqdn: ludo-mini.netbird.selfhosted - age_pubkey: ''