backend/remote-state: Get all the backend tests building again

The state manager refactoring in an earlier commit was reflected in the
implementations of these backends, but not in their tests. This gets us
back to a state where the backend tests will compile, and gets _most_ of
them passing again, with a few exceptions that will be addressed in a
subsequent commit.
This commit is contained in:
Martin Atkins 2018-10-01 14:35:23 -07:00
parent 058a1d81b0
commit aaf405b662
15 changed files with 95 additions and 103 deletions

View File

@ -30,7 +30,7 @@ func testStateClient(t *testing.T, c map[string]string) remote.Client {
synthBody := configs.SynthBody("<test>", vals)
b := backend.TestBackendConfig(t, &Backend{}, synthBody)
raw, err := b.State(backend.DefaultStateName)
raw, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("err: %s", err)
}

View File

@ -30,7 +30,7 @@ func TestArtifactoryFactory(t *testing.T) {
b := backend.TestBackendConfig(t, New(), configs.SynthBody("synth", config))
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("Error for valid config: %s", err)
}

View File

@ -28,7 +28,7 @@ func TestRemoteClient(t *testing.T) {
"access_key": res.accessKey,
})).(*Backend)
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -57,12 +57,12 @@ func TestRemoteClientLocks(t *testing.T) {
"access_key": res.accessKey,
})).(*Backend)
s1, err := b1.State(backend.DefaultStateName)
s1, err := b1.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
s2, err := b2.State(backend.DefaultStateName)
s2, err := b2.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}

View File

@ -26,7 +26,7 @@ func TestRemoteClient(t *testing.T) {
}))
// Grab the client
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("err: %s", err)
}
@ -46,7 +46,7 @@ func TestRemoteClient_gzipUpgrade(t *testing.T) {
}))
// Grab the client
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("err: %s", err)
}
@ -62,7 +62,7 @@ func TestRemoteClient_gzipUpgrade(t *testing.T) {
}))
// Grab the client
state, err = b.State(backend.DefaultStateName)
state, err = b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("err: %s", err)
}
@ -78,7 +78,7 @@ func TestConsul_stateLock(t *testing.T) {
sA, err := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
"address": srv.HTTPAddr,
"path": path,
})).State(backend.DefaultStateName)
})).StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -86,7 +86,7 @@ func TestConsul_stateLock(t *testing.T) {
sB, err := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
"address": srv.HTTPAddr,
"path": path,
})).State(backend.DefaultStateName)
})).StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -102,7 +102,7 @@ func TestConsul_destroyLock(t *testing.T) {
}))
// Grab the client
s, err := b.State(backend.DefaultStateName)
s, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("err: %s", err)
}
@ -138,7 +138,7 @@ func TestConsul_lostLock(t *testing.T) {
sA, err := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
"address": srv.HTTPAddr,
"path": path,
})).State(backend.DefaultStateName)
})).StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -146,7 +146,7 @@ func TestConsul_lostLock(t *testing.T) {
sB, err := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
"address": srv.HTTPAddr,
"path": path + "-not-used",
})).State(backend.DefaultStateName)
})).StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -195,7 +195,7 @@ func TestConsul_lostLockConnection(t *testing.T) {
"path": path,
}))
s, err := b.State(backend.DefaultStateName)
s, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}

View File

@ -36,7 +36,7 @@ func TestEtcdClient(t *testing.T) {
}
b := backend.TestBackendConfig(t, New(), configs.SynthBody("synth", config))
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("Error for valid config: %s", err)
}

View File

@ -28,7 +28,7 @@ func TestRemoteClient(t *testing.T) {
}))
// Grab the client
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("Error: %s.", err)
}
@ -47,7 +47,7 @@ func TestEtcdv3_stateLock(t *testing.T) {
s1, err := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
"endpoints": etcdv3Endpoints,
"prefix": prefix,
})).State(backend.DefaultStateName)
})).StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -55,7 +55,7 @@ func TestEtcdv3_stateLock(t *testing.T) {
s2, err := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
"endpoints": etcdv3Endpoints,
"prefix": prefix,
})).State(backend.DefaultStateName)
})).StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -76,7 +76,7 @@ func TestEtcdv3_destroyLock(t *testing.T) {
}))
// Grab the client
s, err := b.State(backend.DefaultStateName)
s, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("err: %s", err)
}

