+// package version provide the version info for the node, and also provide
+// support for version compatibility check and update notification.
+//
+// The version format should follow Semantic Versioning (https://semver.org/):
+// MAJOR.MINOR.PATCH
+// 1. MAJOR version when you make incompatible API changes,
+// 2. MINOR version when you add functionality in a backwards-compatible manner, and
+// 3. PATCH version when you make backwards-compatible bug fixes.
+//
+// A pre-release version MAY be denoted by appending a hyphen and a series of
+// dot separated identifiers immediately following the patch version.
+// Examples:
+// 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.
+// Precedence:
+// 1. Pre-release versions have a lower precedence than the associated normal version!
+// Numeric identifiers always have lower precedence than non-numeric identifiers.
+// 2. A larger set of pre-release fields has a higher precedence than a smaller set,
+// if all of the preceding identifiers are equal.
+// 3. Example:
+// 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.
+//
+// Build metadata MAY be denoted by appending a plus sign and a series of dot
+// separated identifiers immediately following the patch or pre-release version.
+// Build metadata SHOULD be ignored when determining version precedence. Thus
+// two versions that differ only in the build metadata, have the same precedence.
+
package version
import (
+ "sync"
+
gover "github.com/hashicorp/go-version"
log "github.com/sirupsen/logrus"
"gopkg.in/fatih/set.v0"
- "sync"
)
const (
+ // If needing to edit the iota, please ensure the following:
+ // noUpdate = 0
+ // hasUpdate = 1
+ // hasMUpdate = 2
noUpdate uint16 = iota
hasUpdate
hasMUpdate
+ logModule = "version"
)
var (
// The full version string
- Version = "1.0.4"
+ Version = "2.0.6"
// GitCommit is set with --ldflags "-X main.gitCommit=$(git rev-parse HEAD)"
GitCommit string
Status *UpdateStatus
func init() {
if GitCommit != "" {
- Version += "-" + GitCommit[:8]
+ Version += "+" + GitCommit[:8]
}
+
Status = &UpdateStatus{
+ maxVerSeen: Version,
notified: false,
- versionStatus: noUpdate,
seedSet: set.New(),
+ versionStatus: noUpdate,
}
}
type UpdateStatus struct {
sync.RWMutex
+ maxVerSeen string
notified bool
- versionStatus uint16
seedSet *set.Set
+ versionStatus uint16
}
func (s *UpdateStatus) AddSeed(seedAddr string) {
s.Lock()
defer s.Unlock()
- if s.notified || !s.seedSet.Has(remoteAddr) {
+ if !s.seedSet.Has(remoteAddr) {
return nil
}
return err
}
if remoteVersion.GreaterThan(localVersion) {
- s.versionStatus = hasUpdate
+ if s.versionStatus == noUpdate {
+ s.versionStatus = hasUpdate
+ }
+
+ maxVersion, err := gover.NewVersion(s.maxVerSeen)
+ if err != nil {
+ return err
+ }
+
+ if remoteVersion.GreaterThan(maxVersion) {
+ s.maxVerSeen = remoteVerStr
+ }
}
if remoteVersion.Segments()[0] > localVersion.Segments()[0] {
s.versionStatus = hasMUpdate
}
if s.versionStatus != noUpdate {
log.WithFields(log.Fields{
+ "module": logModule,
"Current version": localVerStr,
"Newer version": remoteVerStr,
"seed": remoteAddr,
return nil
}
+func (s *UpdateStatus) MaxVerSeen() string {
+ s.RLock()
+ defer s.RUnlock()
+ return s.maxVerSeen
+}
+
func (s *UpdateStatus) VersionStatus() uint16 {
s.RLock()
defer s.RUnlock()