87 lines
2.3 KiB
Go
87 lines
2.3 KiB
Go
package updateprotocol
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
var releaseVersionPattern = regexp.MustCompile(`^v(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)$`)
|
|
|
|
const (
|
|
PhaseIdle = "idle"
|
|
PhaseQueued = "queued"
|
|
PhasePulling = "pulling"
|
|
PhaseRestarting = "restarting"
|
|
PhaseVerifying = "verifying"
|
|
PhaseComplete = "complete"
|
|
PhaseFailed = "failed"
|
|
)
|
|
|
|
type Request struct {
|
|
Version string `json:"version"`
|
|
CurrentVersion string `json:"current_version"`
|
|
RegistryUsername string `json:"registry_username"`
|
|
// RegistryToken keeps the v2 wire name for compatibility and carries either
|
|
// a registry password or an API token.
|
|
RegistryToken string `json:"registry_token"`
|
|
}
|
|
|
|
type Status struct {
|
|
Phase string `json:"phase"`
|
|
TargetVersion string `json:"target_version,omitempty"`
|
|
Message string `json:"message,omitempty"`
|
|
StartedAt time.Time `json:"started_at,omitempty"`
|
|
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
|
AgentVersion string `json:"agent_version,omitempty"`
|
|
Protocol int `json:"protocol_version,omitempty"`
|
|
}
|
|
|
|
func (s Status) Busy() bool {
|
|
return s.Phase == PhaseQueued || s.Phase == PhasePulling || s.Phase == PhaseRestarting || s.Phase == PhaseVerifying
|
|
}
|
|
|
|
func ValidVersion(version string) bool {
|
|
return len(version) <= 64 && releaseVersionPattern.MatchString(version)
|
|
}
|
|
|
|
// CompareVersions compares strict stable vMAJOR.MINOR.PATCH versions. It does
|
|
// not require callers to install intermediate releases.
|
|
func CompareVersions(left, right string) (int, error) {
|
|
a, err := parseVersion(left)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
b, err := parseVersion(right)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
for index := range a {
|
|
if a[index] < b[index] {
|
|
return -1, nil
|
|
}
|
|
if a[index] > b[index] {
|
|
return 1, nil
|
|
}
|
|
}
|
|
return 0, nil
|
|
}
|
|
|
|
func parseVersion(raw string) ([3]int, error) {
|
|
if !ValidVersion(raw) {
|
|
return [3]int{}, fmt.Errorf("version must use vMAJOR.MINOR.PATCH")
|
|
}
|
|
parts := strings.Split(strings.TrimPrefix(raw, "v"), ".")
|
|
var values [3]int
|
|
for index, part := range parts {
|
|
value, err := strconv.Atoi(part)
|
|
if err != nil || value < 0 || value > 1_000_000 {
|
|
return [3]int{}, fmt.Errorf("version contains an invalid number")
|
|
}
|
|
values[index] = value
|
|
}
|
|
return values, nil
|
|
}
|