@@ -194,7 +194,7 @@ func (e *imageExporterInstance) Config() *exporter.Config {
194194 return exporter .NewConfigWithCompression (e .opts .RefCfg .Compression )
195195}
196196
197- func (e * imageExporterInstance ) Export (ctx context.Context , src * exporter.Source , sessionID string ) (map [string ]string , error ) {
197+ func (e * imageExporterInstance ) Export (ctx context.Context , src * exporter.Source , sessionID string ) (_ map [string ]string , descref exporter. DescriptorReference , err error ) {
198198 if src .Metadata == nil {
199199 src .Metadata = make (map [string ][]byte )
200200 }
@@ -205,23 +205,28 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
205205 opts := e .opts
206206 as , _ , err := ParseAnnotations (src .Metadata )
207207 if err != nil {
208- return nil , err
208+ return nil , nil , err
209209 }
210210 opts .Annotations = opts .Annotations .Merge (as )
211211
212212 ctx , done , err := leaseutil .WithLease (ctx , e .opt .LeaseManager , leaseutil .MakeTemporary )
213213 if err != nil {
214- return nil , err
214+ return nil , nil , err
215215 }
216- defer done (context .TODO ())
216+ defer func () {
217+ if descref == nil {
218+ done (context .TODO ())
219+ }
220+ }()
217221
218222 desc , err := e .opt .ImageWriter .Commit (ctx , src , sessionID , & opts )
219223 if err != nil {
220- return nil , err
224+ return nil , nil , err
221225 }
222-
223226 defer func () {
224- e .opt .ImageWriter .ContentStore ().Delete (context .TODO (), desc .Digest )
227+ if err == nil {
228+ descref = NewDescriptorReference (* desc , done )
229+ }
225230 }()
226231
227232 resp := make (map [string ]string )
@@ -253,45 +258,45 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
253258 img .Name = targetName + sfx
254259 if _ , err := e .opt .Images .Update (ctx , img ); err != nil {
255260 if ! errors .Is (err , errdefs .ErrNotFound ) {
256- return nil , tagDone (err )
261+ return nil , nil , tagDone (err )
257262 }
258263
259264 if _ , err := e .opt .Images .Create (ctx , img ); err != nil {
260- return nil , tagDone (err )
265+ return nil , nil , tagDone (err )
261266 }
262267 }
263268 }
264269 tagDone (nil )
265270
266271 if src .Ref != nil && e .unpack {
267272 if err := e .unpackImage (ctx , img , src , session .NewGroup (sessionID )); err != nil {
268- return nil , err
273+ return nil , nil , err
269274 }
270275 }
271276
272277 if ! e .storeAllowIncomplete {
273278 if src .Ref != nil {
274279 remotes , err := src .Ref .GetRemotes (ctx , false , e .opts .RefCfg , false , session .NewGroup (sessionID ))
275280 if err != nil {
276- return nil , err
281+ return nil , nil , err
277282 }
278283 remote := remotes [0 ]
279284 if unlazier , ok := remote .Provider .(cache.Unlazier ); ok {
280285 if err := unlazier .Unlazy (ctx ); err != nil {
281- return nil , err
286+ return nil , nil , err
282287 }
283288 }
284289 }
285290 if len (src .Refs ) > 0 {
286291 for _ , r := range src .Refs {
287292 remotes , err := r .GetRemotes (ctx , false , e .opts .RefCfg , false , session .NewGroup (sessionID ))
288293 if err != nil {
289- return nil , err
294+ return nil , nil , err
290295 }
291296 remote := remotes [0 ]
292297 if unlazier , ok := remote .Provider .(cache.Unlazier ); ok {
293298 if err := unlazier .Unlazy (ctx ); err != nil {
294- return nil , err
299+ return nil , nil , err
295300 }
296301 }
297302 }
@@ -301,7 +306,7 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
301306 if e .push {
302307 err := e .pushImage (ctx , src , sessionID , targetName , desc .Digest )
303308 if err != nil {
304- return nil , errors .Wrapf (err , "failed to push %v" , targetName )
309+ return nil , nil , errors .Wrapf (err , "failed to push %v" , targetName )
305310 }
306311 }
307312 }
@@ -316,11 +321,11 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
316321
317322 dtdesc , err := json .Marshal (desc )
318323 if err != nil {
319- return nil , err
324+ return nil , nil , err
320325 }
321326 resp [exptypes .ExporterImageDescriptorKey ] = base64 .StdEncoding .EncodeToString (dtdesc )
322327
323- return resp , nil
328+ return resp , nil , nil
324329}
325330
326331func (e * imageExporterInstance ) pushImage (ctx context.Context , src * exporter.Source , sessionID string , targetName string , dgst digest.Digest ) error {
@@ -460,3 +465,23 @@ func defaultPlatform() string {
460465 // are normalized using platforms.Normalize()
461466 return platforms .Format (platforms .Normalize (platforms .DefaultSpec ()))
462467}
468+
469+ func NewDescriptorReference (desc ocispecs.Descriptor , release func (context.Context ) error ) exporter.DescriptorReference {
470+ return & descriptorReference {
471+ desc : desc ,
472+ release : release ,
473+ }
474+ }
475+
476+ type descriptorReference struct {
477+ desc ocispecs.Descriptor
478+ release func (context.Context ) error
479+ }
480+
481+ func (d * descriptorReference ) Descriptor () ocispecs.Descriptor {
482+ return d .desc
483+ }
484+
485+ func (d * descriptorReference ) Release () error {
486+ return d .release (context .TODO ())
487+ }
0 commit comments