Documentation
¶
Overview ¶
Package agentinstall is one-command node onboarding (forward-sdk.md, section 9): the install script Control serves at /install.sh, its release signature, the release metadata the script reads from /install/agent.env, and the install commands the node page copies.
The script is static: the same bytes are embedded here, served by every Control and published as the release asset agent-install.sh, so one release signature (Ed25519 by the official package root, the format of the packages archive's .sig) verifies all copies. What differs per Control — its address, the node and the one-time token — travels in the command line; what differs per release — the Agent version, mirrors and checksums — comes from /install/agent.env.
Index ¶
- Constants
- Variables
- func ArtifactPath(dir, tag, asset string) (string, error)
- func LoadSignature(path, publicKeyBase64 string) ([]byte, error)
- func ParseDigest(data []byte) (string, bool)
- func ReleaseFilePath(dir, tag, name string) (string, error)
- func RenderCommand(input CommandInput) string
- func ShellQuote(value string) string
- func UpgradeArtifacts(artifactDir, tag, publicKeyBase64, controlURL string) ([]agentcontrol.UpgradeArtifact, error)
- func ValidNode(node string) bool
- func VerifySignature(script, signature []byte, publicKeyBase64 string) error
- type Command
- type CommandInput
- type Metadata
- type OfflineBundle
- type Settings
- type SettingsInput
Constants ¶
const ( // ScriptAssetName is the script's name among Control's release assets. ScriptAssetName = "agent-install.sh" // SignatureAssetName is its detached signature. SignatureAssetName = ScriptAssetName + ".sig" // AgentReleaseBase is where GitHub serves Agent release assets. AgentReleaseBase = "https://github.com/AnixOps/anix-agent/releases/download" // ControlReleaseBase is where GitHub serves Control release assets. ControlReleaseBase = "https://github.com/AnixOps/anix-control/releases/download" // MetadataFormat is the version of the /install/agent.env format. MetadataFormat = "1" )
const ( MirrorControl = "control" MirrorCN = "cn" MirrorGitHub = "github" )
Mirrors the install command can name (--mirror).
const ( SumsAssetName = "SHA256SUMS" SumsSignatureAssetName = SumsAssetName + ".sig" // MetadataFileName is the bundle's copy of /install/agent.env. MetadataFileName = "agent.env" // BundleScriptName is the install script inside a bundle. BundleScriptName = "install.sh" )
Release file names besides the per-architecture assets: the checksums of every asset and its signature (anix-agent's release job).
Variables ¶
var Assets = map[string]string{
"amd64": "anix-agent-linux-64.zip",
"arm64": "anix-agent-linux-arm64-v8a.zip",
}
Assets maps an architecture to the Agent's release asset.
var ErrNoSignature = errors.New("no valid install script signature")
ErrNoSignature means no valid signature is available for Script.
var ErrOfflineBundle = errors.New("cannot make the offline bundle")
ErrOfflineBundle means an offline bundle cannot be made.
var ErrUpgradeRelease = errors.New("the Agent release cannot be pushed")
ErrUpgradeRelease means the Agent release cannot be pushed to nodes.
var Mirrors = []string{MirrorControl, MirrorCN, MirrorGitHub}
Mirrors lists the mirrors in the order the node page shows them.
var ( // ReleaseTagPattern matches release tags (Control's and the Agent's). ReleaseTagPattern = regexp.MustCompile(`^v[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta|rc)(\.[0-9]+)?)?$`) )
var Script []byte
Script is the install script, byte for byte the release asset.
Functions ¶
func ArtifactPath ¶
ArtifactPath confines a release asset to dir/<tag>/<asset>, refusing any name but a release tag and an Agent asset (or its .dgst and .sig).
func LoadSignature ¶
LoadSignature reads the signature file and returns it when it verifies Script with the public key.
func ParseDigest ¶
ParseDigest returns the SHA-256 of an Agent .dgst file (`openssl dgst` lines with the file name removed: "SHA2-256= <hex>" or "SHA256= <hex>").
func ReleaseFilePath ¶
ReleaseFilePath confines a release file to dir/<tag>/<name>: an Agent asset, its .dgst or .sig, SHA256SUMS or SHA256SUMS.sig. Unlike ArtifactPath it admits the checksum files, which Control does not serve.
func RenderCommand ¶
func RenderCommand(input CommandInput) string
RenderCommand returns the one-line install command:
curl -fsSL <script> | sudo bash -s -- --control <url> --node <node> --token <t> [--mirror m]
The "--" ends bash's own options, so every later word reaches the script. curl gets -g (no URL globbing) when the URL has an IPv6 literal.
func ShellQuote ¶
ShellQuote quotes value for a POSIX shell: single quotes, with embedded single quotes closed, escaped and reopened. Words made only of safe characters stay bare, so commands stay readable.
func UpgradeArtifacts ¶
func UpgradeArtifacts(artifactDir, tag, publicKeyBase64, controlURL string) ([]agentcontrol.UpgradeArtifact, error)
UpgradeArtifacts verifies the Agent release tag in artifactDir for an upgrade campaign (forward-sdk.md section 9, O4) and returns what the agent.upgrade operation carries for every architecture: each asset must be there with its .sig, SHA256SUMS with SHA256SUMS.sig, both signatures valid with publicKeyBase64 (plugins.official_public_key), and each asset's SHA-256 listed in SHA256SUMS. controlURL is the https address nodes reach; the artifacts are served at <controlURL>/install/agent/<tag>/<asset> (the control mirror).
func ValidNode ¶
ValidNode reports whether node is an Agent node name the command can carry: proxy-<id> or forward-<id>.
func VerifySignature ¶
VerifySignature checks a detached signature of script: base64 of the raw Ed25519 signature over its exact bytes (whitespace ignored), by the base64 raw public key (plugins.official_public_key).
Types ¶
type Command ¶
type Command struct {
Mirror string `json:"mirror"`
Command string `json:"command"`
// Available is false when the mirror is not set up; the command still
// works, with the fallback Note describes.
Available bool `json:"available"`
Note string `json:"note,omitempty"`
}
Command is one install command line for a mirror.
type CommandInput ¶
type CommandInput struct {
// ControlURL is the Control address nodes reach (scheme://host[:port]).
ControlURL string
// ScriptURL is where the command downloads the script.
ScriptURL string
Node string
Token string
Mirror string
}
CommandInput is what an install command carries.
type Metadata ¶
type Metadata struct {
AgentVersion string
GRPCTarget string
// Sources maps a mirror to the base URL of <tag>/<asset>; a mirror that
// is not set up is absent.
Sources map[string]string
// SHA256 maps an asset to its digest, when Control holds the release.
SHA256 map[string]string
}
Metadata is what /install/agent.env tells the script.
type OfflineBundle ¶
type OfflineBundle struct {
AgentVersion string `json:"agent_version"`
Arch string `json:"arch"`
Asset string `json:"asset"`
SHA256 string `json:"sha256"`
GRPCTarget string `json:"grpc_target"`
Files []string `json:"files"`
}
OfflineBundle describes a written bundle.
func WriteOfflineBundle ¶
func WriteOfflineBundle(w io.Writer, s Settings, arch, publicKeyBase64 string, scriptSignature []byte) (OfflineBundle, error)
WriteOfflineBundle writes the offline bundle of arch to w: a tar.gz of flat files that `install.sh --offline` reads,
agent.env /install/agent.env of this Control <asset>, <asset>.sig the Agent release zip of arch and its signature SHA256SUMS, SHA256SUMS.sig the release checksums and their signature install.sh[, install.sh.sig] the install script (and its release signature)
from the release in s.ArtifactDir/<tag>/. Both signatures must verify with publicKeyBase64 (plugins.official_public_key) and SHA256SUMS must list the asset's digest, which the installer checks again on the node. scriptSignature is the script's verified release signature, or nil.
type Settings ¶
type Settings struct {
// ControlURL is the Control address nodes reach, without a trailing
// slash.
ControlURL string
// GRPCTarget is the gRPC listener's host:port nodes dial.
GRPCTarget string
// AgentVersion is the Agent release tag.
AgentVersion string
// ControlVersion is Control's release tag (where the github mirror's
// script is published).
ControlVersion string
ArtifactDir string
CNMirrorURL string
}
Settings is a Control's onboarding configuration, resolved.
func ResolveSettings ¶
func ResolveSettings(in SettingsInput) (Settings, error)
ResolveSettings resolves a Control's onboarding settings: the https address nodes reach, the gRPC target (agent_install.grpc_target, else that address's host and grpc.port), and the Agent release (agent_install. agent_version, else "v" + Control's version, H25).
func (Settings) Commands ¶
Commands renders the command for every mirror. node and token are validated by the caller.
type SettingsInput ¶
type SettingsInput struct {
// ControlURL is agent_install.public_url, or the request's origin.
ControlURL string
GRPCTarget string
GRPCPort int
AgentVersion string
ReleaseVersion string
ArtifactDir string
CNMirrorURL string
}
SettingsInput is what ResolveSettings needs from a Control's configuration (agent_install, grpc.port) and build.