build: move main solve request into main gateway call

Now, we always perform the full solve request in the main gateway call.
This ensures that progress works properly, and makes the lifetime
semantics much clearer.

NewResultContext abstracts the details of a successful/failed build, to
always return a single ResultContext, even though the details of how a
gateway is created is different:
- For a failed build, we can just keep the gateway open.
- For a successful build, we immediately open another gateway and
  re-evaluate the build definition in that gateway. This should give an
  instant cache hit (since the build was just successful).

Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
Justin Chadwell
2023-05-16 17:25:36 +01:00
parent 2dae553d18
commit 8d822fb06c
2 changed files with 224 additions and 132 deletions

View File

@ -885,7 +885,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
cc := c
var printRes map[string][]byte
rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
buildFunc := func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
if opt.PrintFunc != nil {
if _, ok := req.FrontendOpt["frontend.caps"]; !ok {
req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward"
@ -915,7 +915,6 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
}
if fallback {
fmt.Println("falling back!")
req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage
res2, err2 := c.Solve(ctx, req)
if err2 != nil {
@ -931,16 +930,16 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
}
results.Set(resultKey(dp.driverIndex, k), res)
if resultHandleFunc != nil {
resultCtx, err := NewResultContext(ctx, cc, so, res)
if err == nil {
resultHandleFunc(dp.driverIndex, resultCtx)
} else {
logrus.Warnf("failed to record result: %s", err)
}
}
return res, nil
}, ch)
}
var rr *client.SolveResponse
if resultHandleFunc != nil {
var resultCtx *ResultContext
resultCtx, rr, err = NewResultContext(ctx, cc, so, "buildx", buildFunc, ch)
resultHandleFunc(dp.driverIndex, resultCtx)
} else {
rr, err = c.Build(ctx, so, "buildx", buildFunc, ch)
}
if err != nil {
return err
}