Documentation
¶
Overview ¶
Package upgrade fetches the latest release for stable, beta and edge channels from a GitHub repo, compares versions, and runs the read-only checks that gate a self-upgrade.
Index ¶
- Constants
- func BackupMaxAge(lookup func(string) (string, bool)) time.Duration
- func Blocked(checks []Check) bool
- func EdgeImage(repo string) string
- func HumanDuration(d time.Duration) string
- func IsProductTag(tag string) bool
- func UpdateAvailable(currentVersion string, latest *Release) bool
- func ValidChannel(c string) bool
- type Cache
- type Check
- type Fetchers
- type Fix
- type HistoryAsset
- type HistoryRelease
- type Inputs
- type KnownBad
- type Manifest
- type Release
- type SchemaVerdict
Constants ¶
const ( ChannelStable = "stable" ChannelBeta = "beta" ChannelEdge = "edge" )
Update channels a running build can compare itself against. ChannelStable is GitHub's own "latest release" concept (unchanged default behavior); ChannelBeta and ChannelEdge follow release.yml's own image-channel job scheme: a hyphenated SemVer tag (e.g. v1.2.3-beta.1) gets :beta, a main push gets :edge.
const ( KindRelease = "release" KindEdgeImage = "edge_image" )
Release kinds. An edge pseudo-release is a commit on main shipped as the moving container image tag, never a GitHub release with binaries.
const ( StatusOK = "ok" StatusWarn = "warn" StatusFail = "fail" StatusUnknown = "unknown" // StatusPending is a retryable block: the condition is expected to clear // on its own (a release still being published), so it reads as waiting, // not as a failure. StatusPending = "pending" // StatusSkipped marks a check that does not apply to this target. It // never blocks. StatusSkipped = "skipped" )
Check statuses.
const ( FixBackupNow = "backup_now" FixRecheck = "recheck" FixCommand = "command" )
Fix actions a check can carry. The dashboard renders each as a button, the CLI prints the matching command.
const ( KindReleaseIncomplete = "release_incomplete" KindReleaseUnsigned = "release_unsigned" KindBackupStale = "backup_stale" KindBackupMissing = "backup_missing" )
Check kinds that refine a code for callers that act on them.
const ( ChecksumsAsset = "checksums.txt" SignatureAsset = "checksums.txt.sigstore.json" )
Asset names the release workflow publishes next to the binaries.
const ChannelAll = "all"
ChannelAll is the history view that mixes stable and pre-releases.
const DefaultCacheTTL = time.Hour
DefaultCacheTTL is how long a Cache entry stays fresh before a caller should fetch again: shared by GET /api/v1/updates, updatecheck.Scheduler, and alerting's kind=version_skew evaluator, so none of them hits GitHub more often than this regardless of its own call cadence.
const EdgeImageTag = "edge"
EdgeImageTag is the moving image tag release.yml pushes on every main push.
const EdgeNoSignatureNote = "Edge builds are container images, not signed binaries, so there are no checksums to verify."
EdgeNoSignatureNote explains why release checks are skipped for edge.
const ManifestAsset = "release-manifest.json"
ManifestAsset is the per-release file the release workflow publishes with the binary's own `version --json` output, so a release's schema version is known without downloading and running it.
const VerifierTool = "cosign"
VerifierTool is the program the installer uses to check the release signature.
Variables ¶
This section is empty.
Functions ¶
func BackupMaxAge ¶ added in v0.2.0
BackupMaxAge is how old the newest control plane backup may be before an upgrade is blocked, from APP_UPGRADE_MAX_BACKUP_AGE, default 26h.
func Blocked ¶
Blocked reports whether any check stops an upgrade: a failure, or a retryable pending condition.
func EdgeImage ¶ added in v0.2.0
EdgeImage returns the image reference the edge channel follows for repo ("owner/name").
func HumanDuration ¶ added in v0.2.0
HumanDuration renders d as "11h 18m" or "2d 3h", at minute precision.
func IsProductTag ¶ added in v0.2.0
IsProductTag reports whether tag names a platform release (v1.2.3 or v0.2.0-beta.19). Nested Go module releases such as kit/v0.1.0 share the repository's releases list but are not installable versions.
func UpdateAvailable ¶
UpdateAvailable reports whether latest represents a newer build than currentVersion. A "dev" build never reports an update available: there is no meaningful newer build to compare an unreleased build against. Two SemVer tags compare by precedence (beta.9 < beta.15); anything else (edge's main-<sha>) falls back to inequality.
func ValidChannel ¶
ValidChannel reports whether c is one of the three recognized channels.
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache holds the last successful channel lookup, so GET /api/v1/updates and internal/updatecheck.Scheduler don't hit GitHub on every call. Keyed by channel (not just a bare TTL) so switching channels never serves a stale result cached for a different one.
func (*Cache) Expire ¶ added in v0.2.0
func (c *Cache) Expire()
Expire marks the cached result stale so the next lookup refetches, while Stale still serves it if that fetch fails.
type Check ¶
type Check struct {
Code string `json:"code"`
Name string `json:"name"`
Status string `json:"status"`
Message string `json:"message"`
// Kind refines Code (for example release_incomplete versus release_unsigned).
Kind string `json:"kind,omitempty"`
// Retryable is set when waiting and re-checking is the right response.
Retryable bool `json:"retryable,omitempty"`
// Protects says in one line what this check keeps safe.
Protects string `json:"protects,omitempty"`
// Hint says in plain language what to do when the check is not ok.
Hint string `json:"hint,omitempty"`
Fix *Fix `json:"fix,omitempty"`
}
Check is one preflight result.
type Fetchers ¶
type Fetchers struct {
Stable func(context.Context) (*Release, error)
Beta func(context.Context) (*Release, error)
Edge func(context.Context) (*Release, error)
}
Fetchers groups one fetch function per channel, the same overridable seam Router.fetchLatestRelease (internal/api/updates.go) already establishes for testing without a real outbound call.
func DefaultFetchers ¶
DefaultFetchers wires the three real GitHub lookups above for repo ("owner/name").
type HistoryAsset ¶
type HistoryAsset struct {
Name string `json:"name"`
Size int64 `json:"size"`
URL string `json:"url"`
}
HistoryAsset is one downloadable file on a release.
type HistoryRelease ¶
type HistoryRelease struct {
Tag string `json:"tag"`
URL string `json:"url"`
PublishedAt string `json:"published_at"`
Body string `json:"body"`
Prerelease bool `json:"prerelease"`
Assets []HistoryAsset `json:"assets"`
}
HistoryRelease is one published GitHub release, with the asset details a rollback plan needs.
func FetchHistory ¶
FetchHistory lists the newest limit releases of repo for channel. An empty result with a nil error means GitHub has none for that channel.
func (HistoryRelease) Asset ¶
func (r HistoryRelease) Asset(name string) (HistoryAsset, bool)
Asset returns the asset called name.
func (HistoryRelease) AssetNames ¶
func (r HistoryRelease) AssetNames() []string
AssetNames lists every asset name, for Run's Inputs.
type Inputs ¶
type Inputs struct {
Lookup func(string) (string, bool)
DockerVersion func(ctx context.Context) (string, error)
FreeBytes func() (int64, error)
NewestBackup func() (time.Time, bool, error)
Now time.Time
AssetNames []string
ReleaseKnown bool
// ReleasePublishedAt is when the release went public, zero if unknown.
// It separates a release still being published from a broken one.
ReleasePublishedAt time.Time
// ReleaseKind is Release.Kind of the target; an edge image has no
// binaries, so the checksum and signature checks do not apply to it.
ReleaseKind string
// LookPath finds the signature verifier (cosign) on the host; nil reports unknown.
LookPath func(string) (string, error)
}
Inputs is everything Run needs, injected so tests use fakes.
type Release ¶
type Release struct {
Tag string
URL string
PublishedAt string
Body string
AssetNames []string
// Kind is KindRelease (or empty) for a GitHub release and KindEdgeImage
// for the edge channel's pseudo-release. Commit and Image are set only
// for the latter.
Kind string
Commit string
Image string
}
Release is the subset of a GitHub release, or (for the edge channel) a main-branch commit treated as a pseudo-release, that a channel-aware update check needs.
func FetchLatestBeta ¶
FetchLatestBeta returns the highest-semver prerelease from GitHub's releases list, skipping drafts. nil, nil means no prerelease has ever been published.
func FetchLatestEdge ¶
FetchLatestEdge fetches the latest commit on main and reports it as a pseudo-release tagged "main-<short sha>", matching release.yml's own image-channel job scheme for what a main push's Docker image tag is (IMAGE_VERSION: main-<sha>). nil, nil means the lookup found nothing (an empty or inaccessible repo).
func FetchLatestStable ¶
FetchLatestStable returns the highest-semver non-prerelease, non-draft platform release. With no stable release it falls back to the highest prerelease (install.sh's rule). nil, nil means nothing has been published.
type SchemaVerdict ¶
type SchemaVerdict string
SchemaVerdict says whether a target binary can run on the current database.
const ( // VerdictBinaryOnly: the target supports the database as it is (equal). VerdictBinaryOnly SchemaVerdict = "binary_only" // VerdictForward: the target is newer and will migrate the database. VerdictForward SchemaVerdict = "forward" // VerdictRestoreRequired: the target is older than the database and would // refuse to start; only a backup restore (losing newer data) works. VerdictRestoreRequired SchemaVerdict = "restore_required" // VerdictUnknown: the target's schema version could not be determined. VerdictUnknown SchemaVerdict = "unknown" )
Verdicts for a rollback or re-roll against the database's schema version.
func VerdictFor ¶
func VerdictFor(dbVersion, targetVersion int) SchemaVerdict
VerdictFor compares the database's schema version with the target binary's. A negative value means unknown on that side.