nodes

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package nodes manages the control plane's view of cluster nodes: the per-node Docker client registry and the agent connection manager.

Index

Constants

This section is empty.

Variables

View Source
var ErrNodeOffline = errors.New("node is offline (no connected agent)")

ErrNodeOffline is returned when a Docker client is requested for a node whose agent is not currently connected.

Functions

func BuildDirectClient

func BuildDirectClient(srv *models.Server) (docker.Client, error)

BuildDirectClient creates a Docker client for a non-agent remote node (socket or api) from its stored record. Agent nodes are connected by the tunnel manager instead and return an error here.

Types

type Clients

type Clients struct {
	// contains filtered or unexported fields
}

Clients resolves a Docker client for a given server/node id. The local node uses the direct engine client; remote nodes use a tunneled client registered by the connection manager when their agent connects.

A server id of 0 (unset) resolves to the local node, so code paths that don't yet carry placement keep working on single-node installs.

func NewClients

func NewClients(localID uint, local docker.Client) *Clients

NewClients creates the registry seeded with the local node's client.

func (*Clients) Connected

func (c *Clients) Connected(serverID uint) bool

Connected reports whether a node currently has a usable Docker client.

func (*Clients) For

func (c *Clients) For(serverID uint) (docker.Client, error)

For returns the Docker client for a node, or ErrNodeOffline if a remote node has no connected agent.

func (*Clients) IsLocal

func (c *Clients) IsLocal(serverID uint) bool

IsLocal reports whether the server id refers to the local node.

func (*Clients) IsSelfContainer

func (c *Clients) IsSelfContainer(serverID uint, containerID string) bool

IsSelfContainer reports whether containerID is Miabi's own runtime container on the given node (the control plane locally, or that node's agent).

func (*Clients) Local

func (c *Clients) Local() docker.Client

Local returns the local node's Docker client.

func (*Clients) LocalID

func (c *Clients) LocalID() uint

LocalID returns the local node's server id.

func (*Clients) RemoteIDs

func (c *Clients) RemoteIDs() []uint

RemoteIDs returns the ids of remote nodes that currently have a live client (the local node is excluded). Used by the health sweep to probe each tunnel.

func (*Clients) RemoveRemote

func (c *Clients) RemoveRemote(serverID uint)

RemoveRemote drops a remote node's client when its agent disconnects.

func (*Clients) SelfContainerID

func (c *Clients) SelfContainerID(serverID uint) string

SelfContainerID returns Miabi's own runtime container ID on the node — the control plane locally, or the node's agent — or "" when unknown (e.g. an offline agent or detection that found nothing).

func (*Clients) SetLocalSelf

func (c *Clients) SetLocalSelf(id string)

SetLocalSelf records the control-plane's own container ID (detected at startup) so it is protected from removal on the local node.

func (*Clients) SetRemote

func (c *Clients) SetRemote(serverID uint, cl docker.Client)

SetRemote registers (or replaces) a remote node's client when its agent connects.

func (*Clients) SetRemoteSelf

func (c *Clients) SetRemoteSelf(serverID uint, id string)

SetRemoteSelf records a connected node's agent container ID (reported by the agent) so it is protected from removal on that node.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager accepts agent tunnels and maintains the live remote Docker clients in the registry, plus each node's online/offline status.

func NewManager

func NewManager(clients *Clients, nodes *node.Service) *Manager

func (*Manager) Clients

func (m *Manager) Clients() *Clients

Clients returns the per-node Docker client registry (for service wiring).

func (*Manager) ConnectDirect

func (m *Manager) ConnectDirect(srv *models.Server) error

ConnectDirect builds and registers a direct node's Docker client, replacing any existing one. No-op for agent or local nodes. Best-effort: a build error is returned so callers can surface it, but the node stays registered as offline until the next attempt.

func (*Manager) Connected

func (m *Manager) Connected(nodeID uint) bool

Connected reports whether a node currently has a live agent tunnel.

func (*Manager) Disconnect

func (m *Manager) Disconnect(nodeID uint)

Disconnect tears down a node's tunnel (e.g. when it is deleted).

func (*Manager) DisconnectDirect

func (m *Manager) DisconnectDirect(id uint)

DisconnectDirect drops a direct node's client (on delete or mode change).

func (*Manager) Handle

func (m *Manager) Handle(srv *models.Server, token, agentVersion, agentContainerID string, ws *websocket.Conn)

Handle owns an authenticated agent WebSocket: it builds the tunnel, registers the node's remote Docker client, marks it online, and blocks until the tunnel closes (so the HTTP handler keeps the connection open). The caller has already validated the join token; the plaintext token is passed through so the connect hook can configure node-side infrastructure (e.g. the gateway).

func (*Manager) LoadDirect

func (m *Manager) LoadDirect(ctx context.Context, interval time.Duration)

LoadDirect registers clients for all direct-access nodes at startup and runs a health poller that pings them on interval to keep their status current. It blocks until ctx is cancelled.

func (*Manager) ReconcileHealth

func (m *Manager) ReconcileHealth(ctx context.Context)

ReconcileHealth actively verifies every connected node by pinging its Docker daemon over the tunnel. A node that fails to answer has a dead or half-open tunnel that yamux keepalive hasn't caught yet, so its session is closed — which triggers the normal disconnect cleanup (registry removal + MarkDisconnected), correcting a stale "online" status. Run periodically by the node-health cron task as a global backstop to the per-connection heartbeat; safe to call concurrently with real Docker traffic (ping opens its own short-lived stream).

func (*Manager) RefreshClient

func (m *Manager) RefreshClient(srv *models.Server)

RefreshClient rebuilds a node's Docker client after its connectivity settings change. A live agent tunnel owns its own client registration, so this leaves a connected agent untouched — rebuilding here would evict (and close) the live client and flip the node offline even though the agent is still connected. For direct-access (socket/api) nodes it drops and rebuilds the client to pick up endpoint/credential changes.

func (*Manager) SetOnConnect

func (m *Manager) SetOnConnect(fn func(ctx context.Context, srv *models.Server, token string, dc docker.Client))

SetOnConnect registers a hook run (in a goroutine) once a node's agent has connected and its remote Docker client is live — e.g. to deploy an edge-gateway node's gateway. The hook receives the node's plaintext join token, which is only available at connect time.

func (*Manager) SetOnRemove

func (m *Manager) SetOnRemove(fn func(ctx context.Context, srv *models.Server, dc docker.Client))

SetOnRemove registers a hook run when a node is being removed while still connected — e.g. to tear down an edge-gateway node's gateway. It runs with the node's live Docker client before the tunnel is closed. See Teardown.

func (*Manager) SetSubscriber

func (m *Manager) SetSubscriber(fn func(ctx context.Context, nodeID uint, dc docker.Client))

SetSubscriber registers a per-node worker run (in a goroutine) for the node's whole connection lifetime: started once its Docker client is live, its context cancelled when the tunnel drops. Used for the per-node app event subscriber.

func (*Manager) Teardown

func (m *Manager) Teardown(ctx context.Context, srv *models.Server)

Teardown runs the onRemove hook with the node's live Docker client, if the node is currently connected. Call it before Disconnect/DeleteNode so node-side infrastructure can be cleaned up over the still-open tunnel. Best-effort: a no-op when the node is offline or no hook is set.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL