diff --git a/etcdserver/cluster.go b/etcdserver/cluster.go index ed25d3234..23737de70 100644 --- a/etcdserver/cluster.go +++ b/etcdserver/cluster.go @@ -222,6 +222,7 @@ func (c *cluster) SetStore(st store.Store) { c.store = st } func (c *cluster) Recover() { c.members, c.removed = membersFromStore(c.store) c.version = clusterVersionFromStore(c.store) + MustDetectDowngrade(c.version) } // ValidateConfigurationChange takes a proposed ConfChange and @@ -364,6 +365,7 @@ func (c *cluster) SetVersion(ver *semver.Version) { plog.Noticef("set the initial cluster version to %v", version.Cluster(ver.String())) } c.version = ver + MustDetectDowngrade(c.version) } func membersFromStore(st store.Store) (map[types.ID]*Member, map[types.ID]bool) { diff --git a/etcdserver/cluster_util.go b/etcdserver/cluster_util.go index 66a72064d..6339bec39 100644 --- a/etcdserver/cluster_util.go +++ b/etcdserver/cluster_util.go @@ -252,3 +252,12 @@ func getVersion(m *Member, tr *http.Transport) (*version.Versions, error) { } return nil, err } + +func MustDetectDowngrade(cv *semver.Version) { + lv := semver.Must(semver.NewVersion(version.Version)) + // only keep major.minor version for comparison against cluster version + lv = &semver.Version{Major: lv.Major, Minor: lv.Minor} + if cv != nil && lv.LessThan(*cv) { + plog.Fatalf("cluster cannot be downgraded (current version: %s is lower than determined cluster version: %s).", version.Version, version.Cluster(cv.String())) + } +}