Documentation
¶
Overview ¶
Package updatecheck reports whether a newer NinerLog build has been published. A component carrying a semantic version is compared against the newest GitHub release of its repository; one carrying only a build commit — what the :latest images have — is compared against the head of the tracked branch. A component with neither reports StateUnknown.
The API knows its own version and commit from link-time stamps; the frontend's are supplied by the browser with the request.
Index ¶
Constants ¶
const ( ComponentAPI = "api" ComponentFrontend = "frontend" )
Component names used in the API response and in metric labels.
const ( StateUpToDate = "up_to_date" StateUpdateAvailable = "update_available" StateUnknown = "unknown" )
Component states.
const ( // ChannelRelease compares a semantic version against the newest release. ChannelRelease = "release" // ChannelCommit compares a build commit against the tracked branch, which // is what a deployment running the :latest tag gets. ChannelCommit = "commit" )
How a component's state was determined.
const ( DefaultInterval = 24 * time.Hour DefaultAPIRepo = "fjaeckel/ninerlog-api" DefaultFrontendRepo = "fjaeckel/ninerlog-frontend" // DefaultBranch is the branch a :latest image is built from. DefaultBranch = "main" )
Defaults applied when the corresponding environment variable is unset.
const DevVersion = "dev"
DevVersion is the version reported by a binary that was neither stamped at build time nor given APP_VERSION.
Variables ¶
var ( // RunsTotal counts release check runs. Results: success, error. RunsTotal = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "update_check_runs_total", Help: "Total release check runs by result.", }, []string{"result"}, ) // ErrorsTotal counts failed release checks. Reasons: request, status, // decode, empty. ErrorsTotal = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "update_check_errors_total", Help: "Total release check failures by reason.", }, []string{"reason"}, ) // DurationSeconds tracks how long one release check run takes, covering // every component queried. DurationSeconds = prometheus.NewHistogram( prometheus.HistogramOpts{ Name: "update_check_duration_seconds", Help: "Latency of one release check run.", Buckets: prometheus.ExponentialBuckets(0.05, 2, 10), }, ) // LastSuccessTimestampSeconds is the Unix timestamp of the last run in // which every component's latest release was read. LastSuccessTimestampSeconds = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "update_check_last_success_timestamp_seconds", Help: "Unix timestamp of the last fully successful release check.", }, ) // UpdateAvailable reports whether a newer release exists for a component. // 1 = behind, 0 = current. Components: api. The frontend's running version // is known only to the browser, so it has no series here. UpdateAvailable = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "app_update_available", Help: "1 when a newer release is published for the component, 0 when current.", }, []string{"component"}, ) // CommitsBehind reports how many commits behind the tracked branch a // component's build is. Components: api. Absent for a build compared by // release version rather than by commit. CommitsBehind = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "app_commits_behind", Help: "Commits the tracked branch is ahead of the running build.", }, []string{"component"}, ) // LatestVersionInfo carries the newest published release per component. // Components: api, frontend. LatestVersionInfo = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "update_check_latest_version_info", Help: "Newest published release per component, as a labelled constant 1.", }, []string{"component", "version"}, ) )
Prometheus instrumentation for the release check. No series at all are emitted when the check is disabled.
Functions ¶
func RunningCommit ¶
func RunningCommit() string
RunningCommit returns the commit this binary was built from: the link-time stamp, then APP_COMMIT. Empty when neither is set or the value is not a commit SHA.
func RunningVersion ¶
func RunningVersion() string
RunningVersion returns the version of this binary: the link-time stamp, then APP_VERSION, then DevVersion.
Types ¶
type Checker ¶
type Checker struct {
// contains filtered or unexported fields
}
Checker holds the last known releases and commit comparisons and refreshes them on a timer.
func (*Checker) Interval ¶
Interval is how often the check repeats. Zero or less means it runs only at startup.
func (*Checker) Refresh ¶
Refresh looks up the newest release of every component, and the branch position of every build commit it knows about, and stores them. A lookup that fails leaves the previously known answer in place.
func (*Checker) Start ¶
Start runs a check immediately and then every configured interval until ctx is done. It returns at once; a disabled Checker starts nothing.
func (*Checker) Status ¶
Status reports every component against the last known releases, falling back to the branch position of its build commit. frontendVersion and frontendCommit describe the calling browser's build; a component that reports neither a semantic version nor a commit yields StateUnknown.
type Comparison ¶
type Comparison struct {
// Status is identical, ahead (the branch has moved on), behind (the build
// is ahead of the branch) or diverged.
Status string
// BehindBy is how many commits the branch is ahead of this build.
BehindBy int
URL string
// CheckedAt is when the comparison was made.
CheckedAt time.Time
}
Comparison is one build commit measured against the tracked branch head.
type ComponentStatus ¶
type ComponentStatus struct {
Name string
CurrentVersion string
// CurrentCommit is the short commit the component was built from, empty
// when it reported none.
CurrentCommit string
LatestVersion string
State string
// Channel is how State was reached: ChannelRelease or ChannelCommit.
// Empty when neither comparison could be made.
Channel string
ReleaseURL string
PublishedAt *time.Time
// BehindBy is how many commits behind the tracked branch this build is,
// set only on ChannelCommit.
BehindBy int
// CompareURL is the GitHub comparison between this build and the branch
// head, set only on ChannelCommit.
CompareURL string
}
ComponentStatus is one component's running build measured against the newest published release, or against the tracked branch when it carries no semantic version.
type Config ¶
type Config struct {
// Enabled is false when the deployment opted out of the check; a disabled
// Checker performs no outbound request and reports StateUnknown.
Enabled bool
// Interval between checks. Zero or less disables the periodic refresh,
// leaving only the check performed at startup.
Interval time.Duration
// APIRepo and FrontendRepo are "owner/name" GitHub repository paths.
APIRepo string
FrontendRepo string
// Branch is the branch the :latest images are built from; commit
// comparisons are made against its head.
Branch string
// APIVersion is the running version of this binary.
APIVersion string
// APICommit is the commit this binary was built from, empty when unstamped.
APICommit string
// BaseURL is the GitHub API root.
BaseURL string
// HTTPClient performs the release lookups.
HTTPClient *http.Client
}
Config configures a Checker.
type Status ¶
type Status struct {
Enabled bool
// UpdateAvailable is true when any component is behind its newest
// published release.
UpdateAvailable bool
LastCheckedAt *time.Time
// LastError is a coarse reason for the last failed check, empty when the
// last check succeeded or none has run.
LastError string
// Branch is the branch commit comparisons are made against.
Branch string
Components []ComponentStatus
}
Status is the result of the most recent check, evaluated against the versions currently running.