release(v2.4.0): theta-agent v2.2.0 - Windows local-discovery + route pinning
Rolls up theta-agent v2.2.0: Windows hosts override (CRLF-aware, ipconfig /flushdns), /32 host-route pinning so the WireGuard tunnel can't swallow the direct LAN path, and a prompt WS reconnect on apply/revert. Marks Windows local-discovery shipped in MULTI_SITE_SPEC.md; macOS remains the one unbuilt piece (in progress on a macOS VM).
This commit is contained in:
@@ -9,6 +9,36 @@ orchestration code; see each submodule's own `CHANGELOG.md`
|
||||
[jump-host](https://github.com/theta42/jump-host/blob/master/CHANGELOG.md))
|
||||
for what changed inside the apps it composes.
|
||||
|
||||
## [v2.4.0] - 2026-08-10
|
||||
|
||||
Rolls up **theta-agent v2.2.0** — mDNS local-discovery is now Windows-capable,
|
||||
closing the last gap in the original multi-site design on the agent side.
|
||||
|
||||
### theta-agent v2.2.0
|
||||
- **Windows local-discovery**: the hosts override now runs on Windows
|
||||
(`%SystemRoot%\System32\drivers\etc\hosts`, CRLF-aware, `ipconfig /flushdns`
|
||||
after every change). Reachable because the agent runs as a SYSTEM service, so
|
||||
the elevation question in the spec resolved in our favor. The Windows CI leg
|
||||
now runs the real Windows write path instead of skipping.
|
||||
- **Local route pinning** (`local_route*.go`): the hosts override only fixes
|
||||
*name resolution*; the packet path is the routing table's job. If the WireGuard
|
||||
mesh tunnel is up with `AllowedIPs` covering the LAN subnet (or a full-tunnel
|
||||
`0.0.0.0/0`), the tunnel route would swallow the direct connection to the
|
||||
discovered LAN IP. Discovery now pins a `/32` host route via the owning local
|
||||
interface (`route.exe add ... metric 1` on Windows, `ip route replace` on
|
||||
Linux) and drops it on revert — closing a real gap in the shipped Linux path.
|
||||
- **Prompt reconnect**: an apply/revert signals the WebSocket loop, which
|
||||
reconnects immediately instead of waiting out its 5s backoff.
|
||||
- **Installer version fix**: the setup.exe previously hardcoded `2.1.0` in its
|
||||
file name and version resources no matter the tag; it now derives the version
|
||||
from the git tag.
|
||||
|
||||
### docs
|
||||
- `docs/MULTI_SITE_SPEC.md` status table updated: Windows local-discovery marked
|
||||
shipped; macOS remains the one unbuilt piece (hosts override compiles on
|
||||
darwin but needs `dscacheutil -flushcache` + real hardware testing, being done
|
||||
on a macOS VM).
|
||||
|
||||
## [v2.3.0] - 2026-08-10
|
||||
|
||||
Rolls up **theta-directory v2.4.0**, **jump-host v2.1.0**, **theta-agent v2.1.2**. Live catalog replication and a real gateway-to-gateway WireGuard mesh land in the same pass — multi-site directory sync stops being a one-time snapshot, and site-to-site networking becomes real infrastructure instead of a documented-but-unbuilt design. See `docs/MULTI_SITE_SPEC.md` for the full architecture and an explicit TODO list of what's still open (Windows/macOS mDNS, routing directory traffic over the mesh, `theta-proxy` no-inbound relay automation).
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
> - **Join, live replication, promotion** (`sso-manager-node`): a spoke joins via a one-time export over a site join key (`POST /api/site/join-keys` / `/export` / `/join`), then registers its own endpoint so the master can push live resync pings on every catalog write — no longer a one-time snapshot. Promotion (`POST /api/directory-admin/site-promote`) coordinates a real handoff, demoting the old master as one action. Identical agent-signing keys ride the same export/resync path. Read [`sso-manager-node/docs/site-join.md`](https://github.com/theta42/theta-directory/blob/master/docs/site-join.md) and `directory_spec.md` §11 for the endpoint-level detail.
|
||||
> - **Gateway-to-gateway WireGuard mesh** (`theta-gateway`): real site-to-site tunnels via `POST /api/mesh/register`/`/join`, kernel WireGuard with a userspace `wireguard-go` fallback. Verified with an actual two-container encrypted tunnel passing traffic, not a mock.
|
||||
> - **Not yet connected to each other**: the mesh is a transport layer that exists on its own; `sso-manager-node`'s HTTPS-based join/replicate calls don't route over it yet. That wiring, plus the no-inbound relay it would enable (mechanism verified, automation not built — see status table), is the next layer.
|
||||
> - **mDNS local-discovery, Linux**: shipped and verified end-to-end — `theta-gateway` announces (`services/mdns_announce.js`), `theta-agent` discovers and applies a hosts-file override, cleanly reverts when the announcement disappears. Windows/macOS remain unbuilt — see the TODO list.
|
||||
> - **mDNS local-discovery (Linux + Windows)**: shipped and verified — `theta-gateway` announces (`services/mdns_announce.js`), `theta-agent` discovers and applies a hosts-file override, cleanly reverts when the announcement disappears. Linux was verified end-to-end over real multicast; Windows shipped in `theta-agent` v2.2.0 (CRLF-aware hosts override, `ipconfig /flushdns`, and a /32 host-route pin so the WireGuard tunnel can't swallow the direct LAN path). macOS still needs real testing — see the TODO note.
|
||||
|
||||
Design scale: a handful of sites (dozen max, 254 hard ceiling — see §4), a few hundred users/hosts total. This is a deliberate, small, trusted-operator deployment, not a hyperscale/adversarial-tenant one — several decisions below (fire-and-forget replication, identical directories) trade blast-radius for simplicity *because* the scale allows it. Don't generalize these choices past that scale without re-deriving them.
|
||||
|
||||
@@ -263,7 +263,8 @@ See [`AGENT_LOCAL_DISCOVERY_SPEC.md`](./AGENT_LOCAL_DISCOVERY_SPEC.md) — split
|
||||
| WireGuard gateway-to-gateway mesh (`theta-gateway`) | **Shipped** — `POST /api/mesh/register`/`/join` (join-token bootstrap), `utils/wg_iface.js` (kernel WireGuard, falls back to userspace `wireguard-go`). Verified with a real two-container test: actual encrypted tunnel, real ICMP traffic across it, 0% loss. This is the mesh transport layer only — nothing in `sso-manager-node`'s replication yet routes traffic *over* it; today's site-to-site HTTPS calls (join/export/resync) still go over whatever network path already reaches the target, same as before this layer existed. |
|
||||
| No-inbound-spoke relay (master proxies a spoke with no public IP) | **Mechanism verified, automation not built.** Confirmed with a standalone test (not `theta-proxy`'s actual Lua/Redis engine, which needs its own dedicated pass to wire safely): a spoke with zero published ports, reachable only via its WG mesh IP, served a request that an external client sent to the master's public port — the master terminated the connection and relayed over the tunnel. So the underlying idea works; what's missing is `theta-proxy` automatically creating that relay route when a no-inbound spoke registers (needs a real service-to-service credential between `sso-manager-node` and `theta-proxy`/`theta-gateway` that doesn't exist yet — a new integration, not a small wiring task), and today's HTTPS-based join/replicate still requires the spoke to reach the master's API directly (and vice versa for export), so a spoke with zero inbound *and* zero outbound path still can't join at all. |
|
||||
| mDNS local-discovery (Linux) | **Shipped** — `theta-gateway` announces (`services/mdns_announce.js`, opt-in via `THETA_LOCAL_DISCOVERY_HOSTS`), `theta-agent` discovers and applies a hosts-file override (`local_discovery.go`, opt-in via `prefer_local_directory`). Verified end-to-end with real containers over real multicast: announce → discover → apply → clean revert on disappearance, all confirmed. Caught two real bugs along the way (`mdns.Lookup()`'s IPv6 query aborting the whole lookup even after a valid IPv4 response arrived; `rename()` failing with EBUSY over a bind-mounted `/etc/hosts`, common in every container runtime) — see the commit messages in `theta-agent`. |
|
||||
| mDNS local-discovery (Windows, macOS) | Not built — needs platform-native testing this environment can't do (hosts-file vs. stub-resolver tradeoff, elevation, DNS-cache behavior per OS — see Appendix B §3). This is now the **only unbuilt piece** of the original design. |
|
||||
| mDNS local-discovery (Windows) | **Shipped** — `theta-agent` v2.2.0: Windows hosts override (`%SystemRoot%\System32\drivers\etc\hosts`, CRLF-aware, `ipconfig /flushdns` after each change — reachable because the agent runs as a SYSTEM service, so the elevation question resolved in our favor), plus a /32 host-route pin via the owning local interface (`route.exe add ... metric 1`) so the WireGuard mesh tunnel can't swallow the direct LAN path, and a prompt WS reconnect on apply/revert. Tests run the real Windows write path on the Windows CI leg. |
|
||||
| mDNS local-discovery (macOS) | Not built — the hosts override compiles on darwin via the shared unix path, but macOS still needs `dscacheutil -flushcache` and real hardware testing (mDNSResponder behavior, hosts-file vs. native Bonjour — see Appendix B §3). Being built on a real macOS VM. |
|
||||
|
||||
### TODO — what's actually left, in dependency order
|
||||
|
||||
@@ -273,6 +274,6 @@ See [`AGENT_LOCAL_DISCOVERY_SPEC.md`](./AGENT_LOCAL_DISCOVERY_SPEC.md) — split
|
||||
4. **Full secret replication** — only the agent-signing key is replicated today. LDAP admin credentials, JWT secrets, and other per-deployment secrets still differ per site, which complicates full disaster recovery.
|
||||
5. **Mesh peer cleanup** — `wg_iface.removePeer()` doesn't remove the kernel routes `setPeer()` adds (flagged in code; not yet exercised because nothing removes a mesh peer today).
|
||||
|
||||
**mDNS local-discovery (Windows + macOS)** is deliberately not listed here: another session is actively building it on a real Windows machine (this environment can only do the Linux side, already shipped — see the status table). Check `theta-agent`'s recent history before assuming it's still open.
|
||||
**mDNS local-discovery, macOS** is deliberately not listed above: the Linux and Windows sides are shipped and verified (`theta-agent` v2.2.0), and macOS is being built on a real macOS VM where the darwin-specific behavior (mDNSResponder/DNS-cache) can actually be tested. Check `theta-agent`'s recent history before assuming it's still open.
|
||||
|
||||
*Committed under [`docs/MULTI_SITE_SPEC.md`](file:///home/william/dev/theta42/theta-env/docs/MULTI_SITE_SPEC.md).*
|
||||
|
||||
+1
-1
Submodule theta-agent updated: a3eeed8112...1b332cacab
Reference in New Issue
Block a user