Documentation
¶
Overview ¶
Package upgrade holds the parts of an in-place KubeSolo upgrade that both the kubesolo binary and kubesoloctl need: where the upgrade keeps its files, the record of what it is doing and what it last did, the lock that makes it the only writer, and fetching and checking a release before anything is touched.
It is pure Go. Work that needs SQLite or a Kubernetes client — the backup, the datastore dry-run, the health gate — lives in internal/upgrade/executor, which only the kubesolo binary links. kubesoloctl is built without cgo.
The order of an upgrade is the point of the design: everything that can fail does so while KubeSolo is still running and untouched.
fetch → checksum → arch/libc → version → disk space → backup → dry-run
↓
stop → replace → start → verify
An abort anywhere before the arrow leaves a host that never noticed.
Index ¶
- Constants
- Variables
- func BinaryVersion(ctx context.Context, path string) (string, error)
- func CheckBinary(path string, info *detect.SystemInfo) error
- func CommitBackup(l Layout, staged string) error
- func EnsureProcessKillMode() (bool, error)
- func EscapeServiceCgroup()
- func FileSHA256(path string) (string, error)
- func FreeBytes(path string) (uint64, error)
- func Install(src, dst string) error
- func InstallGuard(l Layout, svc *Service) error
- func LoadKnownGoodConfig(l Layout) ([]byte, error)
- func MainPIDs(binary string) []int
- func NewRunID() string
- func PatchOpenRC(def string, l Layout) (string, error)
- func PatchRunScript(def string, l Layout) (string, error)
- func PatchSysV(def string, l Layout) (string, error)
- func PatchUpstart(def string, l Layout) (string, error)
- func RecordStarted(l Layout, raw []byte) error
- func ReleaseBaseURL() string
- func ReleaseChecksum(ctx context.Context, version, name string) (sum, source string, err error)
- func RemoveGuardHook()
- func RenderGuard(l Layout) ([]byte, error)
- func ReportedVersion(output string) (string, bool)
- func RequireFree(path string, need uint64) error
- func SaveKnownGoodConfig(l Layout, raw []byte) (bool, error)
- func SaveState(l Layout, s *State) error
- func SettleBackups(l Layout, op Operation, result Result)
- func SpawnExecutor(exe, jobFile string, init detect.InitSystem) error
- func StartedPID(l Layout) int
- func UnderSystemdUnit() bool
- func ValidateHealthTimeout(seconds int) error
- func VersionFromArchiveName(path string) (string, bool)
- func WriteFileAtomic(path string, data []byte, mode os.FileMode) error
- func WriteJob(l Layout, j Job) (string, error)
- type Accepted
- type AgentStatus
- type Health
- type Job
- type Layout
- func (l Layout) AdminKubeconfig() string
- func (l Layout) AttemptsFile() string
- func (l Layout) BackupBinary() string
- func (l Layout) BackupConfigFile() string
- func (l Layout) BackupDatastore() string
- func (l Layout) BackupDir() string
- func (l Layout) BackupManifest() string
- func (l Layout) BackupServiceDefinition() string
- func (l Layout) Datastore() string
- func (l Layout) DatastoreDir() string
- func (l Layout) Dir() string
- func (l Layout) FailedConfig() string
- func (l Layout) GuardLog() string
- func (l Layout) GuardScript() string
- func (l Layout) JobFile(id string) string
- func (l Layout) KnownGoodConfig() string
- func (l Layout) LockFile() string
- func (l Layout) PendingFile() string
- func (l Layout) PreviousBackupDir() string
- func (l Layout) RunLog(id string) string
- func (l Layout) RunStagingDir(id string) string
- func (l Layout) StagingDir() string
- func (l Layout) StartedConfig() string
- func (l Layout) StartedFile() string
- func (l Layout) StateFile() string
- type Lock
- type Logf
- type Manifest
- type Operation
- type Phase
- type Request
- type Result
- type Run
- type Service
- type Staged
- type State
- type Status
- type UpgradeStatus
- type Version
Constants ¶
const BinaryPath = "/usr/local/bin/kubesolo"
BinaryPath is where every installer puts the kubesolo binary.
const CheckDatastoreFlag = "--upgrade-check-datastore"
CheckDatastoreFlag runs the kubesolo binary as the datastore dry-run. Its value is the copy of the datastore to migrate and check.
const DefaultHealthTimeout = 10 * time.Minute
DefaultHealthTimeout is generous because the slowest supported hosts take minutes to start the control plane and import images.
const DefaultReleaseBaseURL = "https://github.com/portainer/kubesolo/releases/download"
DefaultReleaseBaseURL is where releases are downloaded from.
const ExecutorFlag = "--upgrade-executor"
ExecutorFlag runs the kubesolo binary as the upgrade executor. Its value is a job file.
const MaxBootAttempts = 3
MaxBootAttempts is how many starts of a new binary the boot guard allows before it restores the previous one. Each start that dies before KubeSolo reports itself healthy uses one.
const MinHealthTimeout = time.Minute
MinHealthTimeout is the shortest health-gate timeout a request may ask for. The gate passes only once KubeSolo has run healthy for 30s as one process, after it has started, so a shorter timeout can never be met.
const SumsFile = "SHA256SUMS"
SumsFile is the checksum file published with each release, in sha256sum format, and expected next to an archive staged by hand.
Variables ¶
var ErrBusy = errors.New("another upgrade, rollback or restart is in progress")
ErrBusy is returned when another upgrade or rollback holds the lock.
var ErrContainerMode = errors.New("KubeSolo is running in a container, which cannot upgrade itself; run `kubesoloctl upgrade` on the host instead")
ErrContainerMode is returned on a KubeSolo running in a container. The container cannot replace its own image; kubesoloctl upgrades it from the host.
var ErrNoChecksum = errors.New("no checksum")
ErrNoChecksum is returned for a local source with no checksum to check it against.
Functions ¶
func BinaryVersion ¶
BinaryVersion runs `<path> --version` and returns the version it reports.
func CheckBinary ¶
func CheckBinary(path string, info *detect.SystemInfo) error
CheckBinary confirms path is an executable for this host: the right machine architecture and, for a dynamically linked binary, the right C library. Running a binary for another architecture fails with "exec format error"; one for the other libc fails with "not found", which is far less obvious.
func CommitBackup ¶
CommitBackup makes the backup in staged the current one, keeping the one it replaces as the previous backup until the upgrade is settled.
func EnsureProcessKillMode ¶
EnsureProcessKillMode makes a systemd kubesolo unit stop with KillMode=process before anything stops it, and reports whether it changed anything. Units install.sh wrote before it set KillMode use systemd's default, control-group, which kills the containerd shims on stop but not the containers: they carry on running where no KubeSolo can reattach to them, and the next one starts a second copy of every pod. A drop-in applies to the running unit once systemd has reloaded.
func EscapeServiceCgroup ¶
func EscapeServiceCgroup()
EscapeServiceCgroup moves the calling process to the root cgroup, where stopping the KubeSolo service cannot reach it. Init systems that track a service by cgroup (OpenRC with rc_cgroup_cleanup, s6 and runit with cgroup supervision) kill everything left in it on stop; a new session is not enough. It is best effort: without permission or cgroups there is nothing to escape.
func FileSHA256 ¶
FileSHA256 returns the hex SHA-256 of a file.
func FreeBytes ¶
FreeBytes is the space available to an unprivileged user on the filesystem holding path. Root can use the reserved blocks too, but an upgrade that relies on them leaves the host with a full disk.
func Install ¶
Install puts a staged binary in place at dst atomically: a copy beside dst, then a rename over it. A running process keeps the old inode.
func InstallGuard ¶
InstallGuard writes the guard script and makes sure the service runs it before KubeSolo starts. It is idempotent. Daemon mode has no init system to restart a failed KubeSolo, so there is nothing for a guard to count, and the executor alone watches the new version.
func LoadKnownGoodConfig ¶ added in v1.2.3
LoadKnownGoodConfig returns the known-good configuration, or nil when none has been recorded.
func MainPIDs ¶
MainPIDs returns the running KubeSolo processes started from binary: those whose executable is binary, including one that has since been replaced on disk. The upgrade's own processes, which may run from the same binary, are excluded, as is the caller.
func PatchOpenRC ¶
PatchOpenRC adds a start_pre to an OpenRC service script. openrc-run sources the whole script, so a function appended at the end is defined like any other. A script that already has its own start_pre is not one KubeSolo wrote, and is left for a human.
Scripts written before KubeSolo sent its output to syslog also get the loggers: without them OpenRC discards everything KubeSolo logs. Each stream is checked on its own, and one the script already sends somewhere is left alone.
func PatchRunScript ¶
PatchRunScript runs the guard before the exec line of an s6 or runit run script.
func PatchUpstart ¶
PatchUpstart adds a pre-start script to an Upstart job.
func RecordStarted ¶ added in v1.2.3
RecordStarted notes that this process has finished starting: every component is up and every add-on, the Portainer agent among them, has been deployed from raw, the configuration file it started with. It is readable by root only: it holds the edge key.
func ReleaseBaseURL ¶
func ReleaseBaseURL() string
ReleaseBaseURL is where releases are downloaded from: DefaultReleaseBaseURL, or a mirror named by KUBESOLO_RELEASE_BASE_URL. A mirror must publish SHA256SUMS with each release; only GitHub can stand in for it.
func ReleaseChecksum ¶
ReleaseChecksum finds the published checksum of a release asset: from the release's SHA256SUMS, or, for a GitHub release without one, from the digest GitHub computed for the asset.
func RemoveGuardHook ¶
func RemoveGuardHook()
RemoveGuardHook removes the systemd drop-in. The hooks patched into other service definitions go with those definitions on uninstall.
func RenderGuard ¶
RenderGuard returns the boot guard script for a layout.
func ReportedVersion ¶
ReportedVersion extracts the version from `kubesolo --version` output.
func RequireFree ¶
RequireFree returns an error unless the filesystem holding path has at least need bytes available.
func SaveKnownGoodConfig ¶ added in v1.2.3
SaveKnownGoodConfig records raw, the configuration file KubeSolo started with, as known to be good. It is written only when it differs from the one recorded, and readable by root only: it holds the edge key.
func SaveState ¶
SaveState writes the state file atomically: a crash mid-write leaves the previous state, never a truncated one.
func SettleBackups ¶
SettleBackups decides which backup to keep once an upgrade has ended.
The backup an upgrade takes is of the version it replaces. Once the upgrade has succeeded it is the rollback target, and the one before it can go. If the upgrade was rolled back, the version it was taken of is the one running again, so it is useless as a target, and the previous backup — of the version before that — is the one worth keeping. A failed upgrade keeps both: someone has to look, and the backups are what they will need.
func SpawnExecutor ¶
func SpawnExecutor(exe, jobFile string, init detect.InitSystem) error
SpawnExecutor starts `exe --upgrade-executor=<jobFile>` so that it outlives the KubeSolo service it is about to stop.
The caller may be KubeSolo itself (the API), and stopping KubeSolo stops everything in its service. Under systemd the executor runs as its own transient unit; elsewhere it starts a new session, and moves itself out of the service's cgroup once running (EscapeServiceCgroup).
func StartedPID ¶ added in v1.2.3
StartedPID is the PID RecordStarted last recorded, or 0.
func UnderSystemdUnit ¶
func UnderSystemdUnit() bool
UnderSystemdUnit reports whether the process was started by systemd as a service, as SpawnExecutor's transient unit is.
func ValidateHealthTimeout ¶
ValidateHealthTimeout checks a healthTimeoutSeconds value: 0 for the default, or from MinHealthTimeout up to the longest duration that can be represented. Upgrades and rollbacks both carry one. The seconds are compared as they are: converting first could overflow, and a wrapped value can land on a plausible timeout.
func VersionFromArchiveName ¶
VersionFromArchiveName returns the version in a release archive's name, such as v1.2.3 in kubesolo-v1.2.3-linux-arm64-musl.tar.gz or kubesolo-v1.2.3-linux-amd64-offline.tar.gz.
func WriteFileAtomic ¶
WriteFileAtomic writes data to a temporary file beside path, syncs it, and renames it over path.
Types ¶
type Accepted ¶
type Accepted struct {
ID string `json:"id"`
Operation Operation `json:"operation"`
From string `json:"from"`
To string `json:"to"`
// StatusPath is where to follow the run.
StatusPath string `json:"statusPath"`
}
Accepted is the body of a 202 from POST /api/v1/upgrade or /rollback.
type AgentStatus ¶
type AgentStatus struct {
ConfiguredImage string `json:"configuredImage"`
RunningImage string `json:"runningImage,omitempty"`
InSync bool `json:"inSync"`
Detail string `json:"detail,omitempty"`
}
AgentStatus is the Portainer agent image, desired and actual.
type Health ¶
type Health struct {
Healthy bool `json:"healthy"`
// Checks maps each check to "ok" or the reason it failed.
Checks map[string]string `json:"checks"`
}
Health is KubeSolo's own view of whether it is working.
type Job ¶
type Job struct {
ID string `json:"id"`
Operation Operation `json:"operation"`
Request Request `json:"request"`
DataDir string `json:"dataDir"`
ConfigFile string `json:"configFile"`
// From is the version running when the job was accepted.
From string `json:"from"`
}
Job is what the executor is asked to do. It is written to a file under the upgrade directory and the executor is pointed at it, so no part of the request depends on surviving a command line.
type Layout ¶
type Layout struct {
// DataDir is KubeSolo's data directory, normally /var/lib/kubesolo.
DataDir string
// Binary is the installed kubesolo binary.
Binary string
// ConfigFile is the configuration file, normally /etc/kubesolo/config.yaml.
// It may not exist on a flag-based install.
ConfigFile string
}
Layout names the files an upgrade reads and writes. Everything except the binary and the configuration file lives under <data>/upgrade, on the same filesystem as the datastore, so restoring is a rename or a reflink rather than a copy across devices.
func NewLayout ¶
NewLayout returns the layout for a data directory and configuration file, with the standard binary path.
func (Layout) AdminKubeconfig ¶
AdminKubeconfig is the admin kubeconfig KubeSolo writes into its PKI.
func (Layout) AttemptsFile ¶
AttemptsFile counts the starts of a pending binary.
func (Layout) BackupBinary ¶
BackupBinary is the previous kubesolo binary.
func (Layout) BackupConfigFile ¶
BackupConfigFile is the configuration file as it was before the upgrade.
func (Layout) BackupDatastore ¶
BackupDatastore is the datastore as it was before the upgrade.
func (Layout) BackupDir ¶
BackupDir is the single retained backup: the previous binary, the datastore and the configuration file as they were before the last upgrade.
func (Layout) BackupManifest ¶
BackupManifest describes the backup in BackupDir.
func (Layout) BackupServiceDefinition ¶
BackupServiceDefinition is the service definition as it was before the upgrade.
func (Layout) Datastore ¶
Datastore is kine's SQLite database. The -wal and -shm files sit beside it.
func (Layout) DatastoreDir ¶
DatastoreDir is kine's database directory.
func (Layout) FailedConfig ¶ added in v1.2.3
FailedConfig is where the last restart that was reverted keeps the configuration file that failed, for whoever looks into it. It is in the data directory, not beside the configuration file, so that it goes with the rest of KubeSolo's state.
func (Layout) GuardLog ¶
GuardLog is appended to by the boot guard when it restores the previous binary, so that the next KubeSolo can report what happened.
func (Layout) GuardScript ¶
GuardScript is the boot guard every init system runs before KubeSolo.
func (Layout) KnownGoodConfig ¶ added in v1.2.3
KnownGoodConfig is the configuration file as it was when KubeSolo last ran healthy on it. A restart that fails puts it back.
func (Layout) PendingFile ¶
PendingFile exists while a new binary has been started but not yet proven healthy. It holds the version being verified. The boot guard reads it.
func (Layout) PreviousBackupDir ¶
PreviousBackupDir holds the backup BackupDir replaced, while the upgrade that replaced it is unproven. A failed upgrade puts it back; see SettleBackups.
func (Layout) RunLog ¶
RunLog is a run's progress as plain text, one line per message, ending with a line "finished: <result>". It is for followers that cannot read JSON, such as install.sh.
func (Layout) RunStagingDir ¶
RunStagingDir is a run's own staging directory.
func (Layout) StagingDir ¶
StagingDir holds downloaded archives and extracted binaries until a binary is moved into place, one subdirectory per run.
func (Layout) StartedConfig ¶ added in v1.2.3
StartedConfig is the configuration file that KubeSolo started with, which its Portainer agent was deployed from.
func (Layout) StartedFile ¶ added in v1.2.3
StartedFile holds the PID of the KubeSolo that last finished starting.
type Lock ¶
type Lock struct {
// contains filtered or unexported fields
}
Lock is the exclusive lock on the upgrade directory. Whoever holds it is the only writer of the binary, the datastore backup and the state file — the API, kubesoloctl and the executor all take it, so a human running kubesoloctl cannot start an upgrade into one Portainer triggered.
type Manifest ¶
type Manifest struct {
// From is the version the backup holds: the rollback target.
From string `json:"from"`
// To is the version that was installed over it. A rollback is only valid
// while To is the version running: the datastore snapshot belongs to the
// moment From was replaced by To, and to nothing later.
To string `json:"to"`
Created time.Time `json:"created"`
// RunID is the upgrade that took the backup.
RunID string `json:"runId"`
DatastoreBytes int64 `json:"datastoreBytes"`
BinarySHA256 string `json:"binarySha256"`
HasConfigFile bool `json:"hasConfigFile"`
// ServiceDefinition is where the backed-up service definition goes back
// to; empty when there was none to back up (daemon mode).
ServiceDefinition string `json:"serviceDefinition,omitempty"`
}
Manifest describes the retained backup.
func LoadManifest ¶
LoadManifest reads the backup manifest. It returns nil, nil when there is no backup.
type Phase ¶
type Phase string
Phase is where a run has got to. The phases before PhaseStopping change nothing on the host; a failure in one of them is reported as ResultAborted.
const ( PhaseQueued Phase = "queued" PhasePreflight Phase = "preflight" PhaseBackup Phase = "backup" PhaseDryRun Phase = "dry-run" PhaseStopping Phase = "stopping" PhaseReplacing Phase = "replacing" PhaseStarting Phase = "starting" PhaseVerifying Phase = "verifying" PhaseRollingBack Phase = "rolling-back" PhaseDone Phase = "done" )
type Request ¶
type Request struct {
// Version is the release to install, e.g. "v1.2.3".
Version string `json:"version"`
// Source is an absolute path to a release archive (.tar.gz) or a kubesolo
// binary already on this host, for air-gapped upgrades. Empty means
// download the release for this host's architecture.
Source string `json:"source,omitempty"`
// SHA256 is the expected checksum of the archive or binary. Optional: when
// empty it is taken from SHA256SUMS published with the release, or placed
// next to Source.
SHA256 string `json:"sha256,omitempty"`
// Force allows installing a version that is not newer than the running one.
Force bool `json:"force,omitempty"`
// HealthTimeoutSeconds bounds how long the new version has to become
// healthy before it is rolled back. Zero means DefaultHealthTimeout.
HealthTimeoutSeconds int `json:"healthTimeoutSeconds,omitempty"`
}
Request asks for an upgrade. It is the body of POST /api/v1/upgrade, and what kubesoloctl hands the executor when the API is not available.
func (Request) HealthTimeout ¶
HealthTimeout returns the effective health-gate timeout.
func (Request) RestoreHealthTimeout ¶
RestoreHealthTimeout returns how long the version restored after a failed upgrade has to become healthy: the request's timeout, but never less than DefaultHealthTimeout. That version was running before the upgrade, and a short timeout chosen for the new one should not decide whether the rollback counts as one.
type Result ¶
type Result string
Result is how a run ended.
const ( // ResultSucceeded: the new version is running and passed the health gate. ResultSucceeded Result = "succeeded" // ResultAborted: the run failed before anything on the host was changed. // KubeSolo kept running throughout. ResultAborted Result = "aborted" // ResultRolledBack: the new version failed the health gate and the previous // binary, datastore and configuration were restored and are running. ResultRolledBack Result = "rolled-back" // ResultFailed: the run changed the host and could not bring it back to a // healthy state. It needs attention. ResultFailed Result = "failed" )
type Run ¶
type Run struct {
ID string `json:"id"`
Operation Operation `json:"operation"`
// From is the version that was running when the run began; To is the one
// it is moving to.
From string `json:"from"`
To string `json:"to"`
Phase Phase `json:"phase"`
Started time.Time `json:"started"`
Updated time.Time `json:"updated"`
Finished time.Time `json:"finished,omitzero"`
Result Result `json:"result,omitempty"`
Error string `json:"error,omitempty"`
// HostChanged becomes true at the first destructive step. Until then a
// failure leaves the host exactly as it was.
HostChanged bool `json:"hostChanged"`
// PID is the executor's process. Zero until it has started.
PID int `json:"pid,omitempty"`
// Messages is a short log of what the run did, oldest first.
Messages []string `json:"messages,omitempty"`
}
Run is one upgrade or rollback.
type Service ¶
type Service struct {
Init detect.InitSystem
// Daemon is set for daemon mode: KubeSolo started in the background with no
// supervisor. It is restarted with the arguments and proxy settings the
// running process was started with.
Daemon bool
// contains filtered or unexported fields
}
Service stops and starts KubeSolo the way it was installed.
func DetectService ¶
func DetectService(l Layout, info *detect.SystemInfo) (*Service, error)
DetectService works out how KubeSolo is run on this host. A service definition for the detected init system wins; failing that, a running KubeSolo with no definition is a daemon.
func (*Service) DefinitionFile ¶
DefinitionFile is the file that defines how the init system runs KubeSolo, or "" in daemon mode, which has none. The upgrade backs it up, because what happens after an upgrade — the move from flags to a configuration file — rewrites it into a form an older release cannot run.
func (*Service) ReloadDefinitions ¶
ReloadDefinitions makes the init system reread a service definition that has changed on disk. Only systemd caches them.
type Staged ¶
type Staged struct {
Version string
// Binary is the extracted kubesolo binary in the staging directory.
Binary string
// SHA256 is the checksum of what was fetched (the archive, or the binary
// when the source was a bare binary), and ChecksumSource where the expected
// value came from.
SHA256 string
ChecksumSource string
}
Staged is a release that has been fetched and verified, ready to install.
func Stage ¶
func Stage(ctx context.Context, l Layout, staging string, req Request, info *detect.SystemInfo, logf Logf) (*Staged, error)
Stage fetches the release the request names, verifies it, and extracts the binary into staging, a directory of the caller's own under l.StagingDir(). Nothing outside it is touched, so any error leaves the host as it was.
type State ¶
type State struct {
// Current is the run in flight, if any.
Current *Run `json:"current,omitempty"`
// Last is the most recent run to finish.
Last *Run `json:"last,omitempty"`
}
State is the upgrade record kept on disk. It is read after the restart an upgrade causes, which is the point: a KubeSolo that has just been rolled back can still say what happened to it.
func (*State) CloseInterrupted ¶
CloseInterrupted finishes s.Current, a run whose executor stopped before it did, now that running is the version KubeSolo is running and healthy. agentProblem says why the Portainer agent is not running, "" when it is or there is none. It returns false when there is no such run.
type Status ¶
type Status struct {
// Version is the running KubeSolo.
Version string `json:"version"`
Commit string `json:"commit,omitempty"`
ContainerMode bool `json:"containerMode"`
Health Health `json:"health"`
// Agent compares the Portainer agent image the configuration asks for with
// the one the cluster runs. Nil when no agent is configured.
Agent *AgentStatus `json:"agent,omitempty"`
Upgrade UpgradeStatus `json:"upgrade"`
}
Status is the body of GET /api/v1/status.
type UpgradeStatus ¶
type UpgradeStatus struct {
InFlight bool `json:"inFlight"`
Current *Run `json:"current,omitempty"`
Last *Run `json:"last,omitempty"`
// Interrupted is a run whose executor stopped before it finished — the
// host lost power or rebooted, or the executor was killed. KubeSolo closes
// it once it is healthy again; until then it is reported here.
Interrupted *Run `json:"interrupted,omitempty"`
// PendingVerify is the version that was started but has not yet been proven
// healthy, and BootAttempts how many times it has been started.
PendingVerify string `json:"pendingVerify,omitempty"`
BootAttempts int `json:"bootAttempts,omitempty"`
// RollbackTarget is the version a rollback would restore, if one is valid.
RollbackTarget *Manifest `json:"rollbackTarget,omitempty"`
RollbackUnavailable string `json:"rollbackUnavailable,omitempty"`
// GuardEvents are the boot guard's records of restoring a previous binary.
GuardEvents []string `json:"guardEvents,omitempty"`
}
UpgradeStatus is the upgrade part of GET /api/v1/status. Everything in it is read from disk.
func ReadUpgradeStatus ¶
func ReadUpgradeStatus(l Layout, running string) UpgradeStatus
ReadUpgradeStatus assembles the upgrade status from disk. running is the version currently running.
type Version ¶
type Version struct {
Major, Minor, Patch int
Pre string
// contains filtered or unexported fields
}
Version is a KubeSolo release version: vMAJOR.MINOR.PATCH with an optional pre-release suffix, as the release tags are written.
func ParseVersion ¶
ParseVersion parses a release tag such as "v1.2.1" or "v1.3.0-rc.1".
It is strict on purpose: the version names a download URL and an archive, and is compared against what the new binary reports about itself. A build from an untagged commit ("v1.2.1-5-gabc123-dirty", "dev") parses only if it happens to fit the pattern, which callers treat as an ordinary pre-release.