diff --git a/pkg/v1/tarball/layer.go b/pkg/v1/tarball/layer.go index 8a2630961..68111b021 100644 --- a/pkg/v1/tarball/layer.go +++ b/pkg/v1/tarball/layer.go @@ -130,6 +130,27 @@ func WithMediaType(mt types.MediaType) LayerOption { } } +// WithMediaType is a functional option for overriding the layer's diffID. +func WithDiffID(diffID v1.Hash) LayerOption { + return func(l *layer) { + l.diffID = diffID + } +} + +// WithDigest is a functional option for overriding the layer's digest. +func WithDigest(digest v1.Hash) LayerOption { + return func(l *layer) { + l.digest = digest + } +} + +// WithSize is a functional option for overriding the layer's size. +func WithSize(size int64) LayerOption { + return func(l *layer) { + l.size = size + } +} + // WithCompressedCaching is a functional option that overrides the // logic for accessing the compressed bytes to memoize the result // and avoid expensive repeated gzips. @@ -302,11 +323,13 @@ func LayerFromOpener(opener Opener, opts ...LayerOption) (v1.Layer, error) { logs.Warn.Printf("Unexpected mediaType (%s) for selected compression in %s in LayerFromOpener().", layer.mediaType, layer.compression) } - if layer.digest, layer.size, err = computeDigest(layer.compressedopener); err != nil { - return nil, err + empty := v1.Hash{} + if layer.digest == empty || layer.size == 0 { + if layer.digest, layer.size, err = computeDigest(layer.compressedopener); err != nil { + return nil, err + } } - empty := v1.Hash{} if layer.diffID == empty { if layer.diffID, err = computeDiffID(layer.uncompressedopener); err != nil { return nil, err diff --git a/pkg/v1/tarball/layer_test.go b/pkg/v1/tarball/layer_test.go index a808b5c24..354536df9 100644 --- a/pkg/v1/tarball/layer_test.go +++ b/pkg/v1/tarball/layer_test.go @@ -292,6 +292,53 @@ func TestWithMediaType(t *testing.T) { } } +func TestWithDigestAndSize(t *testing.T) { + l, err := LayerFromFile("testdata/content.tar") + if err != nil { + t.Fatalf("Unable to create layer from tar file: %v", err) + } + + gotDigest, err := l.Digest() + if err != nil { + t.Fatalf("Digest: %v", err) + } + + gotSize, err := l.Size() + if err != nil { + t.Fatalf("Size: %v", err) + } + + l, err = LayerFromFile("testdata/content.tar", WithDigest(gotDigest), WithSize(gotSize)) + if err != nil { + t.Fatalf("Unable to create layer from tar file: %v", err) + } + + if err = validate.Layer(l); err != nil { + t.Fatalf("validate.Layer(l): %v", err) + } +} + +func TestWithDiffID(t *testing.T) { + l, err := LayerFromFile("testdata/content.tar") + if err != nil { + t.Fatalf("Unable to create layer from tar file: %v", err) + } + + gotDiffID, err := l.DiffID() + if err != nil { + t.Fatalf("DiffID: %v", err) + } + + l, err = LayerFromFile("testdata/content.tar", WithDiffID(gotDiffID)) + if err != nil { + t.Fatalf("Unable to create layer from tar file: %v", err) + } + + if err = validate.Layer(l); err != nil { + t.Fatalf("validate.Layer(l): %v", err) + } +} + func TestLayerFromReader(t *testing.T) { setupFixtures(t) defer teardownFixtures(t)