@@ -14,9 +14,11 @@ import (
1414 gateway "github.com/moby/buildkit/frontend/gateway/client"
1515 "github.com/moby/buildkit/solver/errdefs"
1616 "github.com/moby/buildkit/solver/pb"
17+ "github.com/moby/buildkit/solver/result"
1718 specs "github.com/opencontainers/image-spec/specs-go/v1"
1819 "github.com/pkg/errors"
1920 "github.com/sirupsen/logrus"
21+ "golang.org/x/sync/errgroup"
2022)
2123
2224func NewResultContext (ctx context.Context , c * client.Client , solveOpt client.SolveOpt , res * gateway.Result ) (* ResultContext , error ) {
@@ -27,23 +29,21 @@ func NewResultContext(ctx context.Context, c *client.Client, solveOpt client.Sol
2729 return getResultAt (ctx , c , solveOpt , def , nil )
2830}
2931
30- func getDefinition (ctx context.Context , res * gateway.Result ) (* pb.Definition , error ) {
31- ref , err := res .SingleRef ()
32- if err != nil {
33- return nil , err
34- }
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
32+ func getDefinition (ctx context.Context , res * gateway.Result ) (* result.Result [* pb.Definition ], error ) {
33+ return result .ConvertResult (res , func (ref gateway.Reference ) (* pb.Definition , error ) {
34+ st , err := ref .ToState ()
35+ if err != nil {
36+ return nil , err
37+ }
38+ def , err := st .Marshal (ctx )
39+ if err != nil {
40+ return nil , err
41+ }
42+ return def .ToPB (), nil
43+ })
4444}
4545
46- func getResultAt (ctx context.Context , c * client.Client , solveOpt client.SolveOpt , target * pb.Definition , statusChan chan * client.SolveStatus ) (* ResultContext , error ) {
46+ func getResultAt (ctx context.Context , c * client.Client , solveOpt client.SolveOpt , targets * result. Result [ * pb.Definition ] , statusChan chan * client.SolveStatus ) (* ResultContext , error ) {
4747 ctx , cancel := context .WithCancel (ctx )
4848 defer cancel ()
4949
@@ -77,19 +77,43 @@ func getResultAt(ctx context.Context, c *client.Client, solveOpt client.SolveOpt
7777 _ , err := c .Build (context .Background (), solveOpt , "buildx" , func (ctx context.Context , c gateway.Client ) (* gateway.Result , error ) {
7878 ctx , cancel := context .WithCancel (ctx )
7979 defer cancel ()
80- resultCtx := ResultContext {}
81- res2 , err := c .Solve (ctx , gateway.SolveRequest {
82- Evaluate : true ,
83- Definition : target ,
80+
81+ // force evaluation of all targets in parallel
82+ results := make (map [* pb.Definition ]* gateway.Result )
83+ resultsMu := sync.Mutex {}
84+ eg , egCtx := errgroup .WithContext (ctx )
85+ targets .EachRef (func (def * pb.Definition ) error {
86+ eg .Go (func () error {
87+ res2 , err := c .Solve (egCtx , gateway.SolveRequest {
88+ Evaluate : true ,
89+ Definition : def ,
90+ })
91+ if err != nil {
92+ return err
93+ }
94+ resultsMu .Lock ()
95+ results [def ] = res2
96+ resultsMu .Unlock ()
97+ return nil
98+ })
99+ return nil
84100 })
85- if err != nil {
101+ resultCtx := ResultContext {}
102+ if err := eg .Wait (); err != nil {
86103 var se * errdefs.SolveError
87104 if errors .As (err , & se ) {
88105 resultCtx .solveErr = se
89106 } else {
90107 return nil , err
91108 }
92109 }
110+ res2 , _ := result .ConvertResult (targets , func (def * pb.Definition ) (gateway.Reference , error ) {
111+ if res , ok := results [def ]; ok {
112+ return res .Ref , nil
113+ }
114+ return nil , nil
115+ })
116+
93117 // Record the client and ctx as well so that containers can be created from the SolveError.
94118 resultCtx .res = res2
95119 resultCtx .gwClient = c
@@ -192,32 +216,25 @@ func (r *ResultContext) getProcessConfig(cfg *controllerapi.InvokeConfig, stdin
192216}
193217
194218func containerConfigFromResult (ctx context.Context , res * gateway.Result , c gateway.Client , cfg controllerapi.InvokeConfig ) (* gateway.NewContainerRequest , error ) {
195- if res .Ref == nil {
196- return nil , errors .Errorf ("no reference is registered" )
197- }
198219 if cfg .Initial {
199220 return nil , errors .Errorf ("starting from the container from the initial state of the step is supported only on the failed steps" )
200221 }
201- st , err := res .Ref .ToState ()
202- if err != nil {
203- return nil , err
204- }
205- def , err := st .Marshal (ctx )
222+
223+ ps , err := exptypes .ParsePlatforms (res .Metadata )
206224 if err != nil {
207225 return nil , err
208226 }
209- imgRef , err := c .Solve (ctx , gateway.SolveRequest {
210- Definition : def .ToPB (),
211- })
212- if err != nil {
213- return nil , err
227+ ref , ok := res .FindRef (ps .Platforms [0 ].ID )
228+ if ! ok {
229+ return nil , errors .Errorf ("no reference found" )
214230 }
231+
215232 return & gateway.NewContainerRequest {
216233 Mounts : []gateway.Mount {
217234 {
218235 Dest : "/" ,
219236 MountType : pb .MountType_BIND ,
220- Ref : imgRef . Ref ,
237+ Ref : ref ,
221238 },
222239 },
223240 }, nil
0 commit comments