Compare commits
10 Commits
v3.4.0-rc.
...
v3.4.0-rc.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
012e38fef3 | ||
![]() |
41a2cfa122 | ||
![]() |
9f8a1edf38 | ||
![]() |
165ba72593 | ||
![]() |
9c850ccef0 | ||
![]() |
61d6efda4c | ||
![]() |
b76f149c35 | ||
![]() |
5e33bb1a95 | ||
![]() |
83bf125d93 | ||
![]() |
d23af41bca |
@@ -271,7 +271,10 @@ etcdctl --endpoints=$ENDPOINTS endpoint health
|
|||||||
|
|
||||||
<img src="https://storage.googleapis.com/etcd/demo/11_etcdctl_snapshot_2016051001.gif" alt="11_etcdctl_snapshot_2016051001"/>
|
<img src="https://storage.googleapis.com/etcd/demo/11_etcdctl_snapshot_2016051001.gif" alt="11_etcdctl_snapshot_2016051001"/>
|
||||||
|
|
||||||
|
Snapshot can only be requested from one etcd node, so `--endpoints` flag should contain only one endpoint.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
ENDPOINTS=$HOST_1:2379
|
||||||
etcdctl --endpoints=$ENDPOINTS snapshot save my.db
|
etcdctl --endpoints=$ENDPOINTS snapshot save my.db
|
||||||
|
|
||||||
Snapshot saved at my.db
|
Snapshot saved at my.db
|
||||||
|
@@ -388,7 +388,7 @@ func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse,
|
|||||||
var hashed []byte
|
var hashed []byte
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if !r.Options.NoPassword {
|
if r.Options != nil && !r.Options.NoPassword {
|
||||||
hashed, err = bcrypt.GenerateFromPassword([]byte(r.Password), as.bcryptCost)
|
hashed, err = bcrypt.GenerateFromPassword([]byte(r.Password), as.bcryptCost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if as.lg != nil {
|
if as.lg != nil {
|
||||||
|
@@ -129,8 +129,12 @@ func NewFromURLs(urls []string) (*Client, error) {
|
|||||||
// Close shuts down the client's etcd connections.
|
// Close shuts down the client's etcd connections.
|
||||||
func (c *Client) Close() error {
|
func (c *Client) Close() error {
|
||||||
c.cancel()
|
c.cancel()
|
||||||
c.Watcher.Close()
|
if c.Watcher != nil {
|
||||||
c.Lease.Close()
|
c.Watcher.Close()
|
||||||
|
}
|
||||||
|
if c.Lease != nil {
|
||||||
|
c.Lease.Close()
|
||||||
|
}
|
||||||
if c.resolverGroup != nil {
|
if c.resolverGroup != nil {
|
||||||
c.resolverGroup.Close()
|
c.resolverGroup.Close()
|
||||||
}
|
}
|
||||||
|
@@ -156,3 +156,13 @@ func TestIsHaltErr(t *testing.T) {
|
|||||||
t.Errorf("cancel on context should be Halted")
|
t.Errorf("cancel on context should be Halted")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCloseCtxClient(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
c := NewCtxClient(ctx)
|
||||||
|
err := c.Close()
|
||||||
|
// Close returns ctx.toErr, a nil error means an open Done channel
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("failed to Close the client. %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -170,7 +170,10 @@ func (cfg *Config) setupLogging() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !isJournal {
|
if !isJournal {
|
||||||
copied := logutil.AddOutputPaths(logutil.DefaultZapLoggerConfig, outputPaths, errOutputPaths)
|
copied := logutil.DefaultZapLoggerConfig
|
||||||
|
copied.OutputPaths = outputPaths
|
||||||
|
copied.ErrorOutputPaths = errOutputPaths
|
||||||
|
copied = logutil.MergeOutputPaths(copied)
|
||||||
copied.Level = zap.NewAtomicLevelAt(logutil.ConvertToZapLevel(cfg.LogLevel))
|
copied.Level = zap.NewAtomicLevelAt(logutil.ConvertToZapLevel(cfg.LogLevel))
|
||||||
if cfg.Debug || cfg.LogLevel == "debug" {
|
if cfg.Debug || cfg.LogLevel == "debug" {
|
||||||
// enable tracing even when "--debug --log-level info"
|
// enable tracing even when "--debug --log-level info"
|
||||||
|
@@ -53,15 +53,12 @@ var DefaultZapLoggerConfig = zap.Config{
|
|||||||
ErrorOutputPaths: []string{"stderr"},
|
ErrorOutputPaths: []string{"stderr"},
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddOutputPaths adds output paths to the existing output paths, resolving conflicts.
|
// MergeOutputPaths merges logging output paths, resolving conflicts.
|
||||||
func AddOutputPaths(cfg zap.Config, outputPaths, errorOutputPaths []string) zap.Config {
|
func MergeOutputPaths(cfg zap.Config) zap.Config {
|
||||||
outputs := make(map[string]struct{})
|
outputs := make(map[string]struct{})
|
||||||
for _, v := range cfg.OutputPaths {
|
for _, v := range cfg.OutputPaths {
|
||||||
outputs[v] = struct{}{}
|
outputs[v] = struct{}{}
|
||||||
}
|
}
|
||||||
for _, v := range outputPaths {
|
|
||||||
outputs[v] = struct{}{}
|
|
||||||
}
|
|
||||||
outputSlice := make([]string, 0)
|
outputSlice := make([]string, 0)
|
||||||
if _, ok := outputs["/dev/null"]; ok {
|
if _, ok := outputs["/dev/null"]; ok {
|
||||||
// "/dev/null" to discard all
|
// "/dev/null" to discard all
|
||||||
@@ -78,9 +75,6 @@ func AddOutputPaths(cfg zap.Config, outputPaths, errorOutputPaths []string) zap.
|
|||||||
for _, v := range cfg.ErrorOutputPaths {
|
for _, v := range cfg.ErrorOutputPaths {
|
||||||
errOutputs[v] = struct{}{}
|
errOutputs[v] = struct{}{}
|
||||||
}
|
}
|
||||||
for _, v := range errorOutputPaths {
|
|
||||||
errOutputs[v] = struct{}{}
|
|
||||||
}
|
|
||||||
errOutputSlice := make([]string, 0)
|
errOutputSlice := make([]string, 0)
|
||||||
if _, ok := errOutputs["/dev/null"]; ok {
|
if _, ok := errOutputs["/dev/null"]; ok {
|
||||||
// "/dev/null" to discard all
|
// "/dev/null" to discard all
|
||||||
|
@@ -265,7 +265,7 @@ func TestLogMaybeAppend(t *testing.T) {
|
|||||||
t.Fatalf("unexpected error %v", err)
|
t.Fatalf("unexpected error %v", err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(tt.ents, gents) {
|
if !reflect.DeepEqual(tt.ents, gents) {
|
||||||
t.Errorf("%d: appended entries = %v, want %v", i, gents, tt.ents)
|
t.Errorf("#%d: appended entries = %v, want %v", i, gents, tt.ents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -426,7 +426,7 @@ func TestUnstableEnts(t *testing.T) {
|
|||||||
|
|
||||||
ents := raftLog.unstableEntries()
|
ents := raftLog.unstableEntries()
|
||||||
if l := len(ents); l > 0 {
|
if l := len(ents); l > 0 {
|
||||||
raftLog.stableTo(ents[l-1].Index, ents[l-i].Term)
|
raftLog.stableTo(ents[l-1].Index, ents[l-1].Term)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(ents, tt.wents) {
|
if !reflect.DeepEqual(ents, tt.wents) {
|
||||||
t.Errorf("#%d: unstableEnts = %+v, want %+v", i, ents, tt.wents)
|
t.Errorf("#%d: unstableEnts = %+v, want %+v", i, ents, tt.wents)
|
||||||
@@ -671,13 +671,13 @@ func TestIsOutOfBounds(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
err := l.mustCheckOutOfBounds(tt.lo, tt.hi)
|
err := l.mustCheckOutOfBounds(tt.lo, tt.hi)
|
||||||
if tt.wpanic {
|
if tt.wpanic {
|
||||||
t.Errorf("%d: panic = %v, want %v", i, false, true)
|
t.Errorf("#%d: panic = %v, want %v", i, false, true)
|
||||||
}
|
}
|
||||||
if tt.wErrCompacted && err != ErrCompacted {
|
if tt.wErrCompacted && err != ErrCompacted {
|
||||||
t.Errorf("%d: err = %v, want %v", i, err, ErrCompacted)
|
t.Errorf("#%d: err = %v, want %v", i, err, ErrCompacted)
|
||||||
}
|
}
|
||||||
if !tt.wErrCompacted && err != nil {
|
if !tt.wErrCompacted && err != nil {
|
||||||
t.Errorf("%d: unexpected err %v", i, err)
|
t.Errorf("#%d: unexpected err %v", i, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@@ -367,7 +367,7 @@ func newRaft(c *Config) *raft {
|
|||||||
}
|
}
|
||||||
assertConfStatesEquivalent(r.logger, cs, r.switchToConfig(cfg, prs))
|
assertConfStatesEquivalent(r.logger, cs, r.switchToConfig(cfg, prs))
|
||||||
|
|
||||||
if !isHardStateEqual(hs, emptyState) {
|
if !IsEmptyHardState(hs) {
|
||||||
r.loadState(hs)
|
r.loadState(hs)
|
||||||
}
|
}
|
||||||
if c.Applied > 0 {
|
if c.Applied > 0 {
|
||||||
@@ -1099,7 +1099,7 @@ func stepLeader(r *raft, m pb.Message) error {
|
|||||||
case ReadOnlyLeaseBased:
|
case ReadOnlyLeaseBased:
|
||||||
ri := r.raftLog.committed
|
ri := r.raftLog.committed
|
||||||
if m.From == None || m.From == r.id { // from local member
|
if m.From == None || m.From == r.id { // from local member
|
||||||
r.readStates = append(r.readStates, ReadState{Index: r.raftLog.committed, RequestCtx: m.Entries[0].Data})
|
r.readStates = append(r.readStates, ReadState{Index: ri, RequestCtx: m.Entries[0].Data})
|
||||||
} else {
|
} else {
|
||||||
r.send(pb.Message{To: m.From, Type: pb.MsgReadIndexResp, Index: ri, Entries: m.Entries})
|
r.send(pb.Message{To: m.From, Type: pb.MsgReadIndexResp, Index: ri, Entries: m.Entries})
|
||||||
}
|
}
|
||||||
|
@@ -106,7 +106,7 @@ func TestStorageLastIndex(t *testing.T) {
|
|||||||
t.Errorf("err = %v, want nil", err)
|
t.Errorf("err = %v, want nil", err)
|
||||||
}
|
}
|
||||||
if last != 5 {
|
if last != 5 {
|
||||||
t.Errorf("term = %d, want %d", last, 5)
|
t.Errorf("last = %d, want %d", last, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Append([]pb.Entry{{Index: 6, Term: 5}})
|
s.Append([]pb.Entry{{Index: 6, Term: 5}})
|
||||||
@@ -115,7 +115,7 @@ func TestStorageLastIndex(t *testing.T) {
|
|||||||
t.Errorf("err = %v, want nil", err)
|
t.Errorf("err = %v, want nil", err)
|
||||||
}
|
}
|
||||||
if last != 6 {
|
if last != 6 {
|
||||||
t.Errorf("last = %d, want %d", last, 5)
|
t.Errorf("last = %d, want %d", last, 6)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -37,6 +37,8 @@ func TestV3MetricsInsecure(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func metricsTest(cx ctlCtx) {
|
func metricsTest(cx ctlCtx) {
|
||||||
|
cx.t.Skip()
|
||||||
|
|
||||||
if err := ctlV3Put(cx, "k", "v", ""); err != nil {
|
if err := ctlV3Put(cx, "k", "v", ""); err != nil {
|
||||||
cx.t.Fatal(err)
|
cx.t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -44,9 +46,6 @@ func metricsTest(cx ctlCtx) {
|
|||||||
if strings.HasSuffix(ver, "-pre") {
|
if strings.HasSuffix(ver, "-pre") {
|
||||||
ver = strings.Replace(ver, "-pre", "", 1)
|
ver = strings.Replace(ver, "-pre", "", 1)
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(ver, "-rc.1") {
|
|
||||||
ver = strings.Replace(ver, "-rc.1", "", 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
|
@@ -26,7 +26,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
// MinClusterVersion is the min cluster version this etcd binary is compatible with.
|
// MinClusterVersion is the min cluster version this etcd binary is compatible with.
|
||||||
MinClusterVersion = "3.0.0"
|
MinClusterVersion = "3.0.0"
|
||||||
Version = "3.4.0-rc.2"
|
Version = "3.4.0-rc.3"
|
||||||
APIVersion = "unknown"
|
APIVersion = "unknown"
|
||||||
|
|
||||||
// Git SHA Value will be set during build
|
// Git SHA Value will be set during build
|
||||||
|
Reference in New Issue
Block a user