|
7 | 7 | "io"
|
8 | 8 | "maps"
|
9 | 9 | "os"
|
| 10 | + "strconv" |
10 | 11 | "strings"
|
11 | 12 | "time"
|
12 | 13 |
|
@@ -130,7 +131,8 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
|
130 | 131 | return nil, err
|
131 | 132 | }
|
132 | 133 |
|
133 |
| - storesToUpdate := []string{} |
| 134 | + // maps image exporter id -> store path |
| 135 | + storesToUpdate := make(map[string]ociStore) |
134 | 136 |
|
135 | 137 | if !opt.SessionPreInitialized {
|
136 | 138 | if len(syncedDirs) > 0 {
|
@@ -195,7 +197,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
|
195 | 197 | return nil, err
|
196 | 198 | }
|
197 | 199 | contentStores["export"] = cs
|
198 |
| - storesToUpdate = append(storesToUpdate, ex.OutputDir) |
| 200 | + storesToUpdate[strconv.Itoa(exID)] = ociStore{path: ex.OutputDir} |
199 | 201 | default:
|
200 | 202 | syncTargets = append(syncTargets, filesync.WithFSSyncDir(exID, ex.OutputDir))
|
201 | 203 | }
|
@@ -260,6 +262,8 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
|
260 | 262 | exportDeprecated = exp.Type
|
261 | 263 | exportAttrDeprecated = exp.Attrs
|
262 | 264 | }
|
| 265 | + // FIXME(dima): make this a dedicated attribute on the Exporter |
| 266 | + exp.Attrs[exptypes.ClientKeyID] = strconv.Itoa(i) |
263 | 267 | exports = append(exports, &controlapi.Exporter{
|
264 | 268 | Type: exp.Type,
|
265 | 269 | Attrs: exp.Attrs,
|
@@ -350,29 +354,56 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
|
350 | 354 | }
|
351 | 355 | }
|
352 | 356 | }
|
353 |
| - if manifestDescDt := res.ExporterResponse[exptypes.ExporterImageDescriptorKey]; manifestDescDt != "" { |
354 |
| - manifestDescDt, err := base64.StdEncoding.DecodeString(manifestDescDt) |
| 357 | + |
| 358 | + if len(storesToUpdate) == 0 { |
| 359 | + return res, nil |
| 360 | + } |
| 361 | + for id, store := range storesToUpdate { |
| 362 | + manifestDesc, err := getManifestDescriptor(id, res.ExporterResponse) |
355 | 363 | if err != nil {
|
356 | 364 | return nil, err
|
357 | 365 | }
|
358 |
| - var manifestDesc ocispecs.Descriptor |
359 |
| - if err = json.Unmarshal([]byte(manifestDescDt), &manifestDesc); err != nil { |
360 |
| - return nil, err |
| 366 | + if manifestDesc == nil { |
| 367 | + continue |
361 | 368 | }
|
362 |
| - for _, storePath := range storesToUpdate { |
363 |
| - tag := "latest" |
364 |
| - if t, ok := res.ExporterResponse["image.name"]; ok { |
365 |
| - tag = t |
366 |
| - } |
367 |
| - idx := ociindex.NewStoreIndex(storePath) |
368 |
| - if err := idx.Put(tag, manifestDesc); err != nil { |
369 |
| - return nil, err |
370 |
| - } |
| 369 | + tag := "latest" |
| 370 | + if t, ok := res.ExporterResponse["image.name"]; ok { |
| 371 | + tag = t |
| 372 | + } |
| 373 | + idx := ociindex.NewStoreIndex(store.path) |
| 374 | + if err := idx.Put(tag, *manifestDesc); err != nil { |
| 375 | + return nil, err |
371 | 376 | }
|
372 | 377 | }
|
373 | 378 | return res, nil
|
374 | 379 | }
|
375 | 380 |
|
| 381 | +func getManifestDescriptor(exporterID string, resp map[string]string) (*ocispecs.Descriptor, error) { |
| 382 | + if manifestDescDt := resp[exptypes.FormatImageDescriptorKey(exporterID)]; manifestDescDt != "" { |
| 383 | + return unmarshalManifestDescriptor(manifestDescDt) |
| 384 | + } |
| 385 | + if manifestDescDt := resp[exptypes.ExporterImageDescriptorKey]; manifestDescDt != "" { |
| 386 | + return unmarshalManifestDescriptor(manifestDescDt) |
| 387 | + } |
| 388 | + return nil, nil |
| 389 | +} |
| 390 | + |
| 391 | +func unmarshalManifestDescriptor(manifestDesc string) (*ocispecs.Descriptor, error) { |
| 392 | + manifestDescDt, err := base64.StdEncoding.DecodeString(manifestDesc) |
| 393 | + if err != nil { |
| 394 | + return nil, err |
| 395 | + } |
| 396 | + var desc ocispecs.Descriptor |
| 397 | + if err = json.Unmarshal([]byte(manifestDescDt), &desc); err != nil { |
| 398 | + return nil, err |
| 399 | + } |
| 400 | + return &desc, nil |
| 401 | +} |
| 402 | + |
| 403 | +type ociStore struct { |
| 404 | + path string |
| 405 | +} |
| 406 | + |
376 | 407 | func prepareSyncedFiles(def *llb.Definition, localMounts map[string]fsutil.FS) (filesync.StaticDirSource, error) {
|
377 | 408 | resetUIDAndGID := func(p string, st *fstypes.Stat) fsutil.MapResult {
|
378 | 409 | st.Uid = 0
|
|
0 commit comments