Documentation
¶
Overview ¶
Package worker is the side of a worker that runs code and moves files for a harness over one connection. A frame is one JSON header line, len body bytes, and a newline: the state file record shape, so a frame can be read and logged the same way. The body is never escaped.
Index ¶
- Constants
- Variables
- func Dial(m *mesh.Mesh, l Local) *drives
- func Encode(w io.Writer, f Frame) error
- func File(op, path string) error
- func Install(token string) error
- func Installed() (token string, op *user.User, err error)
- func JS(dir string) error
- func Serve(conn net.Conn, l Local, d *drives) error
- func Uninstall() error
- func ValidDrive(name string) bool
- func Work(key string, l Local) error
- type Client
- type Desired
- type Drive
- type Export
- type Frame
- type Header
- type Local
- type Mount
- type SMB
Constants ¶
const ( Mounted = "mounted" Serving = "serving" Waiting = "waiting" Failed = "error" )
const ( MaxBytes = 50 << 10 MaxLines = 2000 )
Result limits are opencode's: what current models handle in one result. The worker spills output over them to a file; the harness clips what it shows.
const ( Harness = "harness" Admin = "admin" Port = 7000 APIPort = 8080 )
A worker dials the mesh node the coordinator names Harness, at Port, the port the design names. The port is open on the mesh only, and the name is one the coordinator gives no worker. The CLI on a worker calls the API there at APIPort, the harness's loopback port. Admin is the worker on the harness's machine, which the harness install makes: the coordinator gives its name to the node that joins with the join secret of that name, and to no other.
const ( Run = "run" Read = "read" Write = "write" Kill = "kill" // end a session's environments and jobs Update = "update" // become release Version, then restart Drives = "drives" // no id, no answer: the body is the Desired drives, whole Hello = "hello" // first frame on a connection: what the worker is Output = "output" // run: one chunk, in order Result = "result" // run: exit code, path of the whole output when spilled; a job's: its log and tail Started = "started" // run of a job: it runs, as pid, its output in path Bytes = "bytes" // read: the file Done = "done" // write, kill, update; a job a kill ended Error = "error" // any request: text the model reads Status = "status" // no id: the worker's drives changed )
Kinds. The first six go harness to worker; the rest come back. Hello, update, and the done or error that answers an update are the contract every version from v0.1.0 keeps: they are how a worker of another release becomes this one. Workers from before it do not know update and are reinstalled.
const Bin = "/usr/local/bin/mainplane"
Bin is the binary the service runs. It and the state directory are root's: code that runs as the operator cannot replace the service or read its token.
const ( // BunVersion is pinned, so a snippet behaves the same on every worker. A bump is // a PR that changes the version and every sum below, from the release's // SHASUMS256.txt. BunVersion = "1.4.2" )
The js interpreter is Bun running run.js, with cdp.js, a CDP client, and cdp.md, what it does, beside it in <scratch>/js. Every worker has it.
const Sessions = "sessions"
Sessions is the drive of the harness's state files, read-only everywhere, in the harness's directory; only a Linux admin serves it. Every path of a drive is a constant of the worker's OS, so the harness names drives and never a path that root acts on.
Variables ¶
var Default = map[string][]string{"windows": {"pwsh", "js"}, "linux": {"bash", "js"}, "darwin": {"bash", "js"}}
Default is the interpreters of each OS: the shell it ships with, the default, then js, which every worker has.
Functions ¶
func Dial ¶
Dial makes this machine a worker of the harness on m: dial the harness's node at the address the last map gives it, serve until the connection ends, dial again, until the harness removes this worker. WireGuard proved both ends, so the hello carries no secret. A connection that ends within the longest wait, as a refused hello does, keeps the backoff; only one that held resets it. The js folder is readied beside it. The drives outlive every connection, and go with the mesh; Dial returns them at once, for a Windows service told to drop them.
func File ¶
File is the helper's side, run as the operator: read copies path to stdout, up to the bytes that tell it over maxRead, write copies stdin to path and makes its directory.
func Install ¶
Install makes this machine a worker at every boot: a systemd unit running Bin as root. Logs are in journalctl -u mainplaned.
func Installed ¶
Installed is what install left for the service: the join token and the operator, the user code runs as.
func JS ¶ added in v0.5.0
JS makes dir the js interpreter's: the embedded files written over, and Bun fetched when the one there is not BunVersion.
func Serve ¶
Serve answers one harness until the connection ends, then kills every environment. Jobs keep running. Each request runs in its own goroutine; runs that share an environment queue on it. An error frame with no id is the harness ending the connection on purpose, and its text is the error. The drives go to d, which reports on the connection while it lasts.
func Uninstall ¶ added in v0.1.1
func Uninstall() error
Uninstall stops the worker and removes its service, its drives, what a killed worker left of the mesh, Bin, which is also the CLI, and the state directory with the join token and the mesh keys. Scratch stays, it is the operator's, and so do the files of the drives this machine served.
func ValidDrive ¶ added in v0.5.0
Types ¶
type Desired ¶ added in v0.5.0
Desired is what the harness wants of a worker's drives, whole: the drives it serves and to which clients, and the drives it mounts. A worker that serves a drive and mounts it has it from its own disk.
type Drive ¶ added in v0.5.0
type Drive struct {
Name string `json:"name"`
Path string `json:"path"`
Serve bool `json:"serve,omitempty"` // served from Path, not mounted there
State string `json:"state"` // mounted, serving, waiting, error
Error string `json:"error,omitempty"` // why it waits or failed, in the OS's words
}
Drive is one drive as the worker reports it.
type Header ¶
type Header struct {
ID string `json:"id,omitempty"`
Kind string `json:"kind"`
Len int `json:"len"`
Session string `json:"session,omitempty"` // run, kill: environments live per session
Interp string `json:"interp,omitempty"` // run: empty means the worker's first
Timeout int `json:"timeout,omitempty"` // run: seconds before the environment is killed
Job string `json:"job,omitempty"` // run: a background job of this id, in an interpreter of its own
Path string `json:"path,omitempty"` // read, write; started, result: a job's log; update: mainplane-server, to update the harness beside the worker
Pid int `json:"pid,omitempty"` // started
Exit int `json:"exit,omitempty"` // result
Full string `json:"full,omitempty"` // result: file holding all the output, when over the limits
Name string `json:"name,omitempty"` // what sessions call this worker: its mesh name, set by the harness
OS string `json:"os,omitempty"` // hello
Arch string `json:"arch,omitempty"` // hello
Interps []string `json:"interps,omitempty"` // hello: first is the default
Scratch string `json:"scratch,omitempty"` // hello: where spilled output lands
Version string `json:"version,omitempty"` // hello: the release this worker was built from; update: the one to become
Drives []Drive `json:"drives,omitempty"` // hello, status: every drive this worker serves or mounts
DriveServer bool `json:"drive_server,omitempty"` // hello: this worker can serve drives
}
type Local ¶
Local is what this machine offers: its name, the join secret that lets it join the mesh, where spilled output lands, and which interpreters it has. The first interpreter is the default. Under a root service, Operator is the user code runs and files are touched as; nil is the worker's own user.
type Mount ¶ added in v0.5.0
type Mount struct {
Name string `json:"name"`
Server string `json:"server"`
Host string `json:"host"`
Addr netip.Addr `json:"addr"`
SMB *SMB `json:"smb,omitempty"` // how a Windows worker signs in to Server
}
Mount is a drive to mount from Server. Host is the server's long name, which macOS and Windows mount by: Finder and Explorer show it, and on Windows a short name that is also a Tailscale name resolves there.