Move from allowed range to minimum for Version Control (#2421)

This commit is contained in:
Stefan Benten 2019-07-02 17:28:06 +02:00 committed by GitHub
parent d32c907440
commit 3583c65f5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 63 deletions

View File

@ -122,6 +122,7 @@ func (planet *Planet) newVersionControlServer() (peer *versioncontrol.Peer, err
Storagenode: "v0.0.1", Storagenode: "v0.0.1",
Uplink: "v0.0.1", Uplink: "v0.0.1",
Gateway: "v0.0.1", Gateway: "v0.0.1",
Identity: "v0.0.1",
}, },
} }
peer, err = versioncontrol.New(log, config) peer, err = versioncontrol.New(log, config)

View File

@ -109,14 +109,14 @@ func (srv *Service) checkVersion(ctx context.Context) (allowed bool) {
return true return true
} }
list := getFieldString(&accepted, srv.service) minimum := getFieldString(&accepted, srv.service)
zap.S().Debugf("allowed versions from Control Server: %v", list) zap.S().Debugf("allowed minimum version from control server is: %s", minimum.String())
if list == nil { if minimum.String() == "" {
zap.S().Errorf("Empty List from Versioning Server") zap.S().Errorf("no version from control server, accepting to run")
return true return true
} }
if containsVersion(list, srv.info.Version) { if isAcceptedVersion(srv.info.Version, minimum) {
zap.S().Infof("running on version %s", srv.info.Version.String()) zap.S().Infof("running on version %s", srv.info.Version.String())
return true return true
} }
@ -168,12 +168,12 @@ func DebugHandler(w http.ResponseWriter, r *http.Request) {
} }
} }
func getFieldString(array *AllowedVersions, field string) []SemVer { func getFieldString(array *AllowedVersions, field string) SemVer {
r := reflect.ValueOf(array) r := reflect.ValueOf(array)
f := reflect.Indirect(r).FieldByName(field).Interface() f := reflect.Indirect(r).FieldByName(field).Interface()
result, ok := f.([]SemVer) result, ok := f.(SemVer)
if ok { if ok {
return result return result
} }
return nil return SemVer{}
} }

View File

