Documentation
¶
Overview ¶
Package execsession is the VM side of the user shell — and of every `crun exec` invocation. loom-server opens a session by publishing on `weft.exec.<vmID>.<sid>.open` (a JSON ExecRequest), then frames flow over two ephemeral subjects :
weft.exec.<vmID>.<sid>.in — frames TO the pty
'i' + payload stdin
'r' + cols(u16) + rows(u16) resize
'x' eof / close
weft.exec.<vmID>.<sid>.out — frames FROM the pty
'o' + payload stdout
'e' + code(u32) exited (process exit)
The same 1-byte-prefix wire shape as loom-server's existing /api/projects/{p}/shell — so the SPA bridge can forward bytes verbatim, the loom-server is a dumb proxy, and replacing local pty with NATS exec is a router change rather than a protocol change.
Two target modes :
Target.Kind = "shell" — spawn /bin/bash inside the VM root.
The default shell-tab session.
Target.Kind = "exec" — `crun exec <container>` with given
Command/Args. Used for compile jobs
+ tool wrappers (`pdflatex` etc.)
Eviction : a session is closed when the input stream sends 'x', the underlying process exits, or the open-publisher disconnects (via JetStream subscription drop). Sessions never persist across agent restarts — the SPA reconnects + opens a fresh one.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SubjectOpen ¶
SubjectOpen is the request subject for opening a new session.
func SubjectOut ¶
Types ¶
type ExecRequest ¶
type ExecRequest struct {
ID string `json:"id"`
Target ExecTarget `json:"target"`
// InitialSize lets the agent allocate the pty at the right
// dimensions before any 'r' frame arrives. Optional.
InitialCols uint16 `json:"cols,omitempty"`
InitialRows uint16 `json:"rows,omitempty"`
}
ExecRequest is what loom-server publishes on SubjectOpen. ID is chosen by the publisher (typically a ULID), so the SPA can preconfigure its in/out subscriptions before the agent acks open.
func DecodeRequest ¶
func DecodeRequest(data []byte) (ExecRequest, error)
DecodeRequest unmarshals an ExecRequest + validates it. Same testable shape as the other agent reconcilers.
func (*ExecRequest) Validate ¶
func (r *ExecRequest) Validate() error
Validate is the schema check the agent runs before opening a session. Returns the descriptive error a loom-doctor surface can surface back to the publisher.
type ExecTarget ¶
type ExecTarget struct {
Kind string `json:"kind"` // "shell" | "exec"
// For Kind="shell" : Command/Args/Env optionally override
// /bin/bash. Empty = sensible defaults.
// For Kind="exec" : Container must be set ; Command + Args are
// passed to `crun exec`.
Container string `json:"container,omitempty"`
Command []string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
Env map[string]string `json:"env,omitempty"`
WorkDir string `json:"work_dir,omitempty"`
}
ExecTarget tells the agent which process to spawn. Shell vs exec is the only structural split.
type Sessions ¶
type Sessions struct {
// contains filtered or unexported fields
}
Sessions tracks every live execution so the agent can clean up (kill pty, unsubscribe from in subject) when an open-publisher drops or the process exits. Concurrent-safe.
func NewSessions ¶
func NewSessions() *Sessions
NewSessions builds an empty session registry. Agent main wires the NATS subscriber that calls Open / Close from message handlers.
type Subscriber ¶ added in v0.4.0
type Subscriber struct {
// contains filtered or unexported fields
}
func NewSubscriber ¶ added in v0.4.0
func NewSubscriber(_ *nats.Conn, vmID string, logger Logger) *Subscriber