@@ -261,7 +261,7 @@ func (s *saveSession) save(ctx context.Context, outStream io.Writer) error {
261261 dgst := digest .FromBytes (data )
262262
263263 mFile := filepath .Join (s .outDir , ocispec .ImageBlobsDir , dgst .Algorithm ().String (), dgst .Encoded ())
264- if err := os . MkdirAll (filepath .Dir (mFile ), 0o755 ); err != nil {
264+ if err := mkdirAllWithChtimes (filepath .Dir (mFile ), 0o755 , time . Unix ( 0 , 0 ), time . Unix ( 0 , 0 ) ); err != nil {
265265 return errors .Wrap (err , "error creating blob directory" )
266266 }
267267 if err := system .Chtimes (filepath .Dir (mFile ), time .Unix (0 , 0 ), time .Unix (0 , 0 )); err != nil {
@@ -385,6 +385,9 @@ func (s *saveSession) save(ctx context.Context, outStream io.Writer) error {
385385 if err := os .WriteFile (idxFile , data , 0o644 ); err != nil {
386386 return errors .Wrap (err , "error writing oci index file" )
387387 }
388+ if err := system .Chtimes (idxFile , time .Unix (0 , 0 ), time .Unix (0 , 0 )); err != nil {
389+ return errors .Wrap (err , "error setting oci index file timestamps" )
390+ }
388391
389392 return s .writeTar (ctx , tempDir , outStream )
390393}
@@ -419,6 +422,11 @@ func (s *saveSession) saveImage(ctx context.Context, id image.ID) (_ map[layer.D
419422 return nil , fmt .Errorf ("empty export - not implemented" )
420423 }
421424
425+ ts := time .Unix (0 , 0 )
426+ if img .Created != nil {
427+ ts = * img .Created
428+ }
429+
422430 var parent digest.Digest
423431 var layers []layer.DiffID
424432 var foreignSrcs map [layer.DiffID ]distribution.Descriptor
@@ -450,7 +458,7 @@ func (s *saveSession) saveImage(ctx context.Context, id image.ID) (_ map[layer.D
450458 }
451459
452460 v1Img .OS = img .OS
453- src , err := s .saveConfigAndLayer (ctx , rootFS .ChainID (), v1Img , img . Created )
461+ src , err := s .saveConfigAndLayer (ctx , rootFS .ChainID (), v1Img , & ts )
454462 if err != nil {
455463 return nil , err
456464 }
@@ -469,26 +477,22 @@ func (s *saveSession) saveImage(ctx context.Context, id image.ID) (_ map[layer.D
469477 dgst := digest .FromBytes (data )
470478
471479 blobDir := filepath .Join (s .outDir , ocispec .ImageBlobsDir , dgst .Algorithm ().String ())
472- if err := os . MkdirAll (blobDir , 0o755 ); err != nil {
480+ if err := mkdirAllWithChtimes (blobDir , 0o755 , ts , ts ); err != nil {
473481 return nil , err
474482 }
475- if img .Created != nil {
476- if err := system .Chtimes (blobDir , * img .Created , * img .Created ); err != nil {
477- return nil , err
478- }
479- if err := system .Chtimes (filepath .Dir (blobDir ), * img .Created , * img .Created ); err != nil {
480- return nil , err
481- }
483+ if err := system .Chtimes (blobDir , ts , ts ); err != nil {
484+ return nil , err
485+ }
486+ if err := system .Chtimes (filepath .Dir (blobDir ), ts , ts ); err != nil {
487+ return nil , err
482488 }
483489
484490 configFile := filepath .Join (blobDir , dgst .Encoded ())
485491 if err := os .WriteFile (configFile , img .RawJSON (), 0o644 ); err != nil {
486492 return nil , err
487493 }
488- if img .Created != nil {
489- if err := system .Chtimes (configFile , * img .Created , * img .Created ); err != nil {
490- return nil , err
491- }
494+ if err := system .Chtimes (configFile , ts , ts ); err != nil {
495+ return nil , err
492496 }
493497
494498 s .images [id ].layers = layers
@@ -506,6 +510,11 @@ func (s *saveSession) saveConfigAndLayer(ctx context.Context, id layer.ChainID,
506510 span .SetStatus (outErr )
507511 }()
508512
513+ ts := time .Unix (0 , 0 )
514+ if createdTime != nil {
515+ ts = * createdTime
516+ }
517+
509518 outDir := filepath .Join (s .outDir , ocispec .ImageBlobsDir )
510519
511520 if _ , ok := s .savedConfigs [legacyImg .ID ]; ! ok {
@@ -542,7 +551,7 @@ func (s *saveSession) saveConfigAndLayer(ctx context.Context, id layer.ChainID,
542551
543552 // We use sequential file access to avoid depleting the standby list on
544553 // Windows. On Linux, this equates to a regular os.Create.
545- if err := os . MkdirAll (filepath .Dir (layerPath ), 0o755 ); err != nil {
554+ if err := mkdirAllWithChtimes (filepath .Dir (layerPath ), 0o755 , ts , ts ); err != nil {
546555 return distribution.Descriptor {}, errors .Wrap (err , "could not create layer dir parent" )
547556 }
548557 tarFile , err := sequential .Create (layerPath )
@@ -576,12 +585,10 @@ func (s *saveSession) saveConfigAndLayer(ctx context.Context, id layer.ChainID,
576585 layerPath = filepath .Join (outDir , lDgst .Algorithm ().String (), lDgst .Encoded ())
577586 }
578587
579- if createdTime != nil {
580- for _ , fname := range []string {outDir , layerPath } {
581- // todo: maybe save layer created timestamp?
582- if err := system .Chtimes (fname , * createdTime , * createdTime ); err != nil {
583- return distribution.Descriptor {}, errors .Wrap (err , "could not set layer timestamp" )
584- }
588+ for _ , fname := range []string {outDir , layerPath } {
589+ // todo: maybe save layer created timestamp?
590+ if err := system .Chtimes (fname , ts , ts ); err != nil {
591+ return distribution.Descriptor {}, errors .Wrap (err , "could not set layer timestamp" )
585592 }
586593 }
587594
@@ -608,20 +615,23 @@ func (s *saveSession) saveConfig(legacyImg image.V1Image, outDir string, created
608615 return err
609616 }
610617
618+ ts := time .Unix (0 , 0 )
619+ if createdTime != nil {
620+ ts = * createdTime
621+ }
622+
611623 cfgDgst := digest .FromBytes (imageConfig )
612624 configPath := filepath .Join (outDir , cfgDgst .Algorithm ().String (), cfgDgst .Encoded ())
613- if err := os . MkdirAll (filepath .Dir (configPath ), 0o755 ); err != nil {
625+ if err := mkdirAllWithChtimes (filepath .Dir (configPath ), 0o755 , ts , ts ); err != nil {
614626 return errors .Wrap (err , "could not create layer dir parent" )
615627 }
616628
617629 if err := os .WriteFile (configPath , imageConfig , 0o644 ); err != nil {
618630 return err
619631 }
620632
621- if createdTime != nil {
622- if err := system .Chtimes (configPath , * createdTime , * createdTime ); err != nil {
623- return errors .Wrap (err , "could not set config timestamp" )
624- }
633+ if err := system .Chtimes (configPath , ts , ts ); err != nil {
634+ return errors .Wrap (err , "could not set config timestamp" )
625635 }
626636
627637 s .savedConfigs [legacyImg .ID ] = struct {}{}
0 commit comments