From b0887354e965967b3686343db3d521c7ac650e98 Mon Sep 17 00:00:00 2001 From: Geeta Gharpure Date: Fri, 4 Aug 2023 20:06:18 +0000 Subject: [PATCH] Update etcdutl restore to create v2 snapshot from v3 Signed-off-by: Geeta Gharpure --- etcdutl/snapshot/v3_snapshot.go | 11 ++--------- tests/e2e/cluster_downgrade_test.go | 21 +++++++++++++++++++++ tests/e2e/ctl_v3_snapshot_test.go | 7 +++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/etcdutl/snapshot/v3_snapshot.go b/etcdutl/snapshot/v3_snapshot.go index 00969963d64..8494748d3f9 100644 --- a/etcdutl/snapshot/v3_snapshot.go +++ b/etcdutl/snapshot/v3_snapshot.go @@ -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" @@ -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)) @@ -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, diff --git a/tests/e2e/cluster_downgrade_test.go b/tests/e2e/cluster_downgrade_test.go index 64d6b685064..7da3fb42775 100644 --- a/tests/e2e/cluster_downgrade_test.go +++ b/tests/e2e/cluster_downgrade_test.go @@ -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" @@ -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() diff --git a/tests/e2e/ctl_v3_snapshot_test.go b/tests/e2e/ctl_v3_snapshot_test.go index 3c35f68b715..1a3620bd6bb 100644 --- a/tests/e2e/ctl_v3_snapshot_test.go +++ b/tests/e2e/ctl_v3_snapshot_test.go @@ -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()) @@ -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...")