Skip to content

Commit a0d2017

Browse files
committed
build: change build handler to evaluate instead of onresult
This changes the build handler to customize the behavior of evaluate rather than onresult and also simplifies the `ResultHandle`. The `ResultHandle` is now only valid within the gateway callback and can be used to start containers from the handler. `Evaluate` now executes inside of the gateway callback rather than having a separate implementation that executes or re-invokes the build. This keeps the gateway callback session open until the debugger has returned. The `ErrReload` for monitor has now been moved into the `build` package and been renamed to `ErrRestart`. This is because it restarts the build so the name makes a bit more sense. The actual use of this functionality is still tied to the monitor reload. Signed-off-by: Jonathan A. Sternberg <[email protected]>
1 parent da6a1b2 commit a0d2017

File tree

5 files changed

+75
-334
lines changed

5 files changed

+75
-334
lines changed

build/build.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ const (
5959
printLintFallbackImage = "docker/dockerfile:1.8.1@sha256:e87caa74dcb7d46cd820352bfea12591f3dba3ddc4285e19c7dcd13359f7cefd"
6060
)
6161

62+
var ErrRestart = errors.New("build: restart")
63+
6264
type Options struct {
6365
Inputs Inputs
6466

@@ -312,7 +314,7 @@ func toRepoOnly(in string) (string, error) {
312314
}
313315

314316
type Handler struct {
315-
OnResult func(driverIdx int, rCtx *ResultHandle)
317+
Evaluate func(ctx context.Context, c gateway.Client, res *gateway.Result) error
316318
}
317319

318320
func Build(ctx context.Context, nodes []builder.Node, opts map[string]Options, docker *dockerutil.Client, cfg *confutil.Config, w progress.Writer) (resp map[string]*client.SolveResponse, err error) {
@@ -479,9 +481,13 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opts map[
479481
ch, done := progress.NewChannel(pw)
480482
defer func() { <-done }()
481483

482-
cc := c
483-
var callRes map[string][]byte
484-
buildFunc := func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
484+
var (
485+
callRes map[string][]byte
486+
frontendErr error
487+
)
488+
buildFunc := func(ctx context.Context, c gateway.Client) (_ *gateway.Result, retErr error) {
489+
defer func() { frontendErr = retErr }()
490+
485491
if opt.CallFunc != nil {
486492
if _, ok := req.FrontendOpt["frontend.caps"]; !ok {
487493
req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward"
@@ -504,24 +510,25 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opts map[
504510
results.Set(rKey, res)
505511

506512
if children := childTargets[rKey]; len(children) > 0 {
507-
if err := waitForChildren(ctx, res, results, children); err != nil {
513+
if err := waitForChildren(ctx, bh, c, res, results, children); err != nil {
514+
return nil, err
515+
}
516+
} else if bh != nil && bh.Evaluate != nil {
517+
if err := bh.Evaluate(ctx, c, res); err != nil {
508518
return nil, err
509519
}
510520
}
511521
return res, nil
512522
}
523+
513524
buildRef := fmt.Sprintf("%s/%s/%s", node.Builder, node.Name, so.Ref)
514525

515-
var rr *client.SolveResponse
516-
if bh != nil && bh.OnResult != nil {
517-
var resultHandle *ResultHandle
518-
resultHandle, rr, err = NewResultHandle(ctx, cc, *so, "buildx", buildFunc, ch)
519-
bh.OnResult(dp.driverIndex, resultHandle)
520-
} else {
521-
span, ctx := tracing.StartSpan(ctx, "build")
522-
rr, err = c.Build(ctx, *so, "buildx", buildFunc, ch)
523-
tracing.FinishWithError(span, err)
526+
span, ctx := tracing.StartSpan(ctx, "build")
527+
rr, err := c.Build(ctx, *so, "buildx", buildFunc, ch)
528+
if errors.Is(frontendErr, ErrRestart) {
529+
err = ErrRestart
524530
}
531+
tracing.FinishWithError(span, err)
525532

526533
if !so.Internal && desktop.BuildBackendEnabled() && node.Driver.HistoryAPISupported(ctx) {
527534
if err != nil {
@@ -1191,7 +1198,7 @@ func solve(ctx context.Context, c gateway.Client, req gateway.SolveRequest) (*ga
11911198
return res, nil
11921199
}
11931200

1194-
func waitForChildren(ctx context.Context, res *gateway.Result, results *waitmap.Map, children []string) error {
1201+
func waitForChildren(ctx context.Context, bh *Handler, c gateway.Client, res *gateway.Result, results *waitmap.Map, children []string) error {
11951202
// wait for the child targets to register their LLB before evaluating
11961203
_, err := results.Get(ctx, children...)
11971204
if err != nil {
@@ -1200,6 +1207,9 @@ func waitForChildren(ctx context.Context, res *gateway.Result, results *waitmap.
12001207
// we need to wait until the child targets have completed before we can release
12011208
eg, ctx := errgroup.WithContext(ctx)
12021209
eg.Go(func() error {
1210+
if bh != nil && bh.Evaluate != nil {
1211+
return bh.Evaluate(ctx, c, res)
1212+
}
12031213
return res.EachRef(func(ref gateway.Reference) error {
12041214
return ref.Evaluate(ctx)
12051215
})

build/invoke.go

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,18 @@ type Container struct {
5656
func NewContainer(ctx context.Context, resultCtx *ResultHandle, cfg *InvokeConfig) (*Container, error) {
5757
mainCtx := ctx
5858

59-
ctrCh := make(chan *Container)
60-
errCh := make(chan error)
59+
ctrCh := make(chan *Container, 1)
60+
errCh := make(chan error, 1)
6161
go func() {
62-
err := resultCtx.build(func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
63-
ctx, cancel := context.WithCancelCause(ctx)
64-
go func() {
65-
<-mainCtx.Done()
66-
cancel(errors.WithStack(context.Canceled))
67-
}()
68-
69-
containerCfg, err := resultCtx.getContainerConfig(cfg)
70-
if err != nil {
71-
return nil, err
72-
}
62+
err := func() error {
7363
containerCtx, containerCancel := context.WithCancelCause(ctx)
7464
defer containerCancel(errors.WithStack(context.Canceled))
75-
bkContainer, err := c.NewContainer(containerCtx, containerCfg)
65+
66+
bkContainer, err := resultCtx.NewContainer(containerCtx, cfg)
7667
if err != nil {
77-
return nil, err
68+
return err
7869
}
70+
7971
releaseCh := make(chan struct{})
8072
container := &Container{
8173
containerCancel: containerCancel,
@@ -92,8 +84,8 @@ func NewContainer(ctx context.Context, resultCtx *ResultHandle, cfg *InvokeConfi
9284
ctrCh <- container
9385
<-container.releaseCh
9486

95-
return nil, bkContainer.Release(ctx)
96-
})
87+
return bkContainer.Release(ctx)
88+
}()
9789
if err != nil {
9890
errCh <- err
9991
}

0 commit comments

Comments
 (0)