mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00

Cluster version is the min major.minor of all members in the etcd cluster. Cluster version is set to the min version that a etcd member is compatible with when first bootstrapp. During a rolling upgrades, the cluster version will be updated automatically. For example: ``` Cluster [a:1, b:1 ,c:1] -> clusterVersion 1 update a -> 2, b -> 2 after a detection Cluster [a:2, b:2 ,c:1] -> clusterVersion 1, since c is still 1 update c -> 2 after a detection Cluster [a:2, b:2 ,c:2] -> clusterVersion 2 ``` The API/raft component can utilize clusterVersion to determine if it can accept a client request or a raft RPC. We choose polling rather than pushing since we want to use the same logic for cluster version detection and (TODO) cluster version checking. Before a member actually joins a etcd cluster, it should check the version of the cluster. Push does not work since the other members cannot push version info to it before it actually joins. Moreover, we do not want our raft RPC system (which is doing the heartbeat pushing) to coordinate cluster version.
98 lines
2.6 KiB
Go
98 lines
2.6 KiB
Go
// Copyright 2015 CoreOS, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package version
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"os"
|
|
"path"
|
|
|
|
"github.com/coreos/etcd/pkg/fileutil"
|
|
"github.com/coreos/etcd/pkg/types"
|
|
)
|
|
|
|
var (
|
|
// MinClusterVersion is the min cluster version this etcd binary is compatible with.
|
|
MinClusterVersion = "2.0.0"
|
|
Version = "2.1.0-alpha.0+git"
|
|
)
|
|
|
|
// WalVersion is an enum for versions of etcd logs.
|
|
type DataDirVersion string
|
|
|
|
const (
|
|
DataDirUnknown DataDirVersion = "Unknown WAL"
|
|
DataDir0_4 DataDirVersion = "0.4.x"
|
|
DataDir2_0 DataDirVersion = "2.0.0"
|
|
DataDir2_0Proxy DataDirVersion = "2.0 proxy"
|
|
DataDir2_0_1 DataDirVersion = "2.0.1"
|
|
)
|
|
|
|
type Versions struct {
|
|
Server string `json:"etcdserver"`
|
|
// TODO: etcdcluster version
|
|
// TODO: raft state machine version
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of Versions struct.
|
|
func MarshalJSON() []byte {
|
|
b, err := json.Marshal(Versions{Server: Version})
|
|
if err != nil {
|
|
log.Panicf("version: cannot marshal versions to json (%v)", err)
|
|
}
|
|
return b
|
|
}
|
|
|
|
func DetectDataDir(dirpath string) (DataDirVersion, error) {
|
|
names, err := fileutil.ReadDir(dirpath)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
err = nil
|
|
}
|
|
// Error reading the directory
|
|
return DataDirUnknown, err
|
|
}
|
|
nameSet := types.NewUnsafeSet(names...)
|
|
if nameSet.Contains("member") {
|
|
ver, err := DetectDataDir(path.Join(dirpath, "member"))
|
|
if ver == DataDir2_0 {
|
|
return DataDir2_0_1, nil
|
|
} else if ver == DataDir0_4 {
|
|
// How in the blazes did it get there?
|
|
return DataDirUnknown, nil
|
|
}
|
|
return ver, err
|
|
}
|
|
if nameSet.ContainsAll([]string{"snap", "wal"}) {
|
|
// .../wal cannot be empty to exist.
|
|
walnames, err := fileutil.ReadDir(path.Join(dirpath, "wal"))
|
|
if err == nil && len(walnames) > 0 {
|
|
return DataDir2_0, nil
|
|
}
|
|
}
|
|
if nameSet.ContainsAll([]string{"proxy"}) {
|
|
return DataDir2_0Proxy, nil
|
|
}
|
|
if nameSet.ContainsAll([]string{"snapshot", "conf", "log"}) {
|
|
return DataDir0_4, nil
|
|
}
|
|
if nameSet.ContainsAll([]string{"standby_info"}) {
|
|
return DataDir0_4, nil
|
|
}
|
|
|
|
return DataDirUnknown, nil
|
|
}
|