@@ -15,9 +15,11 @@ import (
1515 gateway "github.com/moby/buildkit/frontend/gateway/client"
1616 "github.com/moby/buildkit/solver/errdefs"
1717 "github.com/moby/buildkit/solver/pb"
18+ "github.com/moby/buildkit/solver/result"
1819 specs "github.com/opencontainers/image-spec/specs-go/v1"
1920 "github.com/pkg/errors"
2021 "github.com/sirupsen/logrus"
22+ "golang.org/x/sync/errgroup"
2123)
2224
2325func NewResultContext (ctx context.Context , c * client.Client , solveOpt client.SolveOpt , res * gateway.Result ) (* ResultContext , error ) {
@@ -28,23 +30,21 @@ func NewResultContext(ctx context.Context, c *client.Client, solveOpt client.Sol
2830 return getResultAt (ctx , c , solveOpt , def , nil )
2931}
3032
31- func getDefinition (ctx context.Context , res * gateway.Result ) (* pb.Definition , error ) {
32- ref , err := res .SingleRef ()
33- if err != nil {
34- return nil , err
35- }
36- st , err := ref .ToState ()
37- if err != nil {
38- return nil , err
39- }
40- def , err := st .Marshal (ctx )
41- if err != nil {
42- return nil , err
43- }
44- return def .ToPB (), nil
33+ func getDefinition (ctx context.Context , res * gateway.Result ) (* result.Result [* pb.Definition ], error ) {
34+ return result .ConvertResult (res , func (ref gateway.Reference ) (* pb.Definition , error ) {
35+ st , err := ref .ToState ()
36+ if err != nil {
37+ return nil , err
38+ }
39+ def , err := st .Marshal (ctx )
40+ if err != nil {
41+ return nil , err
42+ }
43+ return def .ToPB (), nil
44+ })
4545}
4646
47- func getResultAt (ctx context.Context , c * client.Client , solveOpt client.SolveOpt , target * pb.Definition , statusChan chan * client.SolveStatus ) (* ResultContext , error ) {
47+ func getResultAt (ctx context.Context , c * client.Client , solveOpt client.SolveOpt , targets * result. Result [ * pb.Definition ] , statusChan chan * client.SolveStatus ) (* ResultContext , error ) {
4848 ctx , cancel := context .WithCancel (ctx )
4949 defer cancel ()
5050
@@ -80,19 +80,43 @@ func getResultAt(ctx context.Context, c *client.Client, solveOpt client.SolveOpt
8080 doneErr := errors .Errorf ("done" )
8181 ctx , cancel := context .WithCancelCause (ctx )
8282 defer cancel (doneErr )
83- resultCtx := ResultContext {}
84- res2 , err := c .Solve (ctx , gateway.SolveRequest {
85- Evaluate : true ,
86- Definition : target ,
83+
84+ // force evaluation of all targets in parallel
85+ results := make (map [* pb.Definition ]* gateway.Result )
86+ resultsMu := sync.Mutex {}
87+ eg , egCtx := errgroup .WithContext (ctx )
88+ targets .EachRef (func (def * pb.Definition ) error {
89+ eg .Go (func () error {
90+ res2 , err := c .Solve (egCtx , gateway.SolveRequest {
91+ Evaluate : true ,
92+ Definition : def ,
93+ })
94+ if err != nil {
95+ return err
96+ }
97+ resultsMu .Lock ()
98+ results [def ] = res2
99+ resultsMu .Unlock ()
100+ return nil
101+ })
102+ return nil
87103 })
88- if err != nil {
104+ resultCtx := ResultContext {}
105+ if err := eg .Wait (); err != nil {
89106 var se * errdefs.SolveError
90107 if errors .As (err , & se ) {
91108 resultCtx .solveErr = se
92109 } else {
93110 return nil , err
94111 }
95112 }
113+ res2 , _ := result .ConvertResult (targets , func (def * pb.Definition ) (gateway.Reference , error ) {
114+ if res , ok := results [def ]; ok {
115+ return res .Ref , nil
116+ }
117+ return nil , nil
118+ })
119+
96120 // Record the client and ctx as well so that containers can be created from the SolveError.
97121 resultCtx .res = res2
98122 resultCtx .gwClient = c
@@ -208,32 +232,25 @@ func (r *ResultContext) getProcessConfig(cfg *controllerapi.InvokeConfig, stdin
208232}
209233
210234func containerConfigFromResult (ctx context.Context , res * gateway.Result , c gateway.Client , cfg controllerapi.InvokeConfig ) (* gateway.NewContainerRequest , error ) {
211- if res .Ref == nil {
212- return nil , errors .Errorf ("no reference is registered" )
213- }
214235 if cfg .Initial {
215236 return nil , errors .Errorf ("starting from the container from the initial state of the step is supported only on the failed steps" )
216237 }
217- st , err := res .Ref .ToState ()
218- if err != nil {
219- return nil , err
220- }
221- def , err := st .Marshal (ctx )
238+
239+ ps , err := exptypes .ParsePlatforms (res .Metadata )
222240 if err != nil {
223241 return nil , err
224242 }
225- imgRef , err := c .Solve (ctx , gateway.SolveRequest {
226- Definition : def .ToPB (),
227- })
228- if err != nil {
229- return nil , err
243+ ref , ok := res .FindRef (ps .Platforms [0 ].ID )
244+ if ! ok {
245+ return nil , errors .Errorf ("no reference found" )
230246 }
247+
231248 return & gateway.NewContainerRequest {
232249 Mounts : []gateway.Mount {
233250 {
234251 Dest : "/" ,
235252 MountType : pb .MountType_BIND ,
236- Ref : imgRef . Ref ,
253+ Ref : ref ,
237254 },
238255 },
239256 }, nil
0 commit comments