View File

@ -61,14 +61,14 @@ func TestRemoteClient(t *testing.T) {
be := setupBackend(t, bucket, noPrefix, noEncryptionKey)
defer teardownBackend(t, be, noPrefix)
ss, err := be.State(backend.DefaultStateName)
ss, err := be.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("be.State(%q) = %v", backend.DefaultStateName, err)
t.Fatalf("be.StateMgr(%q) = %v", backend.DefaultStateName, err)
}
rs, ok := ss.(*remote.State)
if !ok {
t.Fatalf("be.State(): got a %T, want a *remote.State", ss)
t.Fatalf("be.StateMgr(): got a %T, want a *remote.State", ss)
}
remote.TestClient(t, rs.Client)
@ -80,14 +80,14 @@ func TestRemoteClientWithEncryption(t *testing.T) {
be := setupBackend(t, bucket, noPrefix, encryptionKey)
defer teardownBackend(t, be, noPrefix)
ss, err := be.State(backend.DefaultStateName)
ss, err := be.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatalf("be.State(%q) = %v", backend.DefaultStateName, err)
t.Fatalf("be.StateMgr(%q) = %v", backend.DefaultStateName, err)
}
rs, ok := ss.(*remote.State)
if !ok {
t.Fatalf("be.State(): got a %T, want a *remote.State", ss)
t.Fatalf("be.StateMgr(): got a %T, want a *remote.State", ss)
}
remote.TestClient(t, rs.Client)
@ -101,14 +101,14 @@ func TestRemoteLocks(t *testing.T) {
defer teardownBackend(t, be, noPrefix)
remoteClient := func() (remote.Client, error) {
ss, err := be.State(backend.DefaultStateName)
ss, err := be.StateMgr(backend.DefaultStateName)
if err != nil {
return nil, err
}
rs, ok := ss.(*remote.State)
if !ok {
return nil, fmt.Errorf("be.State(): got a %T, want a *remote.State", ss)
return nil, fmt.Errorf("be.StateMgr(): got a %T, want a *remote.State", ss)
}
return rs.Client, nil

View File

@ -6,7 +6,7 @@ import (
"github.com/hashicorp/hcl2/hcl"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/state/remote"
"github.com/hashicorp/terraform/terraform"
statespkg "github.com/hashicorp/terraform/states"
)
func TestBackend_impl(t *testing.T) {
@ -23,7 +23,7 @@ func TestBackendConfig(t *testing.T) {
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend)
s, err := b.State(backend.DefaultStateName)
s, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -39,6 +39,7 @@ func TestBackendConfig(t *testing.T) {
}
func TestBackend(t *testing.T) {
t.Fatalf("FIXME: this test seems to be hanging or getting into an infinite loop")
defer Reset()
b := backend.TestBackendConfig(t, New(), hcl.EmptyBody()).(*Backend)
backend.TestBackendStates(t, b)
@ -54,19 +55,20 @@ func TestBackendLocked(t *testing.T) {
// use the this backen to test the remote.State implementation
func TestRemoteState(t *testing.T) {
t.Fatalf("FIXME: this test seems to be hanging or getting into an infinite loop")
defer Reset()
b := backend.TestBackendConfig(t, New(), hcl.EmptyBody())
workspace := "workspace"
// create a new workspace in this backend
s, err := b.State(workspace)
s, err := b.StateMgr(workspace)
if err != nil {
t.Fatal(err)
}
// force overwriting the remote state
newState := terraform.NewState()
newState := statespkg.NewState()
if err := s.WriteState(newState); err != nil {
t.Fatal(err)
@ -79,13 +81,4 @@ func TestRemoteState(t *testing.T) {
if err := s.RefreshState(); err != nil {
t.Fatal(err)
}
savedState := s.State()
if err != nil {
t.Fatal(err)
}
if savedState.Lineage != newState.Lineage {
t.Fatal("saved state has incorrect lineage")
}
}

View File

@ -17,7 +17,7 @@ func TestRemoteClient(t *testing.T) {
defer Reset()
b := backend.TestBackendConfig(t, New(), hcl.EmptyBody())
s, err := b.State(backend.DefaultStateName)
s, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -27,7 +27,7 @@ func TestRemoteClient(t *testing.T) {
func TestInmemLocks(t *testing.T) {
defer Reset()
s, err := backend.TestBackendConfig(t, New(), hcl.EmptyBody()).State(backend.DefaultStateName)
s, err := backend.TestBackendConfig(t, New(), hcl.EmptyBody()).StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}

View File

@ -28,7 +28,7 @@ func TestRemoteClient(t *testing.T) {
createMantaFolder(t, b.storageClient, directory)
defer deleteMantaFolder(t, b.storageClient, directory)
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -54,12 +54,12 @@ func TestRemoteClientLocks(t *testing.T) {
createMantaFolder(t, b1.storageClient, directory)
defer deleteMantaFolder(t, b1.storageClient, directory)
s1, err := b1.State(backend.DefaultStateName)
s1, err := b1.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
s2, err := b2.State(backend.DefaultStateName)
s2, err := b2.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}

View File

@ -13,7 +13,7 @@ import (
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config/hcl2shim"
"github.com/hashicorp/terraform/state/remote"
"github.com/hashicorp/terraform/terraform"
"github.com/hashicorp/terraform/states"
)
// verify that we are doing ACC tests or the S3 tests specifically
@ -145,8 +145,8 @@ func TestBackendExtraPaths(t *testing.T) {
defer deleteS3Bucket(t, b.s3Client, bucketName)
// put multiple states in old env paths.
s1 := terraform.NewState()
s2 := terraform.NewState()
s1 := states.NewState()
s2 := states.NewState()
// RemoteClient to Put things in various paths
client := &RemoteClient{
@ -172,13 +172,15 @@ func TestBackendExtraPaths(t *testing.T) {
t.Fatal(err)
}
s2Lineage := stateMgr.StateSnapshotMeta().Lineage
if err := checkStateList(b, []string{"default", "s1", "s2"}); err != nil {
t.Fatal(err)
}
// put a state in an env directory name
client.path = b.workspaceKeyPrefix + "/error"
stateMgr.WriteState(terraform.NewState())
stateMgr.WriteState(states.NewState())
if err := stateMgr.PersistState(); err != nil {
t.Fatal(err)
}
@ -188,7 +190,7 @@ func TestBackendExtraPaths(t *testing.T) {
// add state with the wrong key for an existing env
client.path = b.workspaceKeyPrefix + "/s2/notTestState"
stateMgr.WriteState(terraform.NewState())
stateMgr.WriteState(states.NewState())
if err := stateMgr.PersistState(); err != nil {
t.Fatal(err)
}
@ -197,7 +199,7 @@ func TestBackendExtraPaths(t *testing.T) {
}
// remove the state with extra subkey
if err := b.DeleteState("s2"); err != nil {
if err := b.DeleteWorkspace("s2"); err != nil {
t.Fatal(err)
}
@ -206,7 +208,7 @@ func TestBackendExtraPaths(t *testing.T) {
}
// fetch that state again, which should produce a new lineage
s2Mgr, err := b.State("s2")
s2Mgr, err := b.StateMgr("s2")
if err != nil {
t.Fatal(err)
}
@ -214,20 +216,21 @@ func TestBackendExtraPaths(t *testing.T) {
t.Fatal(err)
}
if s2Mgr.State().Lineage == s2.Lineage {
if stateMgr.StateSnapshotMeta().Lineage == s2Lineage {
t.Fatal("state s2 was not deleted")
}
s2 = s2Mgr.State()
s2Lineage = stateMgr.StateSnapshotMeta().Lineage
// add a state with a key that matches an existing environment dir name
client.path = b.workspaceKeyPrefix + "/s2/"
stateMgr.WriteState(terraform.NewState())
stateMgr.WriteState(states.NewState())
if err := stateMgr.PersistState(); err != nil {
t.Fatal(err)
}
// make sure s2 is OK
s2Mgr, err = b.State("s2")
s2Mgr, err = b.StateMgr("s2")
if err != nil {
t.Fatal(err)
}
@ -235,7 +238,7 @@ func TestBackendExtraPaths(t *testing.T) {
t.Fatal(err)
}
if s2Mgr.State().Lineage != s2.Lineage {
if stateMgr.StateSnapshotMeta().Lineage != s2Lineage {
t.Fatal("we got the wrong state for s2")
}
@ -260,7 +263,7 @@ func TestBackendPrefixInWorkspace(t *testing.T) {
defer deleteS3Bucket(t, b.s3Client, bucketName)
// get a state that contains the prefix as a substring
sMgr, err := b.State("env-1")
sMgr, err := b.StateMgr("env-1")
if err != nil {
t.Fatal(err)
}
@ -342,7 +345,7 @@ func testGetWorkspaceForKey(b *Backend, key string, expected string) error {
}
func checkStateList(b backend.Backend, expected []string) error {
states, err := b.States()
states, err := b.Workspaces()
if err != nil {
return err
}

View File

@ -11,7 +11,7 @@ import (
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/state"
"github.com/hashicorp/terraform/state/remote"
"github.com/hashicorp/terraform/terraform"
"github.com/hashicorp/terraform/states/statefile"
)
func TestRemoteClient_impl(t *testing.T) {
@ -33,7 +33,7 @@ func TestRemoteClient(t *testing.T) {
createS3Bucket(t, b.s3Client, bucketName)
defer deleteS3Bucket(t, b.s3Client, bucketName)
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -65,12 +65,12 @@ func TestRemoteClientLocks(t *testing.T) {
createDynamoDBTable(t, b1.dynClient, bucketName)
defer deleteDynamoDBTable(t, b1.dynClient, bucketName)
s1, err := b1.State(backend.DefaultStateName)
s1, err := b1.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
s2, err := b2.State(backend.DefaultStateName)
s2, err := b2.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -104,7 +104,7 @@ func TestForceUnlock(t *testing.T) {
defer deleteDynamoDBTable(t, b1.dynClient, bucketName)
// first test with default
s1, err := b1.State(backend.DefaultStateName)
s1, err := b1.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -119,7 +119,7 @@ func TestForceUnlock(t *testing.T) {
}
// s1 is now locked, get the same state through s2 and unlock it
s2, err := b2.State(backend.DefaultStateName)
s2, err := b2.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal("failed to get default state to force unlock:", err)
}
@ -130,7 +130,7 @@ func TestForceUnlock(t *testing.T) {
// now try the same thing with a named state
// first test with default
s1, err = b1.State("test")
s1, err = b1.StateMgr("test")
if err != nil {
t.Fatal(err)
}
@ -145,7 +145,7 @@ func TestForceUnlock(t *testing.T) {
}
// s1 is now locked, get the same state through s2 and unlock it
s2, err = b2.State("test")
s2, err = b2.StateMgr("test")
if err != nil {
t.Fatal("failed to get named state to force unlock:", err)
}
@ -172,7 +172,7 @@ func TestRemoteClient_clientMD5(t *testing.T) {
createDynamoDBTable(t, b.dynClient, bucketName)
defer deleteDynamoDBTable(t, b.dynClient, bucketName)
s, err := b.State(backend.DefaultStateName)
s, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -220,7 +220,7 @@ func TestRemoteClient_stateChecksum(t *testing.T) {
createDynamoDBTable(t, b1.dynClient, bucketName)
defer deleteDynamoDBTable(t, b1.dynClient, bucketName)
s1, err := b1.State(backend.DefaultStateName)
s1, err := b1.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
@ -228,13 +228,14 @@ func TestRemoteClient_stateChecksum(t *testing.T) {
// create a old and new state version to persist
s := state.TestStateInitial()
sf := &statefile.File{State: s}
var oldState bytes.Buffer
if err := terraform.WriteState(s, &oldState); err != nil {
if err := statefile.Write(sf, &oldState); err != nil {
t.Fatal(err)
}
s.Serial++
sf.Serial++
var newState bytes.Buffer
if err := terraform.WriteState(s, &newState); err != nil {
if err := statefile.Write(sf, &newState); err != nil {
t.Fatal(err)
}
@ -244,7 +245,7 @@ func TestRemoteClient_stateChecksum(t *testing.T) {
"bucket": bucketName,
"key": keyName,
})).(*Backend)
s2, err := b2.State(backend.DefaultStateName)
s2, err := b2.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}

View File

@ -11,9 +11,13 @@ import (
"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers"
"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects"
"github.com/gophercloud/gophercloud/pagination"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/state/remote"
"github.com/hashicorp/terraform/terraform"
"github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/states/statefile"
)
// verify that we are doing ACC tests or the Swift tests specifically
@ -85,9 +89,7 @@ func TestBackendPath(t *testing.T) {
t.Logf("[DEBUG] Testing Backend")
// Generate some state
state1 := terraform.NewState()
// state1Lineage := state1.Lineage
t.Logf("state1 lineage = %s, serial = %d", state1.Lineage, state1.Serial)
state1 := states.NewState()
// RemoteClient to test with
client := &RemoteClient{
@ -108,16 +110,8 @@ func TestBackendPath(t *testing.T) {
}
// Add some state
state1.AddModuleState(&terraform.ModuleState{
Path: []string{"root"},
Outputs: map[string]*terraform.OutputState{
"bar": &terraform.OutputState{
Type: "string",
Sensitive: false,
Value: "baz",
},
},
})
mod := state1.EnsureModule(addrs.RootModuleInstance)
mod.SetOutputValue("bar", cty.StringVal("baz"), false)
stateMgr.WriteState(state1)
if err := stateMgr.PersistState(); err != nil {
t.Fatal(err)
@ -140,9 +134,7 @@ func TestBackendArchive(t *testing.T) {
defer deleteSwiftContainer(t, b.client, archiveContainer)
// Generate some state
state1 := terraform.NewState()
// state1Lineage := state1.Lineage
t.Logf("state1 lineage = %s, serial = %d", state1.Lineage, state1.Serial)
state1 := states.NewState()
// RemoteClient to test with
client := &RemoteClient{
@ -163,16 +155,8 @@ func TestBackendArchive(t *testing.T) {
}
// Add some state
state1.AddModuleState(&terraform.ModuleState{
Path: []string{"root"},
Outputs: map[string]*terraform.OutputState{
"bar": &terraform.OutputState{
Type: "string",
Sensitive: false,
Value: "baz",
},
},
})
mod := state1.EnsureModule(addrs.RootModuleInstance)
mod.SetOutputValue("bar", cty.StringVal("baz"), false)
stateMgr.WriteState(state1)
if err := stateMgr.PersistState(); err != nil {
t.Fatal(err)
@ -187,13 +171,13 @@ func TestBackendArchive(t *testing.T) {
// Download archive state to validate
archiveData := downloadSwiftObject(t, b.client, archiveContainer, archiveObjects[0])
t.Logf("Archive data downloaded... Looks like: %+v", archiveData)
archiveState, err := terraform.ReadState(archiveData)
archiveStateFile, err := statefile.Read(archiveData)
if err != nil {
t.Fatalf("Error Reading State: %s", err)
}
t.Logf("Archive state lineage = %s, serial = %d, lineage match = %t", archiveState.Lineage, archiveState.Serial, stateMgr.State().SameLineage(archiveState))
if !stateMgr.State().SameLineage(archiveState) {
t.Logf("Archive state lineage = %s, serial = %d", archiveStateFile.Lineage, archiveStateFile.Serial)
if stateMgr.StateSnapshotMeta().Lineage != archiveStateFile.Lineage {
t.Fatal("Got a different lineage")
}

View File

@ -22,7 +22,7 @@ func TestRemoteClient(t *testing.T) {
"container": container,
})).(*Backend)
state, err := b.State(backend.DefaultStateName)
state, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}

View File

@ -164,3 +164,14 @@ func (s *State) Unlock(id string) error {
func (s *State) DisableLocks() {
s.disableLocks = true
}
// StateSnapshotMeta returns the metadata from the most recently persisted
// or refreshed persistent state snapshot.
//
// This is an implementation of statemgr.PersistentMeta.
func (s *State) StateSnapshotMeta() statemgr.SnapshotMeta {
return statemgr.SnapshotMeta{
Lineage: s.lineage,
Serial: s.serial,
}
}