etcdserver/cluster_util.go
func decideClusterVersion(lg *zap.Logger, vers map[string]*version.Versions) *semver.Version {
	var cv *semver.Version
	lv := semver.Must(semver.NewVersion(version.Version))

	for mid, ver := range vers {
		if ver == nil {
			return nil
		}
		v, err := semver.NewVersion(ver.Server)
		if err != nil {
			if lg != nil {
				lg.Warn(
					"failed to parse server version of remote member",
					zap.String("remote-member-id", mid),
					zap.String("remote-member-version", ver.Server),
					zap.Error(err),
				)
			} else {
				plog.Errorf("cannot understand the version of member %s (%v)", mid, err)
			}
			return nil
		}
		if lv.LessThan(*v) {
			if lg != nil {
				lg.Warn(
					"leader found higher-versioned member",
					zap.String("local-member-version", lv.String()),
					zap.String("remote-member-id", mid),
					zap.String("remote-member-version", ver.Server),
				)
			} else {
				plog.Warningf("the local etcd version %s is not up-to-date", lv.String())
				plog.Warningf("member %s has a higher version %s", mid, ver.Server)
			}
		}
		if cv == nil {
			cv = v
		} else if v.LessThan(*cv) {
			cv = v
		}
	}
	return cv
}
func decideClusterVersion(lg *zap.Logger, vers map[string]*version.Versions) *semver.Version {
	var cv *semver.Version
	lv := semver.Must(semver.NewVersion(version.Version))

	for mid, ver := range vers {
		if ver == nil {
			return nil
		}
		v, err := semver.NewVersion(ver.Server)
		if err != nil {
			if lg != nil {
				lg.Warn(
					"failed to parse server version of remote member",
					zap.String("remote-member-id", mid),
					zap.String("remote-member-version", ver.Server),
					zap.Error(err),
				)
			} else {
				plog.Errorf("cannot understand the version of member %s (%v)", mid, err)
			}
			return nil
		}
		if lv.LessThan(*v) {
			if lg != nil {
				lg.Warn(
					"leader found higher-versioned member",
					zap.String("local-member-version", lv.String()),
					zap.String("remote-member-id", mid),
					zap.String("remote-member-version", ver.Server),
				)
			} else {
				plog.Warningf("the local etcd version %s is not up-to-date", lv.String())
				plog.Warningf("member %s has a higher version %s", mid, ver.Server)
			}
		}
		if cv == nil {
			cv = v
		} else if v.LessThan(*cv) {
			cv = v
		}
	}
	return cv
}
func decideClusterVersion ( lg * zap . Logger , vers map [ string ] * version . Versions ) * semver . Version { var cv * semver . Version lv := semver . Must ( semver . NewVersion ( version . Version ) ) for mid , ver := range vers { if ver == nil { return nil } v , err := semver . NewVersion ( ver . Server ) if err != nil { if lg != nil { lg . Warn ( " " , zap . String ( " " , mid ) , zap . String ( " " , ver . Server ) , zap . Error ( err ) , ) } else { plog . Errorf ( " " , mid , err ) } return nil } if lv . LessThan ( * v ) { if lg != nil { lg . Warn ( " " , zap . String ( " " , lv . String ( ) ) , zap . String ( " " , mid ) , zap . String ( " " , ver . Server ) , ) } else { plog . Warningf ( " " , lv . String ( ) ) plog . Warningf ( " " , mid , ver . Server ) } } if cv == nil { cv = v } else if v . LessThan ( * cv ) { cv = v } } return cv }
// decideClusterVersion decides the cluster version based on the versions map.
// The returned version is the min server version in the map, or nil if the min
// version in unknown.
decideClusterVersion decides the cluster version based on the versions map . The returned version is the min server version in the map or nil if the min version in unknown .