diff --git a/cli/context/store/store.go b/cli/context/store/store.go index 4122e077927f..fe17bc15b759 100644 --- a/cli/context/store/store.go +++ b/cli/context/store/store.go @@ -264,8 +264,9 @@ func Export(name string, s Reader) io.ReadCloser { reader, writer := io.Pipe() go func() { tw := tar.NewWriter(writer) - defer tw.Close() - defer writer.Close() + defer func() { + writer.CloseWithError(tw.Close()) + }() meta, err := s.GetMetadata(name) if err != nil { writer.CloseWithError(err) diff --git a/cli/context/store/store_test.go b/cli/context/store/store_test.go index 25bfd87c75c0..bc8d3c5641ad 100644 --- a/cli/context/store/store_test.go +++ b/cli/context/store/store_test.go @@ -89,6 +89,30 @@ func TestExportImport(t *testing.T) { assert.DeepEqual(t, file2, destData2) } +func TestExportProducesCompleteTar(t *testing.T) { + s := New(t.TempDir(), testCfg) + err := s.CreateOrUpdate(Metadata{ + Endpoints: map[string]any{"ep1": endpoint{Foo: "bar"}}, + Metadata: context{Bar: "baz"}, + Name: "source", + }) + assert.NilError(t, err) + assert.NilError(t, s.ResetEndpointTLSMaterial("source", "ep1", &EndpointTLSData{ + Files: map[string][]byte{"ca.pem": []byte("not-block-aligned")}, + })) + + r := Export("source", s) + data, err := io.ReadAll(r) + assert.NilError(t, err) + assert.NilError(t, r.Close()) + + assert.Equal(t, len(data)%tarBlockSize, 0) + assert.Assert(t, len(data) >= 2*tarBlockSize) + assert.DeepEqual(t, data[len(data)-2*tarBlockSize:], make([]byte, 2*tarBlockSize)) +} + +const tarBlockSize = 512 + func TestRemove(t *testing.T) { s := New(t.TempDir(), testCfg) err := s.CreateOrUpdate(