2018-07-19 16:34:44 +00:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/moby/buildkit/client/buildid"
|
|
|
|
gateway "github.com/moby/buildkit/frontend/gateway/client"
|
|
|
|
"github.com/moby/buildkit/frontend/gateway/grpcclient"
|
|
|
|
gatewayapi "github.com/moby/buildkit/frontend/gateway/pb"
|
|
|
|
"github.com/moby/buildkit/session"
|
|
|
|
"github.com/moby/buildkit/util/apicaps"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildFunc gateway.BuildFunc, statusChan chan *SolveStatus) (*SolveResponse, error) {
|
|
|
|
defer func() {
|
|
|
|
if statusChan != nil {
|
|
|
|
close(statusChan)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
if opt.Frontend != "" {
|
|
|
|
return nil, errors.New("invalid SolveOpt, Build interface cannot use Frontend")
|
|
|
|
}
|
|
|
|
|
|
|
|
if product == "" {
|
|
|
|
product = apicaps.ExportedProduct
|
|
|
|
}
|
|
|
|
|
|
|
|
feOpts := opt.FrontendAttrs
|
|
|
|
opt.FrontendAttrs = nil
|
|
|
|
|
|
|
|
workers, err := c.ListWorkers(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "listing workers for Build")
|
|
|
|
}
|
|
|
|
var gworkers []gateway.WorkerInfo
|
|
|
|
for _, w := range workers {
|
|
|
|
gworkers = append(gworkers, gateway.WorkerInfo{
|
|
|
|
ID: w.ID,
|
|
|
|
Labels: w.Labels,
|
|
|
|
Platforms: w.Platforms,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
cb := func(ref string, s *session.Session) error {
|
2020-09-13 19:51:32 +00:00
|
|
|
gwClient := c.gatewayClientForBuild(ref)
|
|
|
|
g, err := grpcclient.New(ctx, feOpts, s.ID(), product, gwClient, gworkers)
|
2018-07-19 16:34:44 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-09-13 20:39:59 +00:00
|
|
|
gwClient.caps = g.BuildOpts().Caps
|
2020-09-13 19:51:32 +00:00
|
|
|
|
2018-07-19 16:34:44 +00:00
|
|
|
if err := g.Run(ctx, buildFunc); err != nil {
|
|
|
|
return errors.Wrap(err, "failed to run Build function")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.solve(ctx, nil, cb, opt, statusChan)
|
|
|
|
}
|
|
|
|
|
2020-09-13 19:51:32 +00:00
|
|
|
func (c *Client) gatewayClientForBuild(buildid string) *gatewayClientForBuild {
|
2018-07-19 16:34:44 +00:00
|
|
|
g := gatewayapi.NewLLBBridgeClient(c.conn)
|
2020-09-13 19:51:32 +00:00
|
|
|
return &gatewayClientForBuild{
|
|
|
|
gateway: g,
|
|
|
|
buildID: buildid,
|
|
|
|
}
|
2018-07-19 16:34:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type gatewayClientForBuild struct {
|
|
|
|
gateway gatewayapi.LLBBridgeClient
|
|
|
|
buildID string
|
2020-09-13 19:51:32 +00:00
|
|
|
caps apicaps.CapSet
|
2018-07-19 16:34:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (g *gatewayClientForBuild) ResolveImageConfig(ctx context.Context, in *gatewayapi.ResolveImageConfigRequest, opts ...grpc.CallOption) (*gatewayapi.ResolveImageConfigResponse, error) {
|
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.ResolveImageConfig(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *gatewayClientForBuild) Solve(ctx context.Context, in *gatewayapi.SolveRequest, opts ...grpc.CallOption) (*gatewayapi.SolveResponse, error) {
|
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.Solve(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *gatewayClientForBuild) ReadFile(ctx context.Context, in *gatewayapi.ReadFileRequest, opts ...grpc.CallOption) (*gatewayapi.ReadFileResponse, error) {
|
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.ReadFile(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
2018-09-21 12:48:30 +00:00
|
|
|
func (g *gatewayClientForBuild) ReadDir(ctx context.Context, in *gatewayapi.ReadDirRequest, opts ...grpc.CallOption) (*gatewayapi.ReadDirResponse, error) {
|
2020-09-13 19:51:32 +00:00
|
|
|
if err := g.caps.Supports(gatewayapi.CapReadDir); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-09-21 12:48:30 +00:00
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.ReadDir(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
2018-10-02 13:45:39 +00:00
|
|
|
func (g *gatewayClientForBuild) StatFile(ctx context.Context, in *gatewayapi.StatFileRequest, opts ...grpc.CallOption) (*gatewayapi.StatFileResponse, error) {
|
2020-09-13 19:51:32 +00:00
|
|
|
if err := g.caps.Supports(gatewayapi.CapStatFile); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-10-02 13:45:39 +00:00
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.StatFile(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
2018-07-19 16:34:44 +00:00
|
|
|
func (g *gatewayClientForBuild) Ping(ctx context.Context, in *gatewayapi.PingRequest, opts ...grpc.CallOption) (*gatewayapi.PongResponse, error) {
|
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.Ping(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *gatewayClientForBuild) Return(ctx context.Context, in *gatewayapi.ReturnRequest, opts ...grpc.CallOption) (*gatewayapi.ReturnResponse, error) {
|
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.Return(ctx, in, opts...)
|
|
|
|
}
|
2020-02-07 19:53:18 +00:00
|
|
|
|
|
|
|
func (g *gatewayClientForBuild) Inputs(ctx context.Context, in *gatewayapi.InputsRequest, opts ...grpc.CallOption) (*gatewayapi.InputsResponse, error) {
|
2020-09-13 19:51:32 +00:00
|
|
|
if err := g.caps.Supports(gatewayapi.CapFrontendInputs); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-02-07 19:53:18 +00:00
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.Inputs(ctx, in, opts...)
|
|
|
|
}
|
2020-08-05 01:11:32 +00:00
|
|
|
|
|
|
|
func (g *gatewayClientForBuild) NewContainer(ctx context.Context, in *gatewayapi.NewContainerRequest, opts ...grpc.CallOption) (*gatewayapi.NewContainerResponse, error) {
|
2020-09-13 19:51:32 +00:00
|
|
|
if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-08-05 01:11:32 +00:00
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.NewContainer(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *gatewayClientForBuild) ReleaseContainer(ctx context.Context, in *gatewayapi.ReleaseContainerRequest, opts ...grpc.CallOption) (*gatewayapi.ReleaseContainerResponse, error) {
|
2020-09-13 19:51:32 +00:00
|
|
|
if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-08-05 01:11:32 +00:00
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.ReleaseContainer(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *gatewayClientForBuild) ExecProcess(ctx context.Context, opts ...grpc.CallOption) (gatewayapi.LLBBridge_ExecProcessClient, error) {
|
2020-09-13 19:51:32 +00:00
|
|
|
if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-08-05 01:11:32 +00:00
|
|
|
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
|
|
|
|
return g.gateway.ExecProcess(ctx, opts...)
|
|
|
|
}
|