mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
controller: return solve response through api
Now clients can access the result of the solve, specifically the image id output. This is a useful refactor, as well as being required if we want to allow bake to invoke through the controller api. This also allows us to remove the quiet option from the API, since we can compute the required progress type outside of the controller, and can print the image id from the result of the solve. As a follow-up, we should also be able to remove the image id file output from the controller api, now that the client has access to it. Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
@ -91,18 +91,21 @@ func (c *Client) Invoke(ctx context.Context, ref string, containerConfig pb.Cont
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (string, error) {
|
||||
func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (string, *client.SolveResponse, error) {
|
||||
ref := identity.NewID()
|
||||
pw, err := progress.NewPrinter(context.TODO(), w, out, progressMode)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", nil, err
|
||||
}
|
||||
statusChan := make(chan *client.SolveStatus)
|
||||
statusDone := make(chan struct{})
|
||||
eg, egCtx := errgroup.WithContext(ctx)
|
||||
var resp *client.SolveResponse
|
||||
eg.Go(func() error {
|
||||
defer close(statusChan)
|
||||
return c.build(egCtx, ref, options, in, statusChan)
|
||||
var err error
|
||||
resp, err = c.build(egCtx, ref, options, in, statusChan)
|
||||
return err
|
||||
})
|
||||
eg.Go(func() error {
|
||||
defer close(statusDone)
|
||||
@ -116,20 +119,27 @@ func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadC
|
||||
<-statusDone
|
||||
return pw.Wait()
|
||||
})
|
||||
return ref, eg.Wait()
|
||||
return ref, resp, eg.Wait()
|
||||
}
|
||||
|
||||
func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, in io.ReadCloser, statusChan chan *client.SolveStatus) error {
|
||||
func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, in io.ReadCloser, statusChan chan *client.SolveStatus) (*client.SolveResponse, error) {
|
||||
eg, egCtx := errgroup.WithContext(ctx)
|
||||
done := make(chan struct{})
|
||||
|
||||
var resp *client.SolveResponse
|
||||
|
||||
eg.Go(func() error {
|
||||
defer close(done)
|
||||
if _, err := c.client().Build(egCtx, &pb.BuildRequest{
|
||||
pbResp, err := c.client().Build(egCtx, &pb.BuildRequest{
|
||||
Ref: ref,
|
||||
Options: &options,
|
||||
}); err != nil {
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp = &client.SolveResponse{
|
||||
ExporterResponse: pbResp.ExporterResponse,
|
||||
}
|
||||
return nil
|
||||
})
|
||||
eg.Go(func() error {
|
||||
@ -254,7 +264,7 @@ func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions,
|
||||
return eg2.Wait()
|
||||
})
|
||||
}
|
||||
return eg.Wait()
|
||||
return resp, eg.Wait()
|
||||
}
|
||||
|
||||
func (c *Client) client() pb.ControllerClient {
|
||||
|
@ -141,7 +141,7 @@ func serveCmd(dockerCli command.Cli) *cobra.Command {
|
||||
}()
|
||||
|
||||
// prepare server
|
||||
b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (res *build.ResultContext, err error) {
|
||||
b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (*client.SolveResponse, *build.ResultContext, error) {
|
||||
return cbuild.RunBuild(ctx, dockerCli, *options, stdin, "quiet", statusChan)
|
||||
})
|
||||
defer b.Close()
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (res *build.ResultContext, err error)
|
||||
type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (resp *client.SolveResponse, res *build.ResultContext, err error)
|
||||
|
||||
func NewServer(buildFunc BuildFunc) *Server {
|
||||
return &Server{
|
||||
@ -150,7 +150,7 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp
|
||||
// Build the specified request
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
res, err := m.buildFunc(ctx, req.Options, inR, statusChan)
|
||||
resp, res, err := m.buildFunc(ctx, req.Options, inR, statusChan)
|
||||
m.sessionMu.Lock()
|
||||
if s, ok := m.session[ref]; ok {
|
||||
s.result = res
|
||||
@ -162,7 +162,12 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp
|
||||
}
|
||||
m.sessionMu.Unlock()
|
||||
|
||||
return &pb.BuildResponse{}, err
|
||||
if resp == nil {
|
||||
resp = &client.SolveResponse{}
|
||||
}
|
||||
return &pb.BuildResponse{
|
||||
ExporterResponse: resp.ExporterResponse,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (m *Server) Status(req *pb.StatusRequest, stream pb.Controller_StatusServer) error {
|
||||
|
Reference in New Issue
Block a user