Documentation
¶
Overview ¶
Package remote is the organisation's view of one registered runner: a substrate.Substrate that carries every call over a Transport to a wardyn-runnerd and maps the runner's typed errors back to the runner package's sentinels. It decides nothing; the org dispatches, the runner executes.
Index ¶
- Variables
- type Admission
- type Handler
- type Hub
- func (h *Hub) Close()
- func (h *Hub) Goaway(ctx context.Context, id uuid.UUID) error
- func (h *Hub) GoawayAll(ctx context.Context) error
- func (h *Hub) Online(id uuid.UUID) bool
- func (h *Hub) Revoke(ctx context.Context, id uuid.UUID) error
- func (h *Hub) Serve(ctx context.Context, conn runnerwire.Conn, id uuid.UUID) error
- type HubConfig
- type Link
- func (l *Link) Attach(ctx context.Context, conn runnerwire.Conn) *runnerwire.Peer
- func (l *Link) AttachSession(conn runnerwire.Conn, cfg runnerwire.PeerConfig) *runnerwire.Peer
- func (l *Link) Call(ctx context.Context, method string, args, result any, ...) error
- func (l *Link) Close()
- func (l *Link) Online() bool
- func (l *Link) Ready(peer *runnerwire.Peer) error
- func (l *Link) Send(ctx context.Context, frame runnerwire.Frame) error
- func (l *Link) SetHandler(h Handler)
- func (l *Link) StreamCount() int
- func (l *Link) TakeStream(id uint32) (*runnerwire.Stream, error)
- type Options
- type Substrate
- func (s *Substrate) Advertised() (runner.TargetFacts, bool)
- func (s *Substrate) AgentStatus(ctx context.Context, ref, agentExecID string) (runner.Status, error)
- func (s *Substrate) Attach(ctx context.Context, ref string, opts runner.AttachOptions) (runner.Session, error)
- func (s *Substrate) CanReplaceProxy(ctx context.Context, ref string) error
- func (s *Substrate) Caps() (runnerwire.Caps, bool)
- func (s *Substrate) Classes(context.Context) (substrate.ClassSupport, error)
- func (s *Substrate) CreateSandbox(ctx context.Context, spec runner.SandboxSpec) (runner.Sandbox, error)
- func (s *Substrate) DeliverResident(ctx context.Context, a runnerwire.DeliverResidentArgs) error
- func (s *Substrate) EndSandbox(ctx context.Context, ref string) error
- func (s *Substrate) EnsureProxyImage(ctx context.Context) error
- func (s *Substrate) EraseResident(ctx context.Context, runID uuid.UUID) error
- func (s *Substrate) Exec(ctx context.Context, ref string, argv []string) (string, error)
- func (s *Substrate) ExecStream(ctx context.Context, ref string, spec runner.ExecSpec) (*runner.ExecSession, error)
- func (s *Substrate) ExecutionResult(ctx context.Context, ref string, generation uuid.UUID) (runnerwire.ExecutionResult, error)
- func (s *Substrate) HandleEvent(ev runnerwire.Event)
- func (s *Substrate) HandleOpen(st *runnerwire.Stream, o runnerwire.Open) error
- func (s *Substrate) KillSandbox(ctx context.Context, ref string) error
- func (s *Substrate) Name() string
- func (s *Substrate) ProbeDrive(ctx context.Context, mount types.DriveMount) (runner.DriveProbe, error)
- func (s *Substrate) ProbeSubstrate(context.Context) runner.SubstrateState
- func (s *Substrate) RecoverOutput(ctx context.Context, ref string, w io.Writer) error
- func (s *Substrate) ReplaceProxy(ctx context.Context, ref string, cfgJSON []byte) error
- func (s *Substrate) RunnerID() string
- func (s *Substrate) StartSandbox(ctx context.Context, ref string) error
- func (s *Substrate) Status(ctx context.Context, ref string) (runner.Status, error)
- func (s *Substrate) StopProxy(ctx context.Context, ref string) error
- func (s *Substrate) StopSandbox(ctx context.Context, ref string) error
- func (s *Substrate) SweepOrphanedSandboxes(ctx context.Context, minAge time.Duration, isOrphan func(uuid.UUID) bool) (int, error)
- func (s *Substrate) Wait(ctx context.Context, ref string) (int, error)
- type Transport
Constants ¶
This section is empty.
Variables ¶
var ( // ErrResidentLeak refuses a CreateSandbox whose payload would carry a value // already delivered to the runner as runner_resident: the spec names such a // grant by placeholder, and the value travels only in DeliverResident. ErrResidentLeak = errors.New("remote: a runner_resident value is in the CreateSandbox payload") // ErrForeignRef refuses a ref that is not this runner's. ErrForeignRef = errors.New("remote: ref does not belong to this runner") // ErrUnsupportedStream refuses a runner-opened stream the substrate does not serve. ErrUnsupportedStream = errors.New("remote: unsupported stream") )
Functions ¶
This section is empty.
Types ¶
type Admission ¶
type Admission struct {
Substrate *Substrate
Link *Link
Pending func(context.Context) ([]runnerwire.PendingAction, error)
// BeginInventory captures the org's candidate set for a fresh session
// before AUTH_OK and PENDING, fencing every earlier session's inventory.
// It runs under the runner's session slot; a resumed session skips it.
BeginInventory func(ctx context.Context, sessionID string) error
// StatePage durably accepts one bounded, already-ordered page of that
// session's inventory. It runs on the peer read loop, so it must neither
// call this runner nor wait on a lock held across a call to it. An error
// refuses READY and forces a fresh session; the Hub keeps only a cursor.
StatePage func(ctx context.Context, sessionID string, page runnerwire.StatePage) error
Event func(context.Context, runnerwire.Event) error
// Activity checks current run ownership/lifecycle in its database transaction.
// Nil refuses live activity; historical EVENT ingestion never calls it.
Activity func(context.Context, uuid.UUID) error
// Ready, when set, is told once the session is READY, the first moment the runner accepts a LEASE. It
// runs on the peer read loop for a fresh session, so it must not block or call this runner.
Ready func()
}
Admission is supplied by the org's durable routing/reconciliation layer. Pending, BeginInventory, StatePage and Event are required: missing durable reconciliation must not silently admit a runner. Substrate and Link must be the same pair.
type Handler ¶
type Handler interface {
HandleEvent(ev runnerwire.Event)
HandleOpen(s *runnerwire.Stream, o runnerwire.Open) error
}
Handler receives what a runner sends on its own.
type Hub ¶
type Hub struct {
// contains filtered or unexported fields
}
Hub retains only authenticated sessions, for the bounded resume window. Connections and callbacks belong to ctx, the daemon lifetime.
func (*Hub) Close ¶
func (h *Hub) Close()
Close drops this replica's connections and timers at daemon shutdown.
func (*Hub) Goaway ¶
Goaway forces the next connection through full admission, for replica drain or an administrative session reset. It does not revoke the registered key.
func (*Hub) Online ¶
Online reports whether id's current session reached its own READY and its peer is still up. A session in transition holds its slot and reads offline rather than making the caller wait for it.
type HubConfig ¶
type HubConfig struct {
OrgURL string
Lookup func(context.Context, uuid.UUID) (types.Runner, error)
Admit func(context.Context, types.Runner) (Admission, error)
// Connected and Disconnected are audit/lifecycle callbacks. A resumed
// session emits neither; Disconnected waits for the resume window.
Connected func(context.Context, uuid.UUID) error
Disconnected func(context.Context, uuid.UUID) error
// Verified runs once the runner proves possession of its stored key,
// before any further lookup or admission. An error refuses the connection.
Verified func(context.Context, uuid.UUID) error
// Inactive, when set, says a claimed runner may hold no session now (its
// owner is deactivated), without revoking it. Such a connection is sent
// GOAWAY before admission, and the stored-row recheck ends a live session
// the same way, so a connection after reactivation is admitted again.
Inactive func(context.Context, types.Runner) (bool, error)
}
HubConfig binds proof of possession to stored identity and org admission.
type Link ¶
type Link struct {
// contains filtered or unexported fields
}
Link is the Transport over runnerwire.Conns. Attach starts a session on a connection whose handshake has already run; a later Attach replaces it.
func (*Link) Attach ¶
func (l *Link) Attach(ctx context.Context, conn runnerwire.Conn) *runnerwire.Peer
Attach runs the org side of a session over conn until the link ends, and returns its peer so the caller can send session-level frames and watch Done.
func (*Link) AttachSession ¶
func (l *Link) AttachSession(conn runnerwire.Conn, cfg runnerwire.PeerConfig) *runnerwire.Peer
AttachSession prepares an authenticated session without admitting calls or unsolicited streams. Start drives it; Ready admits dispatch after replay or the full PENDING/STATE/spool/READY sequence. Attach retains its loopback API.
func (*Link) Call ¶
func (l *Link) Call(ctx context.Context, method string, args, result any, opts ...runnerwire.CallOption) error
func (*Link) Close ¶
func (l *Link) Close()
Close rejects dispatch immediately and ends the active peer.
func (*Link) Ready ¶
func (l *Link) Ready(peer *runnerwire.Peer) error
Ready admits only the exact peer that completed admission, never a stale connection's READY racing a newer attachment.
func (*Link) SetHandler ¶
func (*Link) StreamCount ¶
StreamCount is the byte streams the current session holds (0 when none).
func (*Link) TakeStream ¶
func (l *Link) TakeStream(id uint32) (*runnerwire.Stream, error)
type Options ¶
type Options struct {
// Queue durably records an action to apply when the runner reconnects. With
// it set, a teardown issued while offline returns runner.ErrPendingOnRunner
// (queued, not failed); without it, runner.ErrRunnerOffline.
Queue func(ctx context.Context, kind types.RunnerActionKind, ref string) error
// ExecutionGeneration verifies the immutable generation bound to this exact
// dispatch context against its persisted operation. It must never select
// the latest lease/row or allocate a new generation on an ambiguous retry.
// Authenticated Hub admission requires this hook for Exec/Start dispatch.
ExecutionGeneration func(ctx context.Context, method, ref string) (uuid.UUID, error)
// Dispatch, when set, is read before every CreateSandbox CALL; an error
// refuses the create before anything reaches the runner.
Dispatch func(context.Context) error
// OnEvent receives every runner event except `caps` (kept here) and
// `waiting` (delivered to the create that owns it).
OnEvent func(runnerwire.Event)
// Relay takes a runner-opened relay stream as a net.Conn, tagged with the
// session's authenticated runner id. It runs on the peer read loop, so it
// must not block; an error refuses the stream. Nil refuses every relay.
Relay func(runnerID string, conn net.Conn) error
}
Options are the seams the runner hub fills.
type Substrate ¶
type Substrate struct {
// contains filtered or unexported fields
}
Substrate is one runner as a substrate.Substrate.
func (*Substrate) Advertised ¶
func (s *Substrate) Advertised() (runner.TargetFacts, bool)
Advertised is the runner's last advertised classes and per-run capacity, false while it is offline or has advertised nothing, so a caller never reads the unknown as zero.
func (*Substrate) AgentStatus ¶
func (*Substrate) Attach ¶
func (s *Substrate) Attach(ctx context.Context, ref string, opts runner.AttachOptions) (runner.Session, error)
Attach opens a pty stream on the runner. Close resets the stream only.
func (*Substrate) CanReplaceProxy ¶
func (*Substrate) Caps ¶
func (s *Substrate) Caps() (runnerwire.Caps, bool)
Caps is the runner's last advertised capabilities, if any.
func (*Substrate) CreateSandbox ¶
func (s *Substrate) CreateSandbox(ctx context.Context, spec runner.SandboxSpec) (runner.Sandbox, error)
CreateSandbox sends the spec minus OnWaiting and ExecOutput. `waiting` events call spec.NotifyWaiting on this goroutine, in order, before it returns.
func (*Substrate) DeliverResident ¶
func (s *Substrate) DeliverResident(ctx context.Context, a runnerwire.DeliverResidentArgs) error
DeliverResident hands one runner_resident value to the runner's keystore, after claim and before CreateSandbox. It is the only way the value travels: never /internal/*, never inside CreateSandbox.
func (*Substrate) EndSandbox ¶
func (*Substrate) EnsureProxyImage ¶
func (*Substrate) EraseResident ¶
EraseResident asks the runner to erase the run's resident values, best effort.
func (*Substrate) ExecStream ¶
func (s *Substrate) ExecStream(ctx context.Context, ref string, spec runner.ExecSpec) (*runner.ExecSession, error)
ExecStream starts an exec on the runner: stdin and stdout share the `exec` stream (stdin half-close is CLOSE) and stderr is its own stream, drained concurrently by the caller as runner.ExecSession requires.
func (*Substrate) ExecutionResult ¶
func (s *Substrate) ExecutionResult(ctx context.Context, ref string, generation uuid.UUID) (runnerwire.ExecutionResult, error)
ExecutionResult reads the runner's durable result for one already-issued operation. H3 compares Operation with its persisted dispatch before binding the handle. An empty handle means ambiguous intent, never permission to retry. Call only from an asynchronous reconciler after READY, not a checked handler.
func (*Substrate) HandleEvent ¶
func (s *Substrate) HandleEvent(ev runnerwire.Event)
HandleEvent keeps the `caps` event and passes the rest to Options.OnEvent.
func (*Substrate) HandleOpen ¶
func (s *Substrate) HandleOpen(st *runnerwire.Stream, o runnerwire.Open) error
HandleOpen serves the two streams a runner opens: a relay (handleRelay) and an output copy, which resumes at a raw byte offset. Duplicate prefixes are discarded; a forward gap is an error. ACK follows successful writer acceptance.
func (*Substrate) KillSandbox ¶
func (*Substrate) ProbeDrive ¶
func (s *Substrate) ProbeDrive(ctx context.Context, mount types.DriveMount) (runner.DriveProbe, error)
func (*Substrate) ProbeSubstrate ¶
func (s *Substrate) ProbeSubstrate(context.Context) runner.SubstrateState
ProbeSubstrate answers link state; it makes no call.
func (*Substrate) RecoverOutput ¶
RecoverOutput reads the runner-side output buffer into w.
func (*Substrate) ReplaceProxy ¶
ReplaceProxy hands the org's stored, already-stripped proxy config to the runner, which re-applies its resident values from its keystore.
func (*Substrate) StartSandbox ¶
func (*Substrate) StopSandbox ¶
func (*Substrate) SweepOrphanedSandboxes ¶
func (s *Substrate) SweepOrphanedSandboxes(ctx context.Context, minAge time.Duration, isOrphan func(uuid.UUID) bool) (int, error)
SweepOrphanedSandboxes runs the crash-orphan sweep on the runner in two calls (a func cannot cross the wire): the runner lists what it holds older than minAge, the org keeps the run ids isOrphan says are orphans, and the runner removes exactly those. It is skipped, with the runner offline, by the ErrRunnerOffline of the first call.
type Transport ¶
type Transport interface {
// Online is true while an authenticated session is up.
Online() bool
Call(ctx context.Context, method string, args, result any, opts ...runnerwire.CallOption) error
// TakeStream claims a byte stream the runner opened for an in-flight call.
TakeStream(id uint32) (*runnerwire.Stream, error)
// SetHandler is where the transport delivers the runner's events and
// unsolicited streams. New calls it once.
SetHandler(h Handler)
}
Transport is how a Substrate reaches its runner: one session at a time, replaced on reconnect. Link is the implementation over a runnerwire.Conn, the in-memory loopback and the WebSocket alike.