version

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package version is the single place that knows which cloop build this is.

It exists because the answer had to be readable from two places that cannot see each other. The CLI knew its own version — cmd.Version, patched by ldflags at release time — but pkg/executor/agent sits below the CLI in the import graph and cannot import it, so the agent reported a frozen constant ("1", never once incremented) to the control plane instead. The fix is not a second constant; it is moving the answer below both of them.

Two constraints shape this file:

  • Version must stay a plain string var initialised to a *constant* expression. The Go linker's -X flag is documented to work only on such a variable; `var Version = something()` compiles fine and then silently ignores the stamp, which would reintroduce the exact bug this package exists to fix — a build that cannot say what it is.
  • Nothing here imports anything but the standard library, so every layer of cloop can ask.

Index

Constants

View Source
const (
	// SourceCommit: BuiltAt came from vcs.time, which is when the revision was
	// committed — the build itself happened at some later, unrecorded moment.
	SourceCommit = "commit"
	// SourceBinary: BuiltAt is the executable's mtime, i.e. when this file was
	// written or installed. The fallback for builds carrying no VCS data.
	SourceBinary = "binary"
)

Timestamp provenance. Reported alongside BuiltAt so a caller can label it truthfully instead of calling every timestamp a build date.

View Source
const DevVersion = "dev"

DevVersion is the value an unstamped build reports. Exported because both the comparison logic here and the release tooling's tests need to name it rather than repeat the literal.

View Source
const LegacyAgentVersion = "1"

LegacyAgentVersion is what agents built before build-version reporting sent in their hello frame: a hardcoded "1" that never changed.

It is recognised explicitly because it is actively misleading rather than merely absent. Parsed as a version it is major 1, which compares as *newer* than the hub's v0.0.x — so an agent running a year-old build would be reported as ahead of the control plane. Naming the sentinel turns the fleet's most misleading input into its clearest message.

Variables

View Source
var Version = DevVersion

Version is the build version, stamped at release time with

-ldflags "-X github.com/blechschmidt/cloop/pkg/version.Version=v1.2.3"

Keep the initialiser a constant string. See the package comment.

Functions

func Compare

func Compare(a, b string) (result int, ok bool)

Compare orders two versions: -1 if a precedes b, +1 if it follows, 0 if they are equal or not comparable. Ok reports whether both parsed.

Callers must check ok rather than treating 0 as "same build": "dev" versus "v1.2.3" is not a tie, it is a question this function cannot answer, and a caller that conflated the two would report a half-upgraded fleet as uniform.

func String

func String() string

String returns the build version, enriching an unstamped build with whatever the toolchain recorded about the checkout it came from.

A developer running `go build` gets "dev" from the linker, and a fleet of devices all reporting "dev" is no more diagnosable than a fleet all reporting "1". Go stamps VCS data into the binary by default, so a dev build can still identify itself as "dev+g4f7b5bc" — or "dev+g4f7b5bc.dirty" for an uncommitted tree, which is exactly the build an operator most needs to spot on a device.

Types

type BuildInfo added in v0.0.2

type BuildInfo struct {
	// Version is String(): the stamped release, the VCS-enriched dev string,
	// or bare DevVersion when the build carries neither.
	Version string
	// Revision is the full commit hash, empty when the build carries no VCS
	// data. Full rather than the 7 characters String() embeds, because a
	// dashboard showing a build can also link to it.
	Revision string
	// Modified reports that the checkout had uncommitted changes. Only
	// meaningful when Revision is set.
	Modified bool
	// BuiltAt is when this build came into being, as best as can be
	// determined; zero only if even the executable could not be stat'd.
	BuiltAt time.Time
	// BuiltAtSource is SourceCommit or SourceBinary, empty when BuiltAt is
	// zero. See the constants for what each actually measures.
	BuiltAtSource string
	// Identified reports whether the build can name the source it was made
	// from. False means every copy of this binary reports the same "dev" and
	// cannot be told apart — the case worth surfacing to an operator rather
	// than hiding behind a version string that looks like it means something.
	Identified bool
}

BuildInfo is the running binary's self-description.

func Build added in v0.0.2

func Build() BuildInfo

Build returns this binary's provenance, computed once.

type Skew

type Skew string

Skew classifies one agent's build against the control plane's.

const (
	// SkewUnknown: the agent reported no version at all. Either it predates
	// the hello field or something stripped it.
	SkewUnknown Skew = "unknown"
	// SkewLegacy: the agent reported LegacyAgentVersion, so it is running a
	// build from before agents knew their own version.
	SkewLegacy Skew = "legacy"
	// SkewNone: same build as the hub.
	SkewNone Skew = "none"
	// SkewUnversioned: one side is an unstamped dev build, so the two cannot
	// be ordered. Reported rather than hidden: a dev binary on a fleet device
	// is itself worth an operator's attention.
	SkewUnversioned Skew = "unversioned"
	// SkewPatch: trails the hub by a patch release only.
	SkewPatch Skew = "patch"
	// SkewBehind: trails the hub by a minor or major release. This is the
	// "materially trails" case — the one where protocol capabilities and
	// wire-visible behaviour plausibly differ.
	SkewBehind Skew = "behind"
	// SkewAhead: newer than the hub. Not merely cosmetic — an agent can speak
	// frames this control plane does not implement, and the usual cause is a
	// half-finished hub upgrade.
	SkewAhead Skew = "ahead"
)

func Classify

func Classify(hub, agent string) (Skew, string)

Classify compares an agent's reported build against the hub's and returns both the classification and the sentence to show an operator.

The note names the remediation because the classification alone sends somebody to a search box. It deliberately does *not* name a flag that does not exist: the previous message pointed at `cloop executor agent install --upgrade`, and an operator who tried it got an unknown-flag error from the one command they had been told would help.

func (Skew) Material

func (s Skew) Material() bool

Material reports whether this skew deserves an operator's attention now.

Patch drift across a large fleet is normal and flagging it would train operators to ignore the banner, which would cost them the case that matters.

Jump to

Keyboard shortcuts

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