Documentation
¶
Overview ¶
Package plugin is the control plane for the host's zip-native plugins: what each host is running, and the operations that change it — enable, disable, reload, and pin to (or roll back to) a named version.
A plugin here is a service that ships as its OWN binary and is composed in at run time by zip.Load, one child process per app on a private unix socket. The authoritative app->prefixes table is the generated manifest.Apps; the authoritative VERSION is the artifact's SHA-256, because that is the only identifier that cannot drift from the bits actually serving. This package invents neither — it reports the first and moves the second.
It used to be something else: a second plugin registry read from a CLOUD_PLUGINS JSON manifest, mounting wasm/goa modules and reverse proxies. Nothing in this repo, in universe, or in any chart ever set CLOUD_PLUGINS, so that lane mounted nothing in production while publishing an untyped GET /v1/plugins that reported the empty set — a second source of truth for "what is a plugin here" that was always empty, and invisible to OpenAPI, MCP and the CLI because it was untyped. It is gone; this is the one way.
Every route below can take production down, so every one of them is SuperAdmin-gated and every mutation is written to the hash-chained audit trail BEFORE it is reported as done. A deployment with no audit store refuses to mutate at all, the same way a credit grant does.
Index ¶
Constants ¶
const OriginEnv = "CLOUD_PLUGIN_ORIGIN"
OriginEnv names the base URL plugin artifacts are published under — registry.hanzo.ai's S3 store, or a releases URL. A version resolves to <origin>/<version>/binaries.json, which is the index CI already writes, so the mapping from a version to a digest has ONE author.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type ActionOut ¶ added in v1.801.299
type ActionOut struct {
Status string `json:"status"`
Msg string `json:"msg"`
Data []Result `json:"data"`
}
ActionOut is the envelope every mutation answers with. Data is per host and in the order applied, so a halted rollout reads as the prefix that succeeded followed by the one that did not.
type Drift ¶ added in v1.801.299
type Drift struct {
Name string `json:"name"`
Versions []string `json:"versions,omitempty"`
Running int `json:"running"`
Down int `json:"down"`
Disabled int `json:"disabled"`
Drifted bool `json:"drifted"`
}
Drift is one plugin's agreement across the fleet. Versions holds every distinct digest seen running; more than one means a rollout is incomplete or stuck, which is the single question this whole view exists to answer.
type Host ¶ added in v1.801.299
type Host struct {
// Host is the pod's stable id, and Addr where it was reached. Self is true
// for the host that answered the request.
Host string `json:"host"`
Addr string `json:"addr,omitempty"`
Self bool `json:"self,omitempty"`
// Err is set when a peer could not be reached. Its plugins are then
// unknown, which is NOT the same as none, so the list stays empty and the
// drift below refuses to conclude anything from it.
Err string `json:"error,omitempty"`
Plugins []zip.Status `json:"plugins"`
}
Host is one host's own account of what it is running. Reported per host rather than merged, because during a rollout the hosts disagree BY DESIGN and a merged view hides exactly the state an operator is watching for.
type ListIn ¶ added in v1.801.299
type ListIn struct {
// Scope "host" answers for THIS host only. Default "fleet" fans out to every
// live peer. A peer answers a host-scoped read, which is what stops the
// fan-out recursing.
Scope string `json:"scope"`
}
ListIn is the GET /v1/admin/plugins query.
type ListOut ¶ added in v1.801.299
type ListOut struct {
Status string `json:"status"`
Msg string `json:"msg"`
Data []Host `json:"data"`
Drift []Drift `json:"drift,omitempty"`
Data2 *int `json:"data2,omitempty"`
}
ListOut is the fleet board.
type NameIn ¶ added in v1.801.299
type NameIn struct {
// Name is the app, from the path.
Name string `json:"name"`
// Scope "host" applies here only; default "fleet" applies everywhere.
Scope string `json:"scope"`
}
NameIn addresses one plugin by name, for the operations that take nothing else.
type ReloadIn ¶ added in v1.801.299
type ReloadIn struct {
// Name is the app, from the path. It must be one the manifest declares.
Name string `json:"name"`
// Version is a release tag, resolved to a URL and digest through the
// origin's binaries.json index — the same index CI publishes, so there is
// no second table mapping versions to digests.
Version string `json:"version"`
// URL is the artifact directly, for an origin with no index. Sum is its hex
// SHA-256 and is REQUIRED with it: zip refuses an unverified download, and
// so does this.
URL string `json:"url"`
Sum string `json:"sum"`
// Scope "host" applies here only. Default "fleet" rolls it out one host at
// a time, halting on the first host that fails to come up.
Scope string `json:"scope"`
}
ReloadIn names an artifact to run. Exactly one of Version or URL+Sum, or neither to restart the artifact already loaded — which is how a wedged plugin is bounced without changing what it runs.