plugin

package
v1.801.468 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package plugin is what each host is running, and how to change it: enable, disable, reload, or pin a service to a version.

It is the control plane for the host's zip-native plugins, and a pin rolls back as readily as it rolls forward.

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 hand-authored 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. That lane is gone from here.

GET /v1/plugins still exists, in apps/tools, and it answers the SAME question from a different source: cloud.Subsystems(), the snapshot taken at boot. It therefore cannot see the effect of the enable/disable/reload below, which is why this surface — live, per host, keyed on the running artifact's digest — is the one to read when the answer has to be true right now.

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

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

func Mount

func Mount(app cloud.Router, deps cloud.Deps) error

Mount registers the control plane. It needs the concrete *zip.App rather than the Router interface, because the plugin set is app state — Plugins, Reload and Unload are the app's, and no interface should widen to carry them.

func Routes

func Routes(z *zip.App, o *ops)

Routes is separate from Mount so the surface can be registered against a bare app in a test without a full Deps.

Types

type ActionOut

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

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

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

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

type ListOut struct {
	Status string  `json:"status"`
	Msg    string  `json:"msg"`
	Data   []Host  `json:"data"`
	Drift  []Drift `json:"drift,omitempty"`
	Total  *int    `json:"total,omitempty"`
}

ListOut is the fleet board.

type NameIn

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

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.

type Result

type Result struct {
	Host    string `json:"host"`
	OK      bool   `json:"ok"`
	Version string `json:"version,omitempty"`
	Msg     string `json:"msg,omitempty"`
}

Result is one host's outcome for one action.

Jump to

Keyboard shortcuts

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