Repository navigation
feat(mesh): another machine joins as a node with the install line and lens node - #591
Merged
Merged
Conversation
… lens node Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTrHPwWHtEvFJFq3M1YpH4
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTrHPwWHtEvFJFq3M1YpH4
Merged
21 of 23 tasks
adeelahmad
pushed a commit
that referenced
this pull request
Oct 18, 2026
The mesh's install line landed (#591), so a group on a cloud, Proxmox or SSH provider could launch, but a node runs no `lens worker` yet: its units would never count as joined and only cost until given up on. can_join now also needs the mesh to say its nodes run workers (WORKER_NODES), and waiting_for says which of the three it waits for. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ALjNbLobvPe7VwvDL8j7V3
This was referenced Oct 18, 2026
adeelahmad
added a commit
that referenced
this pull request
Oct 18, 2026
* feat(scaling): Linux hosts over SSH as a provider Each unit is the first-boot script started in its own process group on one of the provider's hosts, up to per_host each; letting it go stops the group. Host keys are trusted on first use when an admin saves or checks the provider, kept when a later check fails, and held to on every call. Paramiko is the ssh extra, fetched when the first SSH provider is saved. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ALjNbLobvPe7VwvDL8j7V3 * fix(scaling): launch on other machines only once mesh nodes run workers The mesh's install line landed (#591), so a group on a cloud, Proxmox or SSH provider could launch, but a node runs no `lens worker` yet: its units would never count as joined and only cost until given up on. can_join now also needs the mesh to say its nodes run workers (WORKER_NODES), and waiting_for says which of the three it waits for. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ALjNbLobvPe7VwvDL8j7V3 --------- Co-authored-by: Adeel Ahmad <noreply@anthropic.com>
20 of 23 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Before: an admin could make a join token, but no machine could use it. There was no agent on the other side, and no install line.
After:
POST /api/v1/mesh/tokensreturns aninstall_line. On another machine,curl … install.sh | LENS_JOIN=<url> LENS_JOIN_TOKEN=<token> shmakes it a node in~/lens-node. It asks nothing, publishes no port and starts two containers (docker-compose.node.yml):meshruns Nebula. It is the same sidecar the primary uses.noderuns the newlens nodeagent.The agent joins once. The token never crosses the wire and is never written to
.env. After that it talks to the primary over the mesh only. Every minute it fetches its config (the blocklist), renews its certificate when a third of its life is left or its key changed, and sends its report. A removed node keeps asking, so an undo brings it back.lens node statussays what the machine is on the mesh, without its credentials.The API's host check now admits the primary's mesh address for
/api/v1/mesh/node/*only, and only while the mesh is on.Motivation and Context
This is the third step of the Nebula network Adeel asked for: workers and other nodes always talk over their own private network, set up automatically. Worker nodes running jobs and the Settings › Nodes and Network pages follow in their own PRs.
Steps to reproduce (if appropriate):
I ran it end to end in this container with real Nebula 1.11.2 and Docker:
docs/mesh.md"On a node" says.Types of changes
!in the title)Checklist:
make hookschecks it on commit).tests/api/test_mesh_node.py,test_mesh.py).docs/accordingly (docs/mesh.md"On a node").changelog.d/mesh-node.md.Done questions (AGENTS.md)
install_line);lens node statusprints JSON.meshsettings are feat(mesh): Lens as the CA of a Nebula mesh between its machines, with join tokens and a node registry #546's).leanimage; nothing changes on installs without nodes.make openapi).docs/mesh.md(an upgrade agent on nodes).Generated by Claude Code