@@ -16,6 +16,7 @@ import (
16
16
"github.com/moby/buildkit/util/compression"
17
17
"github.com/moby/buildkit/util/converter"
18
18
"github.com/moby/buildkit/util/flightcontrol"
19
+ "github.com/moby/buildkit/util/leaseutil"
19
20
"github.com/moby/buildkit/util/winlayers"
20
21
digest "github.com/opencontainers/go-digest"
21
22
imagespecidentity "github.com/opencontainers/image-spec/identity"
@@ -24,7 +25,7 @@ import (
24
25
"golang.org/x/sync/errgroup"
25
26
)
26
27
27
- var g flightcontrol.Group [struct {} ]
28
+ var g flightcontrol.Group [* leaseutil. LeaseRef ]
28
29
var gFileList flightcontrol.Group [[]string ]
29
30
30
31
var ErrNoBlobs = errors .Errorf ("no blobs for snapshot" )
@@ -87,14 +88,24 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool
87
88
88
89
if _ , ok := filter [sr .ID ()]; ok {
89
90
eg .Go (func () error {
90
- _ , err := g .Do (ctx , fmt .Sprintf ("%s-%t" , sr .ID (), createIfNeeded ), func (ctx context.Context ) (struct {}, error ) {
91
+ l , err := g .Do (ctx , fmt .Sprintf ("%s-%t" , sr .ID (), createIfNeeded ), func (ctx context.Context ) (_ * leaseutil. LeaseRef , err error ) {
91
92
if sr .getBlob () != "" {
92
- return struct {}{} , nil
93
+ return nil , nil
93
94
}
94
95
if ! createIfNeeded {
95
- return struct {}{} , errors .WithStack (ErrNoBlobs )
96
+ return nil , errors .WithStack (ErrNoBlobs )
96
97
}
97
98
99
+ l , ctx , err := leaseutil .NewLease (ctx , sr .cm .LeaseManager , leaseutil .MakeTemporary )
100
+ if err != nil {
101
+ return nil , err
102
+ }
103
+ defer func () {
104
+ if err != nil {
105
+ l .Discard ()
106
+ }
107
+ }()
108
+
98
109
compressorFunc , finalize := comp .Type .Compress (ctx , comp )
99
110
mediaType := comp .Type .MediaType ()
100
111
@@ -109,12 +120,12 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool
109
120
if lowerRef != nil {
110
121
m , err := lowerRef .Mount (ctx , true , s )
111
122
if err != nil {
112
- return struct {}{} , err
123
+ return nil , err
113
124
}
114
125
var release func () error
115
126
lower , release , err = m .Mount ()
116
127
if err != nil {
117
- return struct {}{} , err
128
+ return nil , err
118
129
}
119
130
if release != nil {
120
131
defer release ()
@@ -132,27 +143,26 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool
132
143
if upperRef != nil {
133
144
m , err := upperRef .Mount (ctx , true , s )
134
145
if err != nil {
135
- return struct {}{} , err
146
+ return nil , err
136
147
}
137
148
var release func () error
138
149
upper , release , err = m .Mount ()
139
150
if err != nil {
140
- return struct {}{} , err
151
+ return nil , err
141
152
}
142
153
if release != nil {
143
154
defer release ()
144
155
}
145
156
}
146
157
147
158
var desc ocispecs.Descriptor
148
- var err error
149
159
150
160
// Determine differ and error/log handling according to the platform, envvar and the snapshotter.
151
161
var enableOverlay , fallback , logWarnOnErr bool
152
162
if forceOvlStr := os .Getenv ("BUILDKIT_DEBUG_FORCE_OVERLAY_DIFF" ); forceOvlStr != "" && sr .kind () != Diff {
153
163
enableOverlay , err = strconv .ParseBool (forceOvlStr )
154
164
if err != nil {
155
- return struct {}{} , errors .Wrapf (err , "invalid boolean in BUILDKIT_DEBUG_FORCE_OVERLAY_DIFF" )
165
+ return nil , errors .Wrapf (err , "invalid boolean in BUILDKIT_DEBUG_FORCE_OVERLAY_DIFF" )
156
166
}
157
167
fallback = false // prohibit fallback on debug
158
168
} else if ! isTypeWindows (sr ) {
@@ -174,10 +184,10 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool
174
184
if ! ok || err != nil {
175
185
if ! fallback {
176
186
if ! ok {
177
- return struct {}{} , errors .Errorf ("overlay mounts not detected (lower=%+v,upper=%+v)" , lower , upper )
187
+ return nil , errors .Errorf ("overlay mounts not detected (lower=%+v,upper=%+v)" , lower , upper )
178
188
}
179
189
if err != nil {
180
- return struct {}{} , errors .Wrapf (err , "failed to compute overlay diff" )
190
+ return nil , errors .Wrapf (err , "failed to compute overlay diff" )
181
191
}
182
192
}
183
193
if logWarnOnErr {
@@ -210,7 +220,7 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool
210
220
diff .WithCompressor (compressorFunc ),
211
221
)
212
222
if err != nil {
213
- return struct {}{} , err
223
+ return nil , err
214
224
}
215
225
}
216
226
@@ -220,34 +230,40 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool
220
230
if finalize != nil {
221
231
a , err := finalize (ctx , sr .cm .ContentStore )
222
232
if err != nil {
223
- return struct {}{} , errors .Wrapf (err , "failed to finalize compression" )
233
+ return nil , errors .Wrapf (err , "failed to finalize compression" )
224
234
}
225
235
for k , v := range a {
226
236
desc .Annotations [k ] = v
227
237
}
228
238
}
229
239
info , err := sr .cm .ContentStore .Info (ctx , desc .Digest )
230
240
if err != nil {
231
- return struct {}{} , err
241
+ return nil , err
232
242
}
233
243
234
244
if diffID , ok := info .Labels [labels .LabelUncompressed ]; ok {
235
245
desc .Annotations [labels .LabelUncompressed ] = diffID
236
246
} else if mediaType == ocispecs .MediaTypeImageLayer {
237
247
desc .Annotations [labels .LabelUncompressed ] = desc .Digest .String ()
238
248
} else {
239
- return struct {}{} , errors .Errorf ("unknown layer compression type" )
249
+ return nil , errors .Errorf ("unknown layer compression type" )
240
250
}
241
251
242
252
if err := sr .setBlob (ctx , desc ); err != nil {
243
- return struct {}{} , err
253
+ return nil , err
244
254
}
245
- return struct {}{} , nil
255
+ return l , nil
246
256
})
247
257
if err != nil {
248
258
return err
249
259
}
250
260
261
+ if l != nil {
262
+ if err := l .Adopt (ctx ); err != nil {
263
+ return err
264
+ }
265
+ }
266
+
251
267
if comp .Force {
252
268
if err := ensureCompression (ctx , sr , comp , s ); err != nil {
253
269
return errors .Wrapf (err , "failed to ensure compression type of %q" , comp .Type )
@@ -416,29 +432,42 @@ func isTypeWindows(sr *immutableRef) bool {
416
432
417
433
// ensureCompression ensures the specified ref has the blob of the specified compression Type.
418
434
func ensureCompression (ctx context.Context , ref * immutableRef , comp compression.Config , s session.Group ) error {
419
- _ , err := g .Do (ctx , fmt .Sprintf ("ensureComp-%s-%s" , ref .ID (), comp .Type ), func (ctx context.Context ) (struct {}, error ) {
435
+ l , err := g .Do (ctx , fmt .Sprintf ("ensureComp-%s-%s" , ref .ID (), comp .Type ), func (ctx context.Context ) (_ * leaseutil. LeaseRef , err error ) {
420
436
desc , err := ref .ociDesc (ctx , ref .descHandlers , true )
421
437
if err != nil {
422
- return struct {}{}, err
438
+ return nil , err
439
+ }
440
+
441
+ l , ctx , err := leaseutil .NewLease (ctx , ref .cm .LeaseManager , leaseutil .MakeTemporary )
442
+ if err != nil {
443
+ return nil , err
423
444
}
445
+ defer func () {
446
+ if err != nil {
447
+ l .Discard ()
448
+ }
449
+ }()
424
450
425
451
// Resolve converters
426
452
layerConvertFunc , err := converter .New (ctx , ref .cm .ContentStore , desc , comp )
427
453
if err != nil {
428
- return struct {}{} , err
454
+ return nil , err
429
455
} else if layerConvertFunc == nil {
430
456
if isLazy , err := ref .isLazy (ctx ); err != nil {
431
- return struct {}{} , err
457
+ return nil , err
432
458
} else if isLazy {
433
459
// This ref can be used as the specified compressionType. Keep it lazy.
434
- return struct {}{} , nil
460
+ return l , nil
435
461
}
436
- return struct {}{}, ref .linkBlob (ctx , desc )
462
+ if err := ref .linkBlob (ctx , desc ); err != nil {
463
+ return nil , err
464
+ }
465
+ return l , nil
437
466
}
438
467
439
468
// First, lookup local content store
440
469
if _ , err := ref .getBlobWithCompression (ctx , comp .Type ); err == nil {
441
- return struct {}{} , nil // found the compression variant. no need to convert.
470
+ return l , nil // found the compression variant. no need to convert.
442
471
}
443
472
444
473
// Convert layer compression type
@@ -448,18 +477,26 @@ func ensureCompression(ctx context.Context, ref *immutableRef, comp compression.
448
477
dh : ref .descHandlers [desc .Digest ],
449
478
session : s ,
450
479
}).Unlazy (ctx ); err != nil {
451
- return struct {}{} , err
480
+ return l , err
452
481
}
453
482
newDesc , err := layerConvertFunc (ctx , ref .cm .ContentStore , desc )
454
483
if err != nil {
455
- return struct {}{} , errors .Wrapf (err , "failed to convert" )
484
+ return nil , errors .Wrapf (err , "failed to convert" )
456
485
}
457
486
458
487
// Start to track converted layer
459
488
if err := ref .linkBlob (ctx , * newDesc ); err != nil {
460
- return struct {}{} , errors .Wrapf (err , "failed to add compression blob" )
489
+ return nil , errors .Wrapf (err , "failed to add compression blob" )
461
490
}
462
- return struct {}{} , nil
491
+ return l , nil
463
492
})
464
- return err
493
+ if err != nil {
494
+ return err
495
+ }
496
+ if l != nil {
497
+ if err := l .Adopt (ctx ); err != nil {
498
+ return err
499
+ }
500
+ }
501
+ return nil
465
502
}
0 commit comments