@@ -63,6 +63,7 @@ type Opts struct {
63
63
Pause bool
64
64
Changes Changes
65
65
Compression types.CompressionType
66
+ Format types.ImageFormat
66
67
}
67
68
68
69
var (
@@ -177,7 +178,7 @@ func Commit(ctx context.Context, client *containerd.Client, container containerd
177
178
// Sync filesystem to make sure that all the data writes in container could be persisted to disk.
178
179
Sync ()
179
180
180
- diffLayerDesc , diffID , err := createDiff (ctx , id , sn , client .ContentStore (), differ , opts .Compression )
181
+ diffLayerDesc , diffID , err := createDiff (ctx , id , sn , client .ContentStore (), differ , opts .Compression , opts )
181
182
if err != nil {
182
183
return emptyDigest , fmt .Errorf ("failed to export layer: %w" , err )
183
184
}
@@ -192,7 +193,7 @@ func Commit(ctx context.Context, client *containerd.Client, container containerd
192
193
return emptyDigest , fmt .Errorf ("failed to apply diff: %w" , err )
193
194
}
194
195
195
- commitManifestDesc , configDigest , err := writeContentsForImage (ctx , snName , baseImg , imageConfig , diffLayerDesc )
196
+ commitManifestDesc , configDigest , err := writeContentsForImage (ctx , snName , baseImg , imageConfig , diffLayerDesc , opts )
196
197
if err != nil {
197
198
return emptyDigest , err
198
199
}
@@ -287,14 +288,29 @@ func generateCommitImageConfig(ctx context.Context, container containerd.Contain
287
288
}
288
289
289
290
// writeContentsForImage will commit oci image config and manifest into containerd's content store.
290
- func writeContentsForImage (ctx context.Context , snName string , baseImg containerd.Image , newConfig ocispec.Image , diffLayerDesc ocispec.Descriptor ) (ocispec.Descriptor , digest.Digest , error ) {
291
+ func writeContentsForImage (ctx context.Context , snName string , baseImg containerd.Image , newConfig ocispec.Image , diffLayerDesc ocispec.Descriptor , opts * Opts ) (ocispec.Descriptor , digest.Digest , error ) {
291
292
newConfigJSON , err := json .Marshal (newConfig )
292
293
if err != nil {
293
294
return ocispec.Descriptor {}, emptyDigest , err
294
295
}
295
296
297
+ // Select media types based on format choice
298
+ var configMediaType , manifestMediaType string
299
+ switch opts .Format {
300
+ case types .ImageFormatOCI :
301
+ configMediaType = ocispec .MediaTypeImageConfig
302
+ manifestMediaType = ocispec .MediaTypeImageManifest
303
+ case types .ImageFormatDocker :
304
+ configMediaType = images .MediaTypeDockerSchema2Config
305
+ manifestMediaType = images .MediaTypeDockerSchema2Manifest
306
+ default :
307
+ // Default to Docker Schema2 for compatibility
308
+ configMediaType = images .MediaTypeDockerSchema2Config
309
+ manifestMediaType = images .MediaTypeDockerSchema2Manifest
310
+ }
311
+
296
312
configDesc := ocispec.Descriptor {
297
- MediaType : images . MediaTypeDockerSchema2Config ,
313
+ MediaType : configMediaType ,
298
314
Digest : digest .FromBytes (newConfigJSON ),
299
315
Size : int64 (len (newConfigJSON )),
300
316
}
@@ -310,7 +326,7 @@ func writeContentsForImage(ctx context.Context, snName string, baseImg container
310
326
MediaType string `json:"mediaType,omitempty"`
311
327
ocispec.Manifest
312
328
}{
313
- MediaType : images . MediaTypeDockerSchema2Manifest ,
329
+ MediaType : manifestMediaType ,
314
330
Manifest : ocispec.Manifest {
315
331
Versioned : specs.Versioned {
316
332
SchemaVersion : 2 ,
@@ -326,7 +342,7 @@ func writeContentsForImage(ctx context.Context, snName string, baseImg container
326
342
}
327
343
328
344
newMfstDesc := ocispec.Descriptor {
329
- MediaType : images . MediaTypeDockerSchema2Manifest ,
345
+ MediaType : manifestMediaType ,
330
346
Digest : digest .FromBytes (newMfstJSON ),
331
347
Size : int64 (len (newMfstJSON )),
332
348
}
@@ -357,14 +373,45 @@ func writeContentsForImage(ctx context.Context, snName string, baseImg container
357
373
}
358
374
359
375
// createDiff creates a layer diff into containerd's content store.
360
- func createDiff (ctx context.Context , name string , sn snapshots.Snapshotter , cs content.Store , comparer diff.Comparer , compression types.CompressionType ) (ocispec.Descriptor , digest.Digest , error ) {
361
- opts := make ([]diff.Opt , 0 )
362
- mediaType := images .MediaTypeDockerSchema2LayerGzip
363
- if compression == types .Zstd {
364
- opts = append (opts , diff .WithMediaType (ocispec .MediaTypeImageLayerZstd ))
365
- mediaType = images .MediaTypeDockerSchema2LayerZstd
366
- }
367
- newDesc , err := rootfs .CreateDiff (ctx , name , sn , comparer , opts ... )
376
+ func createDiff (ctx context.Context , name string , sn snapshots.Snapshotter , cs content.Store , comparer diff.Comparer , compression types.CompressionType , opts * Opts ) (ocispec.Descriptor , digest.Digest , error ) {
377
+ diffOpts := make ([]diff.Opt , 0 )
378
+ var mediaType string
379
+
380
+ // Select media type based on format and compression
381
+ switch opts .Format {
382
+ case types .ImageFormatOCI :
383
+ // Use OCI media types
384
+ switch compression {
385
+ case types .Zstd :
386
+ diffOpts = append (diffOpts , diff .WithMediaType (ocispec .MediaTypeImageLayerZstd ))
387
+ mediaType = ocispec .MediaTypeImageLayerZstd
388
+ default :
389
+ diffOpts = append (diffOpts , diff .WithMediaType (ocispec .MediaTypeImageLayerGzip ))
390
+ mediaType = ocispec .MediaTypeImageLayerGzip
391
+ }
392
+ case types .ImageFormatDocker :
393
+ // Use Docker Schema2 media types for compatibility
394
+ switch compression {
395
+ case types .Zstd :
396
+ diffOpts = append (diffOpts , diff .WithMediaType (ocispec .MediaTypeImageLayerZstd ))
397
+ mediaType = images .MediaTypeDockerSchema2LayerZstd
398
+ default :
399
+ diffOpts = append (diffOpts , diff .WithMediaType (ocispec .MediaTypeImageLayerGzip ))
400
+ mediaType = images .MediaTypeDockerSchema2LayerGzip
401
+ }
402
+ default :
403
+ // Default to Docker Schema2 media types for compatibility
404
+ switch compression {
405
+ case types .Zstd :
406
+ diffOpts = append (diffOpts , diff .WithMediaType (ocispec .MediaTypeImageLayerZstd ))
407
+ mediaType = images .MediaTypeDockerSchema2LayerZstd
408
+ default :
409
+ diffOpts = append (diffOpts , diff .WithMediaType (ocispec .MediaTypeImageLayerGzip ))
410
+ mediaType = images .MediaTypeDockerSchema2LayerGzip
411
+ }
412
+ }
413
+
414
+ newDesc , err := rootfs .CreateDiff (ctx , name , sn , comparer , diffOpts ... )
368
415
if err != nil {
369
416
return ocispec.Descriptor {}, digest .Digest ("" ), err
370
417
}
0 commit comments