clientv3/snapshot/v3_snapshot.go
func (s *v3Manager) saveWALAndSnap() error {
	if err := fileutil.CreateDirAll(s.walDir); err != nil {
		return err
	}

	// add members again to persist them to the store we create.
	st := v2store.New(etcdserver.StoreClusterPrefix, etcdserver.StoreKeysPrefix)
	s.cl.SetStore(st)
	for _, m := range s.cl.Members() {
		s.cl.AddMember(m)
	}

	m := s.cl.MemberByName(s.name)
	md := &etcdserverpb.Metadata{NodeID: uint64(m.ID), ClusterID: uint64(s.cl.ID())}
	metadata, merr := md.Marshal()
	if merr != nil {
		return merr
	}
	w, walerr := wal.Create(s.lg, s.walDir, metadata)
	if walerr != nil {
		return walerr
	}
	defer w.Close()

	peers := make([]raft.Peer, len(s.cl.MemberIDs()))
	for i, id := range s.cl.MemberIDs() {
		ctx, err := json.Marshal((*s.cl).Member(id))
		if err != nil {
			return err
		}
		peers[i] = raft.Peer{ID: uint64(id), Context: ctx}
	}

	ents := make([]raftpb.Entry, len(peers))
	nodeIDs := make([]uint64, len(peers))
	for i, p := range peers {
		nodeIDs[i] = p.ID
		cc := raftpb.ConfChange{
			Type:    raftpb.ConfChangeAddNode,
			NodeID:  p.ID,
			Context: p.Context,
		}
		d, err := cc.Marshal()
		if err != nil {
			return err
		}
		ents[i] = raftpb.Entry{
			Type:  raftpb.EntryConfChange,
			Term:  1,
			Index: uint64(i + 1),
			Data:  d,
		}
	}

	commit, term := uint64(len(ents)), uint64(1)
	if err := w.Save(raftpb.HardState{
		Term:   term,
		Vote:   peers[0].ID,
		Commit: commit,
	}, ents); err != nil {
		return err
	}

	b, berr := st.Save()
	if berr != nil {
		return berr
	}
	raftSnap := raftpb.Snapshot{
		Data: b,
		Metadata: raftpb.SnapshotMetadata{
			Index: commit,
			Term:  term,
			ConfState: raftpb.ConfState{
				Nodes: nodeIDs,
			},
		},
	}
	sn := snap.New(s.lg, s.snapDir)
	if err := sn.SaveSnap(raftSnap); err != nil {
		return err
	}
	return w.SaveSnapshot(walpb.Snapshot{Index: commit, Term: term})
}
func (s *v3Manager) saveWALAndSnap() error {
	if err := fileutil.CreateDirAll(s.walDir); err != nil {
		return err
	}

	// add members again to persist them to the store we create.
	st := v2store.New(etcdserver.StoreClusterPrefix, etcdserver.StoreKeysPrefix)
	s.cl.SetStore(st)
	for _, m := range s.cl.Members() {
		s.cl.AddMember(m)
	}

	m := s.cl.MemberByName(s.name)
	md := &etcdserverpb.Metadata{NodeID: uint64(m.ID), ClusterID: uint64(s.cl.ID())}
	metadata, merr := md.Marshal()
	if merr != nil {
		return merr
	}
	w, walerr := wal.Create(s.lg, s.walDir, metadata)
	if walerr != nil {
		return walerr
	}
	defer w.Close()

	peers := make([]raft.Peer, len(s.cl.MemberIDs()))
	for i, id := range s.cl.MemberIDs() {
		ctx, err := json.Marshal((*s.cl).Member(id))
		if err != nil {
			return err
		}
		peers[i] = raft.Peer{ID: uint64(id), Context: ctx}
	}

	ents := make([]raftpb.Entry, len(peers))
	nodeIDs := make([]uint64, len(peers))
	for i, p := range peers {
		nodeIDs[i] = p.ID
		cc := raftpb.ConfChange{
			Type:    raftpb.ConfChangeAddNode,
			NodeID:  p.ID,
			Context: p.Context,
		}
		d, err := cc.Marshal()
		if err != nil {
			return err
		}
		ents[i] = raftpb.Entry{
			Type:  raftpb.EntryConfChange,
			Term:  1,
			Index: uint64(i + 1),
			Data:  d,
		}
	}

	commit, term := uint64(len(ents)), uint64(1)
	if err := w.Save(raftpb.HardState{
		Term:   term,
		Vote:   peers[0].ID,
		Commit: commit,
	}, ents); err != nil {
		return err
	}

	b, berr := st.Save()
	if berr != nil {
		return berr
	}
	raftSnap := raftpb.Snapshot{
		Data: b,
		Metadata: raftpb.SnapshotMetadata{
			Index: commit,
			Term:  term,
			ConfState: raftpb.ConfState{
				Nodes: nodeIDs,
			},
		},
	}
	sn := snap.New(s.lg, s.snapDir)
	if err := sn.SaveSnap(raftSnap); err != nil {
		return err
	}
	return w.SaveSnapshot(walpb.Snapshot{Index: commit, Term: term})
}
func ( s * v3Manager ) saveWALAndSnap ( ) error { if err := fileutil . CreateDirAll ( s . walDir ) ; err != nil { return err } // add members again to persist them to the store we create. st := v2store . New ( etcdserver . StoreClusterPrefix , etcdserver . StoreKeysPrefix ) s . cl . SetStore ( st ) for _ , m := range s . cl . Members ( ) { s . cl . AddMember ( m ) } m := s . cl . MemberByName ( s . name ) md := & etcdserverpb . Metadata { NodeID : uint64 ( m . ID ) , ClusterID : uint64 ( s . cl . ID ( ) ) } metadata , merr := md . Marshal ( ) if merr != nil { return merr } w , walerr := wal . Create ( s . lg , s . walDir , metadata ) if walerr != nil { return walerr } defer w . Close ( ) peers := make ( [ ] raft . Peer , len ( s . cl . MemberIDs ( ) ) ) for i , id := range s . cl . MemberIDs ( ) { ctx , err := json . Marshal ( ( * s . cl ) . Member ( id ) ) if err != nil { return err } peers [ i ] = raft . Peer { ID : uint64 ( id ) , Context : ctx } } ents := make ( [ ] raftpb . Entry , len ( peers ) ) nodeIDs := make ( [ ] uint64 , len ( peers ) ) for i , p := range peers { nodeIDs [ i ] = p . ID cc := raftpb . ConfChange { Type : raftpb . ConfChangeAddNode , NodeID : p . ID , Context : p . Context , } d , err := cc . Marshal ( ) if err != nil { return err } ents [ i ] = raftpb . Entry { Type : raftpb . EntryConfChange , Term : 1 , Index : uint64 ( i + 1 ) , Data : d , } } commit , term := uint64 ( len ( ents ) ) , uint64 ( 1 ) if err := w . Save ( raftpb . HardState { Term : term , Vote : peers [ 0 ] . ID , Commit : commit , } , ents ) ; err != nil { return err } b , berr := st . Save ( ) if berr != nil { return berr } raftSnap := raftpb . Snapshot { Data : b , Metadata : raftpb . SnapshotMetadata { Index : commit , Term : term , ConfState : raftpb . ConfState { Nodes : nodeIDs , } , } , } sn := snap . New ( s . lg , s . snapDir ) if err := sn . SaveSnap ( raftSnap ) ; err != nil { return err } return w . SaveSnapshot ( walpb . Snapshot { Index : commit , Term : term } ) }
// saveWALAndSnap creates a WAL for the initial cluster
saveWALAndSnap creates a WAL for the initial cluster