@@ -38,15 +38,30 @@ import (
3838 "github.com/pkg/errors"
3939)
4040
41+ type importOpts struct {
42+ compress bool
43+ }
44+
45+ // ImportOpt is an option for importing an OCI index
46+ type ImportOpt func (* importOpts ) error
47+
48+ // WithImportCompression compresses uncompressed layers on import.
49+ // This is used for import formats which do not include the manifest.
50+ func WithImportCompression () ImportOpt {
51+ return func (io * importOpts ) error {
52+ io .compress = true
53+ return nil
54+ }
55+ }
56+
4157// ImportIndex imports an index from a tar archive image bundle
4258// - implements Docker v1.1, v1.2 and OCI v1.
4359// - prefers OCI v1 when provided
4460// - creates OCI index for Docker formats
4561// - normalizes Docker references and adds as OCI ref name
4662// e.g. alpine:latest -> docker.io/library/alpine:latest
4763// - existing OCI reference names are untouched
48- // - TODO: support option to compress layers on ingest
49- func ImportIndex (ctx context.Context , store content.Store , reader io.Reader ) (ocispec.Descriptor , error ) {
64+ func ImportIndex (ctx context.Context , store content.Store , reader io.Reader , opts ... ImportOpt ) (ocispec.Descriptor , error ) {
5065 var (
5166 tr = tar .NewReader (reader )
5267
@@ -58,7 +73,15 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader) (oc
5873 }
5974 symlinks = make (map [string ]string )
6075 blobs = make (map [string ]ocispec.Descriptor )
76+ iopts importOpts
6177 )
78+
79+ for _ , o := range opts {
80+ if err := o (& iopts ); err != nil {
81+ return ocispec.Descriptor {}, err
82+ }
83+ }
84+
6285 for {
6386 hdr , err := tr .Next ()
6487 if err == io .EOF {
@@ -141,7 +164,7 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader) (oc
141164 }
142165 config .MediaType = images .MediaTypeDockerSchema2Config
143166
144- layers , err := resolveLayers (ctx , store , mfst .Layers , blobs )
167+ layers , err := resolveLayers (ctx , store , mfst .Layers , blobs , iopts . compress )
145168 if err != nil {
146169 return ocispec.Descriptor {}, errors .Wrap (err , "failed to resolve layers" )
147170 }
@@ -217,7 +240,7 @@ func onUntarBlob(ctx context.Context, r io.Reader, store content.Ingester, size
217240 return dgstr .Digest (), nil
218241}
219242
220- func resolveLayers (ctx context.Context , store content.Store , layerFiles []string , blobs map [string ]ocispec.Descriptor ) ([]ocispec.Descriptor , error ) {
243+ func resolveLayers (ctx context.Context , store content.Store , layerFiles []string , blobs map [string ]ocispec.Descriptor , compress bool ) ([]ocispec.Descriptor , error ) {
221244 layers := make ([]ocispec.Descriptor , len (layerFiles ))
222245 descs := map [digest.Digest ]* ocispec.Descriptor {}
223246 filters := []string {}
@@ -261,17 +284,23 @@ func resolveLayers(ctx context.Context, store content.Store, layerFiles []string
261284 return nil , errors .Wrapf (err , "failed to detect compression for %q" , layerFiles [i ])
262285 }
263286 if s .GetCompression () == compression .Uncompressed {
264- ref := fmt .Sprintf ("compress-blob-%s-%s" , desc .Digest .Algorithm ().String (), desc .Digest .Encoded ())
265- labels := map [string ]string {
266- "containerd.io/uncompressed" : desc .Digest .String (),
267- }
268- layers [i ], err = compressBlob (ctx , store , s , ref , content .WithLabels (labels ))
269- if err != nil {
270- s .Close ()
271- return nil , err
287+ if compress {
288+ ref := fmt .Sprintf ("compress-blob-%s-%s" , desc .Digest .Algorithm ().String (), desc .Digest .Encoded ())
289+ labels := map [string ]string {
290+ "containerd.io/uncompressed" : desc .Digest .String (),
291+ }
292+ layers [i ], err = compressBlob (ctx , store , s , ref , content .WithLabels (labels ))
293+ if err != nil {
294+ s .Close ()
295+ return nil , err
296+ }
297+ layers [i ].MediaType = images .MediaTypeDockerSchema2LayerGzip
298+ } else {
299+ layers [i ].MediaType = images .MediaTypeDockerSchema2Layer
272300 }
301+ } else {
302+ layers [i ].MediaType = images .MediaTypeDockerSchema2LayerGzip
273303 }
274- layers [i ].MediaType = images .MediaTypeDockerSchema2LayerGzip
275304 s .Close ()
276305
277306 }
0 commit comments