build: use copy for BuildWithResultHandler loop vars

Signed-off-by: Justin Chadwell <me@jedevc.com>
pull/1504/head
Justin Chadwell 2 years ago
parent fb27e3f919
commit 347417ee12

@ -1072,7 +1072,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
}) })
for i, dp := range dps { for i, dp := range dps {
so := *dp.so i, dp, so := i, dp, *dp.so
if multiDriver { if multiDriver {
for i, e := range so.Exports { for i, e := range so.Exports {
switch e.Type { switch e.Type {
@ -1101,144 +1101,141 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
} }
} }
func(i int, dp driverPair, so client.SolveOpt) { pw := progress.WithPrefix(w, k, multiTarget)
pw := progress.WithPrefix(w, k, multiTarget)
c := clients[dp.driverIndex] c := clients[dp.driverIndex]
eg.Go(func() error { eg.Go(func() error {
pw = progress.ResetTime(pw) pw = progress.ResetTime(pw)
defer wg.Done() defer wg.Done()
if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil { if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil {
return err
}
frontendInputs := make(map[string]*pb.Definition)
for key, st := range so.FrontendInputs {
def, err := st.Marshal(ctx)
if err != nil {
return err return err
} }
frontendInputs[key] = def.ToPB()
}
frontendInputs := make(map[string]*pb.Definition) req := gateway.SolveRequest{
for key, st := range so.FrontendInputs { Frontend: so.Frontend,
def, err := st.Marshal(ctx) FrontendInputs: frontendInputs,
if err != nil { FrontendOpt: make(map[string]string),
return err }
for k, v := range so.FrontendAttrs {
req.FrontendOpt[k] = v
}
so.Frontend = ""
so.FrontendInputs = nil
ch, done := progress.NewChannel(pw)
defer func() { <-done }()
cc := c
var printRes map[string][]byte
rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
var isFallback bool
var origErr error
for {
if opt.PrintFunc != nil {
if _, ok := req.FrontendOpt["frontend.caps"]; !ok {
req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward"
} else {
req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward"
}
req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name
if isFallback {
req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage
}
} }
frontendInputs[key] = def.ToPB() res, err := c.Solve(ctx, req)
} if err != nil {
if origErr != nil {
req := gateway.SolveRequest{ return nil, err
Frontend: so.Frontend,
FrontendInputs: frontendInputs,
FrontendOpt: make(map[string]string),
}
for k, v := range so.FrontendAttrs {
req.FrontendOpt[k] = v
}
so.Frontend = ""
so.FrontendInputs = nil
ch, done := progress.NewChannel(pw)
defer func() { <-done }()
cc := c
var printRes map[string][]byte
rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
var isFallback bool
var origErr error
for {
if opt.PrintFunc != nil {
if _, ok := req.FrontendOpt["frontend.caps"]; !ok {
req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward"
} else {
req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward"
}
req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name
if isFallback {
req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage
}
} }
res, err := c.Solve(ctx, req) var reqErr *errdefs.UnsupportedSubrequestError
if err != nil { if !isFallback {
if origErr != nil { if errors.As(err, &reqErr) {
return nil, err switch reqErr.Name {
} case "frontend.outline", "frontend.targets":
var reqErr *errdefs.UnsupportedSubrequestError
if !isFallback {
if errors.As(err, &reqErr) {
switch reqErr.Name {
case "frontend.outline", "frontend.targets":
isFallback = true
origErr = err
continue
}
return nil, err
}
// buildkit v0.8 vendored in Docker 20.10 does not support typed errors
if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") {
isFallback = true isFallback = true
origErr = err origErr = err
continue continue
} }
return nil, err
}
// buildkit v0.8 vendored in Docker 20.10 does not support typed errors
if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") {
isFallback = true
origErr = err
continue
} }
return nil, err
}
if opt.PrintFunc != nil {
printRes = res.Metadata
}
results.Set(resultKey(dp.driverIndex, k), res)
if resultHandleFunc != nil {
resultHandleFunc(dp.driverIndex, &ResultContext{cc, res})
} }
return res, nil return nil, err
} }
}, ch) if opt.PrintFunc != nil {
if err != nil { printRes = res.Metadata
return err }
results.Set(resultKey(dp.driverIndex, k), res)
if resultHandleFunc != nil {
resultHandleFunc(dp.driverIndex, &ResultContext{cc, res})
}
return res, nil
} }
res[i] = rr }, ch)
if err != nil {
return err
}
res[i] = rr
if rr.ExporterResponse == nil { if rr.ExporterResponse == nil {
rr.ExporterResponse = map[string]string{} rr.ExporterResponse = map[string]string{}
} }
for k, v := range printRes { for k, v := range printRes {
rr.ExporterResponse[k] = string(v) rr.ExporterResponse[k] = string(v)
} }
node := nodes[dp.driverIndex].Driver node := nodes[dp.driverIndex].Driver
if node.IsMobyDriver() { if node.IsMobyDriver() {
for _, e := range so.Exports { for _, e := range so.Exports {
if e.Type == "moby" && e.Attrs["push"] != "" { if e.Type == "moby" && e.Attrs["push"] != "" {
if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok { if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok {
pushNames = e.Attrs["name"] pushNames = e.Attrs["name"]
if pushNames == "" { if pushNames == "" {
return errors.Errorf("tag is needed when pushing to registry") return errors.Errorf("tag is needed when pushing to registry")
} }
pw := progress.ResetTime(pw) pw := progress.ResetTime(pw)
pushList := strings.Split(pushNames, ",") pushList := strings.Split(pushNames, ",")
for _, name := range pushList { for _, name := range pushList {
if err := progress.Wrap(fmt.Sprintf("pushing %s with docker", name), pw.Write, func(l progress.SubLogger) error { if err := progress.Wrap(fmt.Sprintf("pushing %s with docker", name), pw.Write, func(l progress.SubLogger) error {
return pushWithMoby(ctx, node, name, l) return pushWithMoby(ctx, node, name, l)
}); err != nil { }); err != nil {
return err return err
}
} }
remoteDigest, err := remoteDigestWithMoby(ctx, node, pushList[0]) }
if err == nil && remoteDigest != "" { remoteDigest, err := remoteDigestWithMoby(ctx, node, pushList[0])
// old daemons might not have containerimage.config.digest set if err == nil && remoteDigest != "" {
// in response so use containerimage.digest value for it if available // old daemons might not have containerimage.config.digest set
if _, ok := rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; !ok { // in response so use containerimage.digest value for it if available
if v, ok := rr.ExporterResponse[exptypes.ExporterImageDigestKey]; ok { if _, ok := rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; !ok {
rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey] = v if v, ok := rr.ExporterResponse[exptypes.ExporterImageDigestKey]; ok {
} rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey] = v
} }
rr.ExporterResponse[exptypes.ExporterImageDigestKey] = remoteDigest
} else if err != nil {
return err
} }
rr.ExporterResponse[exptypes.ExporterImageDigestKey] = remoteDigest
} else if err != nil {
return err
} }
} }
} }
} }
return nil }
}) return nil
})
}(i, dp, so)
} }
return nil return nil

Loading…
Cancel
Save