Help us shape the future of Go! Take the 2026 Go Developer Survey

worker

package
v0.5.8 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 35 Imported by: 0

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

View Source
const (
	Mounted = "mounted"
	Serving = "serving"
	Waiting = "waiting"
	Failed  = "error"
)
View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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

View Source
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

func Dial(m *mesh.Mesh, l Local) *drives

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 Encode

func Encode(w io.Writer, f Frame) error

func File

func File(op, path string) error

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

func Install(token string) error

Install makes this machine a worker at every boot: a systemd unit running Bin as root. Logs are in journalctl -u mainplaned.

func Installed

func Installed() (token string, op *user.User, err error)

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

func JS(dir string) error

JS makes dir the js interpreter's: the embedded files written over, and Bun fetched when the one there is not BunVersion.

func Serve

func Serve(conn net.Conn, l Local, d *drives) error

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

func ValidDrive(name string) bool

func Work

func Work(key string, l Local) error

Work is the worker: on the mesh, with its state in the state directory under a service and in scratch when run by hand, and dialing the harness, until the service manager stops it. Then it leaves the mesh, so no address, route, rule or hosts block stays behind.

Types

type Client added in v0.5.0

type Client struct {
	Name string     `json:"name"`
	Addr netip.Addr `json:"addr"`
	SMB  *SMB       `json:"smb,omitempty"` // a Windows client's user on this server
}

type Desired added in v0.5.0

type Desired struct {
	Serve []Export `json:"serve"`
	Mount []Mount  `json:"mount"`
}

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.

func (Drive) String added in v0.5.0

func (d Drive) String() string

type Export added in v0.5.0

type Export struct {
	Name    string   `json:"name"`
	Clients []Client `json:"clients"`
}

type Frame

type Frame struct {
	Header
	Body []byte
}

func Decode

func Decode(br *bufio.Reader) (Frame, error)
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

type Local struct {
	Name     string
	Secret   string
	Scratch  string
	Interps  []string
	Operator *user.User
}

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.

type SMB added in v0.5.0

type SMB struct {
	User     string `json:"user"`
	Password string `json:"password"`
}

SMB is a Windows worker's user on one server, the same for each of that server's drives, since Windows holds one credential per server. The harness derives the password from its key, so neither end stores it before the harness sends it.

Jump to

Keyboard shortcuts

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