@@ -966,6 +966,21 @@ func (o *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
966966
967967 opts = append (opts , snapshots .WithLabels (map [string ]string {label .LocalOverlayBDPath : o .overlaybdSealedFilePath (id )}))
968968 }
969+ } else if oinfo .Labels [label .AccelerationLayer ] != "yes" {
970+ // Fallback: detect writable overlaybd layers without SupportReadWriteMode label.
971+ // buildkit OCI worker never sets SupportReadWriteMode, so we detect by checking
972+ // whether a backing store config and writable_data file both exist.
973+ if _ , err := o .loadBackingStoreConfig (id ); err == nil {
974+ if _ , statErr := os .Stat (o .overlaybdWritableDataPath (id )); statErr == nil {
975+ if err := o .unmountAndDetachBlockDevice (ctx , id , key ); err != nil {
976+ return errors .Wrapf (err , "failed to unmount device for snapshot %s" , key )
977+ }
978+ if err := o .sealWritableOverlaybd (ctx , id ); err != nil {
979+ return err
980+ }
981+ opts = append (opts , snapshots .WithLabels (map [string ]string {label .LocalOverlayBDPath : o .overlaybdSealedFilePath (id )}))
982+ }
983+ }
969984 }
970985
971986 if isOverlaybd , err := zdfs .PrepareOverlayBDSpec (ctx , key , id , o .snPath (id ), oinfo , o .snPath ); isOverlaybd {
@@ -988,24 +1003,41 @@ func (o *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
9881003 log .G (ctx ).Debugf ("Commit info (id: %s, info: %v, stype: %d)" , id , info .Labels , stype )
9891004
9901005 // For turboOCI, we need to construct OverlayBD spec after unpacking
991- // since there could be multiple fs metadata in a turboOCI layer
1006+ // since there could be multiple fs metadata in a turboOCI layer.
1007+ // For normal OCI layers (e.g. ubuntu:22.04 extracted by buildkit OCI worker), tar the upper
1008+ // directory to feed the existing turboOCI conversion pipeline.
1009+ ociLayerConverted := false
9921010 if isTurboOCI , digest , _ := o .checkTurboOCI (info .Labels ); isTurboOCI {
9931011 log .G (ctx ).Infof ("commit turboOCI.v1 layer: (%s, %s)" , id , digest )
9941012 if err := o .constructOverlayBDSpec (ctx , name , false ); err != nil {
9951013 return errors .Wrapf (err , "failed to construct overlaybd config" )
9961014 }
9971015 stype = storageTypeNormal
1016+ } else if stype == storageTypeNormal {
1017+ if err := o .createLayerTarFromUpper (ctx , id ); err != nil {
1018+ log .G (ctx ).Debugf ("skipping overlaybd conversion for snapshot %s: %v" , id , err )
1019+ } else {
1020+ stype = storageTypeLocalLayer
1021+ ociLayerConverted = true
1022+ }
9981023 }
9991024
10001025 // Firstly, try to convert an OCIv1 tarball to a turboOCI layer.
10011026 // then change stype to 'storageTypeLocalBlock' which can make it attach a overlaybd block
10021027 if stype == storageTypeLocalLayer {
10031028 // PERFORMANCE WARNING: Converting local layer to turboOCI format
1004- log .G (ctx ).Warnf ("Converting local blob to turboOCI layer (sn: %s). This is a heavyweight operation that processes the entire layer and may take significant time ." , id )
1029+ log .G (ctx ).Warnf ("Converting local blob to turboOCI layer (sn: %s).. ." , id )
10051030 if err := o .constructOverlayBDSpec (ctx , name , false ); err != nil {
1006- return errors .Wrapf (err , "failed to construct overlaybd config" )
1031+ if ociLayerConverted {
1032+ log .G (ctx ).Warnf ("Failed to convert OCI layer to overlaybd for sn %s, falling back: %v" , id , err )
1033+ os .Remove (o .overlaybdOCILayerPath (id ))
1034+ stype = storageTypeNormal
1035+ } else {
1036+ return errors .Wrapf (err , "failed to construct overlaybd config" )
1037+ }
1038+ } else {
1039+ stype = storageTypeLocalBlock
10071040 }
1008- stype = storageTypeLocalBlock
10091041 }
10101042
10111043 if stype == storageTypeLocalBlock {
@@ -1017,7 +1049,11 @@ func (o *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
10171049 info .Labels = make (map [string ]string )
10181050 }
10191051
1020- info .Labels [label .LocalOverlayBDPath ] = o .overlaybdSealedFilePath (id )
1052+ obdPath := o .overlaybdSealedFilePath (id )
1053+ if _ , statErr := os .Stat (obdPath ); os .IsNotExist (statErr ) {
1054+ obdPath = o .magicFilePath (id )
1055+ }
1056+ info .Labels [label .LocalOverlayBDPath ] = obdPath
10211057 delete (info .Labels , label .SupportReadWriteMode )
10221058 info , err = storage .UpdateInfo (ctx , info )
10231059 if err != nil {
@@ -1031,6 +1067,29 @@ func (o *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
10311067 return t .Commit ()
10321068}
10331069
1070+ // createLayerTarFromUpper creates a layer.tar from the snapshot's upper (fs/) directory.
1071+ // This enables the existing storageTypeLocalLayer → overlaybd conversion path for snapshots
1072+ // that were prepared and committed as plain overlayfs (e.g. OCI base image layers pulled by
1073+ // the buildkit OCI worker). Returns an error if the upper dir is empty or the tar fails.
1074+ func (o * snapshotter ) createLayerTarFromUpper (ctx context.Context , id string ) error {
1075+ upper := o .upperPath (id )
1076+ entries , err := os .ReadDir (upper )
1077+ if err != nil {
1078+ return fmt .Errorf ("cannot read upper dir %s: %w" , upper , err )
1079+ }
1080+ if len (entries ) == 0 {
1081+ return fmt .Errorf ("upper dir %s is empty, nothing to convert" , upper )
1082+ }
1083+ tarPath := o .overlaybdOCILayerPath (id )
1084+ log .G (ctx ).Infof ("creating layer.tar from upper directory for overlaybd conversion (sn: %s)" , id )
1085+ cmd := exec .CommandContext (ctx , "tar" , "--xattrs" , "--xattrs-include=*" , "-C" , upper , "-cf" , tarPath , "." )
1086+ if out , err := cmd .CombinedOutput (); err != nil {
1087+ os .Remove (tarPath )
1088+ return errors .Wrapf (err , "failed to create layer.tar (output: %s)" , out )
1089+ }
1090+ return nil
1091+ }
1092+
10341093func (o * snapshotter ) commit (ctx context.Context , name , key string , opts ... snapshots.Opt ) (string , snapshots.Info , error ) {
10351094 ctx , span := tracing .GetDefaultTracer ().Start (ctx , "snapshotter.commit" , trace .WithAttributes (
10361095 attribute .String ("snapshot_name" , name ),
0 commit comments