@ -5,7 +5,6 @@ package version
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"regexp" "regexp"
"strconv" "strconv"
@ -13,7 +12,8 @@ import (
"time" "time"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
monkit "gopkg.in/spacemonkeygo/monkit.v2" "github.com/zeebo/errs"
"gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/pkg/pb" "storj.io/storj/pkg/pb"
) )
@ -21,6 +21,7 @@ import (
var ( var (
mon = monkit.Package() mon = monkit.Package()
verError = errs.Class("version error")
// the following fields are set by linker flags. if any of them // the following fields are set by linker flags. if any of them
// are set and fail to parse, the program will fail to start // are set and fail to parse, the program will fail to start
buildTimestamp string // unix seconds since epoch buildTimestamp string // unix seconds since epoch
@ -50,14 +51,14 @@ type SemVer struct {
Patch int64 `json:"patch"` Patch int64 `json:"patch"`
} }
// AllowedVersions provides a list of SemVer per Service // AllowedVersions provides the Minimum SemVer per Service
type AllowedVersions struct { type AllowedVersions struct {
Bootstrap []SemVer Bootstrap SemVer
Satellite []SemVer Satellite SemVer
Storagenode []SemVer Storagenode SemVer
Uplink []SemVer Uplink SemVer
Gateway []SemVer Gateway SemVer
Identity []SemVer Identity SemVer
} }
// SemVerRegex is the regular expression used to parse a semantic version. // SemVerRegex is the regular expression used to parse a semantic version.
@ -68,33 +69,29 @@ var versionRegex = regexp.MustCompile("^" + SemVerRegex + "$")
// NewSemVer parses a given version and returns an instance of SemVer or // NewSemVer parses a given version and returns an instance of SemVer or
// an error if unable to parse the version. // an error if unable to parse the version.
func NewSemVer(v string) (*SemVer, error) { func NewSemVer(v string) (sv SemVer, err error) {
m := versionRegex.FindStringSubmatch(v) m := versionRegex.FindStringSubmatch(v)
if m == nil { if m == nil {
return nil, errors.New("invalid semantic version for build") return SemVer{}, verError.New("invalid semantic version for build %s", v)
} }
sv := SemVer{}
var err error
// first entry of m is the entire version string // first entry of m is the entire version string
sv.Major, err = strconv.ParseInt(m[1], 10, 64) sv.Major, err = strconv.ParseInt(m[1], 10, 64)
if err != nil { if err != nil {
return nil, err return SemVer{}, err
} }
sv.Minor, err = strconv.ParseInt(m[2], 10, 64) sv.Minor, err = strconv.ParseInt(m[2], 10, 64)
if err != nil { if err != nil {
return nil, err return SemVer{}, err
} }
sv.Patch, err = strconv.ParseInt(m[3], 10, 64) sv.Patch, err = strconv.ParseInt(m[3], 10, 64)
if err != nil { if err != nil {
return nil, err return SemVer{}, err
} }
return &sv, nil return sv, nil
} }
// String converts the SemVer struct to a more easy to handle string // String converts the SemVer struct to a more easy to handle string
@ -130,26 +127,9 @@ func (v Info) Proto() (*pb.NodeVersion, error) {
}, nil }, nil
} }
// containsVersion compares the allowed version array against the passed version // isAcceptedVersion compares and checks if the passed version is greater/equal than the minimum required version
func containsVersion(all []SemVer, x SemVer) bool { func isAcceptedVersion(test SemVer, target SemVer) bool {
for _, n := range all { return test.Major > target.Major || (test.Major == target.Major && (test.Minor > target.Minor || (test.Minor == target.Minor && test.Patch >= target.Patch)))
if x == n {
return true
}
}
return false
}
// StrToSemVerList converts a list of versions to a list of SemVer
func StrToSemVerList(serviceVersions []string) (versions []SemVer, err error) {
for _, subversion := range serviceVersions {
sVer, err := NewSemVer(subversion)
if err != nil {
return nil, err
}
versions = append(versions, *sVer)
}
return versions, err
} }
func init() { func init() {
@ -158,7 +138,7 @@ func init() {
} }
timestamp, err := strconv.ParseInt(buildTimestamp, 10, 64) timestamp, err := strconv.ParseInt(buildTimestamp, 10, 64)
if err != nil { if err != nil {
panic(fmt.Sprintf("invalid timestamp: %v", err)) panic(verError.Wrap(err))
} }
Build = Info{ Build = Info{
Timestamp: time.Unix(timestamp, 0), Timestamp: time.Unix(timestamp, 0),
@ -171,7 +151,7 @@ func init() {
panic(err) panic(err)
} }
Build.Version = *sv Build.Version = sv
if Build.Timestamp.Unix() == 0 || Build.CommitHash == "" { if Build.Timestamp.Unix() == 0 || Build.CommitHash == "" {
Build.Release = false Build.Release = false

View File

@ -8,7 +8,6 @@ import (
"encoding/json" "encoding/json"
"net" "net"
"net/http" "net/http"
"strings"
"github.com/zeebo/errs" "github.com/zeebo/errs"
"go.uber.org/zap" "go.uber.org/zap"
@ -77,24 +76,36 @@ func New(log *zap.Logger, config *Config) (peer *Peer, err error) {
Log: log, Log: log,
} }
// Convert each Service's Version String to List of SemVer // Convert each Service's Version String to SemVer
bootstrapVersions := strings.Split(config.Versions.Bootstrap, ",") peer.Versions.Bootstrap, err = version.NewSemVer(config.Versions.Bootstrap)
peer.Versions.Bootstrap, err = version.StrToSemVerList(bootstrapVersions) if err != nil {
return &Peer{}, err
}
satelliteVersions := strings.Split(config.Versions.Satellite, ",") peer.Versions.Satellite, err = version.NewSemVer(config.Versions.Satellite)
peer.Versions.Satellite, err = version.StrToSemVerList(satelliteVersions) if err != nil {
return &Peer{}, err
}
storagenodeVersions := strings.Split(config.Versions.Storagenode, ",") peer.Versions.Storagenode, err = version.NewSemVer(config.Versions.Storagenode)
peer.Versions.Storagenode, err = version.StrToSemVerList(storagenodeVersions) if err != nil {
return &Peer{}, err
}
uplinkVersions := strings.Split(config.Versions.Uplink, ",") peer.Versions.Uplink, err = version.NewSemVer(config.Versions.Uplink)
peer.Versions.Uplink, err = version.StrToSemVerList(uplinkVersions) if err != nil {
return &Peer{}, err
}
gatewayVersions := strings.Split(config.Versions.Gateway, ",") peer.Versions.Gateway, err = version.NewSemVer(config.Versions.Gateway)
peer.Versions.Gateway, err = version.StrToSemVerList(gatewayVersions) if err != nil {
return &Peer{}, err
}
identityVersions := strings.Split(config.Versions.Identity, ",") peer.Versions.Identity, err = version.NewSemVer(config.Versions.Identity)
peer.Versions.Identity, err = version.StrToSemVerList(identityVersions) if err != nil {
return &Peer{}, err
}
peer.response, err = json.Marshal(peer.Versions) peer.response, err = json.Marshal(peer.Versions)