Skip to content

Commit

Permalink
Update etcdutl restore to create v2 snapshot from v3
Browse files Browse the repository at this point in the history
Signed-off-by: Geeta Gharpure <[email protected]>
  • Loading branch information
Geeta Gharpure committed Aug 11, 2023
1 parent def3494 commit b088735
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 9 deletions.
11 changes: 2 additions & 9 deletions etcdutl/snapshot/v3_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import (
"go.etcd.io/etcd/server/v3/etcdserver"
"go.etcd.io/etcd/server/v3/etcdserver/api/membership"
"go.etcd.io/etcd/server/v3/etcdserver/api/snap"
"go.etcd.io/etcd/server/v3/etcdserver/api/v2store"
"go.etcd.io/etcd/server/v3/etcdserver/cindex"
"go.etcd.io/etcd/server/v3/storage/backend"
"go.etcd.io/etcd/server/v3/storage/mvcc"
Expand Down Expand Up @@ -472,9 +471,7 @@ func (s *v3Manager) saveWALAndSnap() (*raftpb.HardState, error) {
return nil, err
}

// add members again to persist them to the store we create.
st := v2store.New(etcdserver.StoreClusterPrefix, etcdserver.StoreKeysPrefix)
s.cl.SetStore(st)
// add members again to persist them to the backend we create.
be := backend.NewDefaultBackend(s.lg, s.outDbPath())
defer be.Close()
s.cl.SetBackend(schema.NewMembershipBackend(s.lg, be))
Expand Down Expand Up @@ -534,15 +531,11 @@ func (s *v3Manager) saveWALAndSnap() (*raftpb.HardState, error) {
return nil, err
}

b, berr := st.Save()
if berr != nil {
return nil, berr
}
confState := raftpb.ConfState{
Voters: nodeIDs,
}
raftSnap := raftpb.Snapshot{
Data: b,
Data: etcdserver.GetMembershipInfoInV2Format(s.lg, s.cl),
Metadata: raftpb.SnapshotMetadata{
Index: commit,
Term: term,
Expand Down
21 changes: 21 additions & 0 deletions tests/e2e/cluster_downgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ import (

"go.etcd.io/etcd/api/v3/version"
"go.etcd.io/etcd/client/pkg/v3/fileutil"
"go.etcd.io/etcd/client/pkg/v3/types"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/server/v3/etcdserver"
"go.etcd.io/etcd/server/v3/etcdserver/api/membership"
"go.etcd.io/etcd/server/v3/etcdserver/api/snap"
"go.etcd.io/etcd/server/v3/etcdserver/api/v2store"
"go.etcd.io/etcd/server/v3/storage/datadir"
"go.etcd.io/etcd/tests/v3/framework/config"
"go.etcd.io/etcd/tests/v3/framework/e2e"
Expand Down Expand Up @@ -293,6 +297,23 @@ func verifySnapshot(t *testing.T, epc *e2e.EtcdProcessCluster) {
t.Logf("All members have a valid snapshot")
}

func verifySnapshotMembers(t *testing.T, epc *e2e.EtcdProcessCluster, expectedMembers *clientv3.MemberListResponse) {
for i := range epc.Procs {
t.Logf("Verifying snapshot for member %d", i)
ss := snap.New(epc.Cfg.Logger, datadir.ToSnapDir(epc.Procs[i].Config().DataDirPath))
snap, err := ss.Load()
st := v2store.New(etcdserver.StoreClusterPrefix, etcdserver.StoreKeysPrefix)
err = st.Recovery(snap.Data)
assert.NoError(t, err)
for _, m := range expectedMembers.Members {
_, err := st.Get(membership.MemberStoreKey(types.ID(m.ID)), true, true)
assert.NoError(t, err)
}
t.Logf("Verifed snapshot for member %d", i)
}
t.Log("All members have a valid snapshot")
}

func getMembersAndKeys(t *testing.T, epc *e2e.EtcdProcessCluster) (*clientv3.MemberListResponse, *clientv3.GetResponse) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
Expand Down
7 changes: 7 additions & 0 deletions tests/e2e/ctl_v3_snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,9 @@ func TestRestoreCompactionRevBump(t *testing.T) {
require.NoError(t, ctl.Put(context.Background(), unsnappedKVs[i].Key, unsnappedKVs[i].Val, config.PutOptions{}))
}

membersBefore, err := ctl.MemberList(context.Background(), false)
require.NoError(t, err)

t.Log("Stopping the original server...")
require.NoError(t, epc.Stop())

Expand All @@ -380,12 +383,16 @@ func TestRestoreCompactionRevBump(t *testing.T) {

t.Log("(Re)starting the etcd member using the restored snapshot...")
epc.Procs[0].Config().DataDirPath = newDataDir

for i := range epc.Procs[0].Config().Args {
if epc.Procs[0].Config().Args[i] == "--data-dir" {
epc.Procs[0].Config().Args[i+1] = newDataDir
}
}

// Verify that initial snapshot is created by the restore operation
verifySnapshotMembers(t, epc, membersBefore)

require.NoError(t, epc.Restart(context.Background()))

t.Log("Ensuring the restored member has the correct data...")
Expand Down

0 comments on commit b088735

Please sign in to comment.