Skip to content

Commit a8b2234

Browse files
committed
XX
Split copy pipeline up Signed-off-by: Miloslav Trmač <[email protected]>
1 parent dc9eca0 commit a8b2234

7 files changed

Lines changed: 107 additions & 12 deletions

File tree

copy/compression.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,17 @@ func (ic *imageCopier) bpcPreserveEncrypted(stream *sourceStream, _ bpDetectComp
104104

105105
// bpcCompressUncompressed checks if we should be compressing an uncompressed input, and returns a *bpCompressionStepData if so.
106106
func (ic *imageCopier) bpcCompressUncompressed(stream *sourceStream, detected bpDetectCompressionStepData) (*bpCompressionStepData, error) {
107-
if ic.c.dest.DesiredLayerCompression() == types.Compress && !detected.isCompressed {
107+
var chosenFormat *compressiontypes.Algorithm
108+
if ic.c.compressionFormat != nil {
109+
chosenFormat = ic.c.compressionFormat
110+
} else {
111+
chosenFormat = defaultCompressionFormat
112+
}
113+
if ic.c.dest.DesiredLayerCompression() == types.Compress && !detected.isCompressed &&
114+
ic.src.CanCompressLayer(stream.info.MediaType, chosenFormat) {
108115
logrus.Debugf("Compressing blob on the fly")
109-
var uploadedAlgorithm *compressiontypes.Algorithm
110-
if ic.c.compressionFormat != nil {
111-
uploadedAlgorithm = ic.c.compressionFormat
112-
} else {
113-
uploadedAlgorithm = defaultCompressionFormat
114-
}
115116

116-
reader, annotations := ic.c.compressedStream(stream.reader, *uploadedAlgorithm)
117+
reader, annotations := ic.c.compressedStream(stream.reader, *chosenFormat)
117118
// Note: reader must be closed on all return paths.
118119
stream.reader = reader
119120
stream.info = types.BlobInfo{ // FIXME? Should we preserve more data in src.info?
@@ -122,10 +123,10 @@ func (ic *imageCopier) bpcCompressUncompressed(stream *sourceStream, detected bp
122123
}
123124
return &bpCompressionStepData{
124125
operation: types.Compress,
125-
uploadedAlgorithm: uploadedAlgorithm,
126+
uploadedAlgorithm: chosenFormat,
126127
uploadedAnnotations: annotations,
127128
srcCompressorName: detected.srcCompressorName,
128-
uploadedCompressorName: uploadedAlgorithm.Name(),
129+
uploadedCompressorName: chosenFormat.Name(),
129130
closers: []io.Closer{reader},
130131
}, nil
131132
}
@@ -135,7 +136,8 @@ func (ic *imageCopier) bpcCompressUncompressed(stream *sourceStream, detected bp
135136
// bpcRecompressCompressed checks if we should be recompressing a compressed input to another format, and returns a *bpCompressionStepData if so.
136137
func (ic *imageCopier) bpcRecompressCompressed(stream *sourceStream, detected bpDetectCompressionStepData) (*bpCompressionStepData, error) {
137138
if ic.c.dest.DesiredLayerCompression() == types.Compress && detected.isCompressed &&
138-
ic.c.compressionFormat != nil && ic.c.compressionFormat.Name() != detected.format.Name() {
139+
ic.c.compressionFormat != nil && ic.c.compressionFormat.Name() != detected.format.Name() &&
140+
ic.src.CanCompressLayer(stream.info.MediaType, ic.c.compressionFormat) {
139141
// When the blob is compressed, but the desired format is different, it first needs to be decompressed and finally
140142
// re-compressed using the desired format.
141143
logrus.Debugf("Blob will be converted")
@@ -173,7 +175,8 @@ func (ic *imageCopier) bpcRecompressCompressed(stream *sourceStream, detected bp
173175

174176
// bpcDecompressCompressed checks if we should be decompressing a compressed input, and returns a *bpCompressionStepData if so.
175177
func (ic *imageCopier) bpcDecompressCompressed(stream *sourceStream, detected bpDetectCompressionStepData) (*bpCompressionStepData, error) {
176-
if ic.c.dest.DesiredLayerCompression() == types.Decompress && detected.isCompressed {
178+
if ic.c.dest.DesiredLayerCompression() == types.Decompress && detected.isCompressed &&
179+
ic.src.CanDecompressLayer(stream.info.MediaType) {
177180
logrus.Debugf("Blob will be decompressed")
178181
s, err := detected.decompressor(stream.reader)
179182
if err != nil {

internal/image/docker_schema1.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/containers/image/v5/docker/reference"
77
"github.com/containers/image/v5/manifest"
8+
compression "github.com/containers/image/v5/pkg/compression/types"
89
"github.com/containers/image/v5/types"
910
"github.com/opencontainers/go-digest"
1011
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
@@ -257,3 +258,18 @@ func (m *manifestSchema1) CanSubstituteLayers() bool {
257258
func (m *manifestSchema1) CanChangeLayerCompression(mimeType string) bool {
258259
return true // There are no MIME types in the manifest, so we must assume a valid image.
259260
}
261+
262+
// CanDecompressLayer returns true if a layer with mimeType can be decompressed (and the code can handle that)
263+
// FIXME FIXME: Some other API
264+
// FIXME FIXME: Tests
265+
func (m *manifestSchema1) CanDecompressLayer(mimeType string) bool {
266+
return true // There are no MIME types in the manifest, so we must assume a valid image.
267+
}
268+
269+
// CanDecompressLayer returns true if a layer with mimeType can be (re)compressed to algorithm (and the code can handle that)
270+
// FIXME FIXME: Some other API
271+
// FIXME FIXME: Tests
272+
func (m *manifestSchema1) CanCompressLayer(mimeType string, algorithm *compression.Algorithm) bool {
273+
// There are no MIME types in the manifest, so we must assume a valid image. But gzip is the only supported format.
274+
return algorithm.Name() == compression.GzipAlgorithmName
275+
}

internal/image/docker_schema2.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/containers/image/v5/internal/iolimits"
1414
"github.com/containers/image/v5/manifest"
1515
"github.com/containers/image/v5/pkg/blobinfocache/none"
16+
compression "github.com/containers/image/v5/pkg/compression/types"
1617
"github.com/containers/image/v5/types"
1718
"github.com/opencontainers/go-digest"
1819
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
@@ -413,3 +414,17 @@ func (m *manifestSchema2) CanSubstituteLayers() bool {
413414
func (m *manifestSchema2) CanChangeLayerCompression(mimeType string) bool {
414415
return m.m.CanChangeLayerCompression(mimeType)
415416
}
417+
418+
// CanDecompressLayer returns true if a layer with mimeType can be decompressed (and the code can handle that)
419+
// FIXME FIXME: Some other API
420+
// FIXME FIXME: Tests
421+
func (m *manifestSchema2) CanDecompressLayer(mimeType string) bool {
422+
return m.m.CanDecompressLayer(mimeType)
423+
}
424+
425+
// CanDecompressLayer returns true if a layer with mimeType can be (re)compressed to algorithm (and the code can handle that)
426+
// FIXME FIXME: Some other API
427+
// FIXME FIXME: Tests
428+
func (m *manifestSchema2) CanCompressLayer(mimeType string, algorithm *compression.Algorithm) bool {
429+
return m.m.CanCompressLayer(mimeType, algorithm)
430+
}

internal/image/manifest.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/containers/image/v5/docker/reference"
88
"github.com/containers/image/v5/manifest"
9+
compression "github.com/containers/image/v5/pkg/compression/types"
910
"github.com/containers/image/v5/types"
1011
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
1112
"github.com/pkg/errors"
@@ -57,7 +58,14 @@ type genericManifest interface {
5758
// CanSubstituteBlobs returns true if the generic image copy code is allowed to substitute layers with their semantic equivalents.
5859
CanSubstituteLayers() bool
5960
// CanChangeLayerCompression returns true if it is allowed to compress/decompress layers with mimeType (and the code can handle that)
61+
// FIXME FIXME: This does not say which compression formats are supported, and it almost certainly should.
6062
CanChangeLayerCompression(mimeType string) bool
63+
// CanDecompressLayer returns true if a layer with mimeType can be decompressed (and the code can handle that)
64+
// FIXME FIXME: Some other API
65+
CanDecompressLayer(mimeType string) bool
66+
// CanDecompressLayer returns true if a layer with mimeType can be (re)compressed to algorithm (and the code can handle that)
67+
// FIXME FIXME: Some other API
68+
CanCompressLayer(mimeType string, algorithm *compression.Algorithm) bool
6169
}
6270

6371
// manifestInstanceFromBlob returns a genericManifest implementation for (manblob, mt) in src.

internal/image/oci.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
internalManifest "github.com/containers/image/v5/internal/manifest"
1111
"github.com/containers/image/v5/manifest"
1212
"github.com/containers/image/v5/pkg/blobinfocache/none"
13+
compression "github.com/containers/image/v5/pkg/compression/types"
1314
"github.com/containers/image/v5/types"
1415
"github.com/opencontainers/go-digest"
1516
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
@@ -272,3 +273,17 @@ func (m *manifestOCI1) CanSubstituteLayers() bool {
272273
func (m *manifestOCI1) CanChangeLayerCompression(mimeType string) bool {
273274
return m.m.CanChangeLayerCompression(mimeType)
274275
}
276+
277+
// CanDecompressLayer returns true if a layer with mimeType can be decompressed (and the code can handle that)
278+
// FIXME FIXME: Some other API
279+
// FIXME FIXME: Tests
280+
func (m *manifestOCI1) CanDecompressLayer(mimeType string) bool {
281+
return m.m.CanDecompressLayer(mimeType)
282+
}
283+
284+
// CanDecompressLayer returns true if a layer with mimeType can be (re)compressed to algorithm (and the code can handle that)
285+
// FIXME FIXME: Some other API
286+
// FIXME FIXME: Tests
287+
func (m *manifestOCI1) CanCompressLayer(mimeType string, algorithm *compression.Algorithm) bool {
288+
return m.m.CanCompressLayer(mimeType, algorithm)
289+
}

manifest/docker_schema2.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,19 @@ func (m *Schema2) ImageID([]digest.Digest) (string, error) {
301301
func (m *Schema2) CanChangeLayerCompression(mimeType string) bool {
302302
return compressionVariantsRecognizeMIMEType(schema2CompressionMIMETypeSets, mimeType)
303303
}
304+
305+
// CanDecompressLayer returns true if a layer with mimeType can be decompressed (and the code can handle that)
306+
// FIXME FIXME: Some other API
307+
// FIXME FIXME: Tests
308+
func (m *Schema2) CanDecompressLayer(mimeType string) bool {
309+
_, err := compressionVariantMIMEType(schema2CompressionMIMETypeSets, mimeType, nil)
310+
return err == nil
311+
}
312+
313+
// CanDecompressLayer returns true if a layer with mimeType can be (re)compressed to algorithm (and the code can handle that)
314+
// FIXME FIXME: Some other API
315+
// FIXME FIXME: Tests
316+
func (m *Schema2) CanCompressLayer(mimeType string, algorithm *compressiontypes.Algorithm) bool {
317+
_, err := compressionVariantMIMEType(schema2CompressionMIMETypeSets, mimeType, algorithm)
318+
return err == nil
319+
}

manifest/oci.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,25 @@ func (m *OCI1) CanChangeLayerCompression(mimeType string) bool {
258258
}
259259
return compressionVariantsRecognizeMIMEType(oci1CompressionMIMETypeSets, mimeType)
260260
}
261+
262+
// CanDecompressLayer returns true if a layer with mimeType can be decompressed (and the code can handle that)
263+
// FIXME FIXME: Some other API
264+
// FIXME FIXME: Tests
265+
func (m *OCI1) CanDecompressLayer(mimeType string) bool {
266+
if m.Config.MediaType != imgspecv1.MediaTypeImageConfig {
267+
return false
268+
}
269+
_, err := compressionVariantMIMEType(oci1CompressionMIMETypeSets, mimeType, nil)
270+
return err == nil
271+
}
272+
273+
// CanDecompressLayer returns true if a layer with mimeType can be (re)compressed to algorithm (and the code can handle that)
274+
// FIXME FIXME: Some other API
275+
// FIXME FIXME: Tests
276+
func (m *OCI1) CanCompressLayer(mimeType string, algorithm *compressiontypes.Algorithm) bool {
277+
if m.Config.MediaType != imgspecv1.MediaTypeImageConfig {
278+
return false
279+
}
280+
_, err := compressionVariantMIMEType(oci1CompressionMIMETypeSets, mimeType, algorithm)
281+
return err == nil
282+
}

0 commit comments

Comments
 (0)