@@ -14,8 +14,9 @@ import (
14
14
15
15
"github.com/containers/image/v5/internal/imagesource/impl"
16
16
"github.com/containers/image/v5/internal/imagesource/stubs"
17
+ "github.com/containers/image/v5/pkg/compression"
18
+ compressionTypes "github.com/containers/image/v5/pkg/compression/types"
17
19
"github.com/containers/image/v5/types"
18
- "github.com/klauspost/pgzip"
19
20
digest "github.com/opencontainers/go-digest"
20
21
imgspecs "github.com/opencontainers/image-spec/specs-go"
21
22
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
@@ -82,31 +83,47 @@ func (r *tarballReference) NewImageSource(ctx context.Context, sys *types.System
82
83
}
83
84
}
84
85
85
- // Default to assuming the layer is compressed.
86
- layerType := imgspecv1 .MediaTypeImageLayerGzip
87
-
88
86
// Set up to digest the file as it is.
89
87
blobIDdigester := digest .Canonical .Digester ()
90
88
reader = io .TeeReader (reader , blobIDdigester .Hash ())
91
89
92
- // Set up to digest the file after we maybe decompress it.
93
- diffIDdigester := digest .Canonical .Digester ()
94
- uncompressed , err := pgzip .NewReader (reader )
95
- if err == nil {
96
- // It is compressed, so the diffID is the digest of the uncompressed version
97
- reader = io .TeeReader (uncompressed , diffIDdigester .Hash ())
98
- } else {
99
- // It is not compressed, so the diffID and the blobID are going to be the same
100
- diffIDdigester = blobIDdigester
101
- layerType = imgspecv1 .MediaTypeImageLayer
102
- uncompressed = nil
103
- }
104
- // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done().
105
- if _ , err := io .Copy (io .Discard , reader ); err != nil {
106
- return nil , fmt .Errorf ("error reading %q: %w" , filename , err )
107
- }
108
- if uncompressed != nil {
109
- uncompressed .Close ()
90
+ var layerType string
91
+ var diffIDdigester digest.Digester
92
+ // If necessary, digest the file after we decompress it.
93
+ if err := func () error { // A scope for defer
94
+ format , decompressor , reader , err := compression .DetectCompressionFormat (reader )
95
+ if err != nil {
96
+ return err
97
+ }
98
+ if decompressor != nil {
99
+ uncompressed , err := decompressor (reader )
100
+ if err != nil {
101
+ return err
102
+ }
103
+ defer uncompressed .Close ()
104
+ // It is compressed, so the diffID is the digest of the uncompressed version
105
+ diffIDdigester = digest .Canonical .Digester ()
106
+ reader = io .TeeReader (uncompressed , diffIDdigester .Hash ())
107
+ switch format .Name () {
108
+ case compressionTypes .GzipAlgorithmName :
109
+ layerType = imgspecv1 .MediaTypeImageLayerGzip
110
+ case compressionTypes .ZstdAlgorithmName :
111
+ layerType = imgspecv1 .MediaTypeImageLayerZstd
112
+ default : // This is incorrect, but we have no good options, and it is what this transport was historically doing.
113
+ layerType = imgspecv1 .MediaTypeImageLayerGzip
114
+ }
115
+ } else {
116
+ // It is not compressed, so the diffID and the blobID are going to be the same
117
+ diffIDdigester = blobIDdigester
118
+ layerType = imgspecv1 .MediaTypeImageLayer
119
+ }
120
+ // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done().
121
+ if _ , err := io .Copy (io .Discard , reader ); err != nil {
122
+ return fmt .Errorf ("error reading %q: %w" , filename , err )
123
+ }
124
+ return nil
125
+ }(); err != nil {
126
+ return nil , err
110
127
}
111
128
112
129
// Grab our uncompressed and possibly-compressed digests and sizes.
0 commit comments