github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/helper/raftutil/snapshot.go (about)

     1  package raftutil
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	"github.com/hashicorp/go-hclog"
     8  	"github.com/hashicorp/raft"
     9  
    10  	"github.com/hashicorp/nomad/helper/snapshot"
    11  	"github.com/hashicorp/nomad/nomad"
    12  	"github.com/hashicorp/nomad/nomad/state"
    13  )
    14  
    15  func RestoreFromArchive(archive io.Reader, filter *nomad.FSMFilter) (*state.StateStore, *raft.SnapshotMeta, error) {
    16  	logger := hclog.L()
    17  
    18  	fsm, err := dummyFSM(logger)
    19  	if err != nil {
    20  		return nil, nil, fmt.Errorf("failed to create FSM: %w", err)
    21  	}
    22  
    23  	// r is closed by RestoreFiltered, w is closed by CopySnapshot
    24  	r, w := io.Pipe()
    25  
    26  	errCh := make(chan error)
    27  	metaCh := make(chan *raft.SnapshotMeta)
    28  
    29  	go func() {
    30  		meta, err := snapshot.CopySnapshot(archive, w)
    31  		if err != nil {
    32  			errCh <- fmt.Errorf("failed to read snapshot: %w", err)
    33  		} else {
    34  			metaCh <- meta
    35  		}
    36  	}()
    37  
    38  	err = fsm.RestoreWithFilter(r, filter)
    39  	if err != nil {
    40  		return nil, nil, fmt.Errorf("failed to restore from snapshot: %w", err)
    41  	}
    42  
    43  	select {
    44  	case err := <-errCh:
    45  		return nil, nil, err
    46  	case meta := <-metaCh:
    47  		return fsm.State(), meta, nil
    48  	}
    49  }