mirror of
https://github.com/mudler/luet.git
synced 2025-09-05 09:10:43 +00:00
Update go.mod and vendor
This commit is contained in:
74
vendor/github.com/moby/buildkit/frontend/gateway/client/client.go
generated
vendored
74
vendor/github.com/moby/buildkit/frontend/gateway/client/client.go
generated
vendored
@@ -1,74 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/moby/buildkit/client/llb"
|
||||
"github.com/moby/buildkit/solver/pb"
|
||||
"github.com/moby/buildkit/util/apicaps"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
fstypes "github.com/tonistiigi/fsutil/types"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
Solve(ctx context.Context, req SolveRequest) (*Result, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string, opt llb.ResolveImageConfigOpt) (digest.Digest, []byte, error)
|
||||
BuildOpts() BuildOpts
|
||||
Inputs(ctx context.Context) (map[string]llb.State, error)
|
||||
}
|
||||
|
||||
type Reference interface {
|
||||
ToState() (llb.State, error)
|
||||
ReadFile(ctx context.Context, req ReadRequest) ([]byte, error)
|
||||
StatFile(ctx context.Context, req StatRequest) (*fstypes.Stat, error)
|
||||
ReadDir(ctx context.Context, req ReadDirRequest) ([]*fstypes.Stat, error)
|
||||
}
|
||||
|
||||
type ReadRequest struct {
|
||||
Filename string
|
||||
Range *FileRange
|
||||
}
|
||||
|
||||
type FileRange struct {
|
||||
Offset int
|
||||
Length int
|
||||
}
|
||||
|
||||
type ReadDirRequest struct {
|
||||
Path string
|
||||
IncludePattern string
|
||||
}
|
||||
|
||||
type StatRequest struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// SolveRequest is same as frontend.SolveRequest but avoiding dependency
|
||||
type SolveRequest struct {
|
||||
Definition *pb.Definition
|
||||
Frontend string
|
||||
FrontendOpt map[string]string
|
||||
FrontendInputs map[string]*pb.Definition
|
||||
CacheImports []CacheOptionsEntry
|
||||
}
|
||||
|
||||
type CacheOptionsEntry struct {
|
||||
Type string
|
||||
Attrs map[string]string
|
||||
}
|
||||
|
||||
type WorkerInfo struct {
|
||||
ID string
|
||||
Labels map[string]string
|
||||
Platforms []specs.Platform
|
||||
}
|
||||
|
||||
type BuildOpts struct {
|
||||
Opts map[string]string
|
||||
SessionID string
|
||||
Workers []WorkerInfo
|
||||
Product string
|
||||
LLBCaps apicaps.CapSet
|
||||
Caps apicaps.CapSet
|
||||
}
|
54
vendor/github.com/moby/buildkit/frontend/gateway/client/result.go
generated
vendored
54
vendor/github.com/moby/buildkit/frontend/gateway/client/result.go
generated
vendored
@@ -1,54 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type BuildFunc func(context.Context, Client) (*Result, error)
|
||||
|
||||
type Result struct {
|
||||
mu sync.Mutex
|
||||
Ref Reference
|
||||
Refs map[string]Reference
|
||||
Metadata map[string][]byte
|
||||
}
|
||||
|
||||
func NewResult() *Result {
|
||||
return &Result{}
|
||||
}
|
||||
|
||||
func (r *Result) AddMeta(k string, v []byte) {
|
||||
r.mu.Lock()
|
||||
if r.Metadata == nil {
|
||||
r.Metadata = map[string][]byte{}
|
||||
}
|
||||
r.Metadata[k] = v
|
||||
r.mu.Unlock()
|
||||
}
|
||||
|
||||
func (r *Result) AddRef(k string, ref Reference) {
|
||||
r.mu.Lock()
|
||||
if r.Refs == nil {
|
||||
r.Refs = map[string]Reference{}
|
||||
}
|
||||
r.Refs[k] = ref
|
||||
r.mu.Unlock()
|
||||
}
|
||||
|
||||
func (r *Result) SetRef(ref Reference) {
|
||||
r.Ref = ref
|
||||
}
|
||||
|
||||
func (r *Result) SingleRef() (Reference, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
if r.Refs != nil && r.Ref == nil {
|
||||
return nil, errors.Errorf("invalid map result")
|
||||
}
|
||||
|
||||
return r.Ref, nil
|
||||
}
|
756
vendor/github.com/moby/buildkit/frontend/gateway/gateway.go
generated
vendored
756
vendor/github.com/moby/buildkit/frontend/gateway/gateway.go
generated
vendored
@@ -1,756 +0,0 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
apitypes "github.com/moby/buildkit/api/types"
|
||||
"github.com/moby/buildkit/cache"
|
||||
cacheutil "github.com/moby/buildkit/cache/util"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/client/llb"
|
||||
"github.com/moby/buildkit/executor"
|
||||
"github.com/moby/buildkit/exporter/containerimage/exptypes"
|
||||
"github.com/moby/buildkit/frontend"
|
||||
pb "github.com/moby/buildkit/frontend/gateway/pb"
|
||||
"github.com/moby/buildkit/identity"
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/solver"
|
||||
opspb "github.com/moby/buildkit/solver/pb"
|
||||
"github.com/moby/buildkit/util/apicaps"
|
||||
"github.com/moby/buildkit/util/tracing"
|
||||
"github.com/moby/buildkit/worker"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/http2"
|
||||
spb "google.golang.org/genproto/googleapis/rpc/status"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/health"
|
||||
"google.golang.org/grpc/health/grpc_health_v1"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const (
|
||||
keySource = "source"
|
||||
keyDevel = "gateway-devel"
|
||||
)
|
||||
|
||||
func NewGatewayFrontend(w frontend.WorkerInfos) frontend.Frontend {
|
||||
return &gatewayFrontend{
|
||||
workers: w,
|
||||
}
|
||||
}
|
||||
|
||||
type gatewayFrontend struct {
|
||||
workers frontend.WorkerInfos
|
||||
}
|
||||
|
||||
func filterPrefix(opts map[string]string, pfx string) map[string]string {
|
||||
m := map[string]string{}
|
||||
for k, v := range opts {
|
||||
if strings.HasPrefix(k, pfx) {
|
||||
m[strings.TrimPrefix(k, pfx)] = v
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string, inputs map[string]*opspb.Definition) (*frontend.Result, error) {
|
||||
source, ok := opts[keySource]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("no source specified for gateway")
|
||||
}
|
||||
|
||||
sid := session.FromContext(ctx)
|
||||
|
||||
_, isDevel := opts[keyDevel]
|
||||
var img specs.Image
|
||||
var rootFS cache.ImmutableRef
|
||||
var readonly bool // TODO: try to switch to read-only by default.
|
||||
|
||||
if isDevel {
|
||||
devRes, err := llbBridge.Solve(session.NewContext(ctx, "gateway:"+sid),
|
||||
frontend.SolveRequest{
|
||||
Frontend: source,
|
||||
FrontendOpt: filterPrefix(opts, "gateway-"),
|
||||
FrontendInputs: inputs,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
devRes.EachRef(func(ref solver.ResultProxy) error {
|
||||
return ref.Release(context.TODO())
|
||||
})
|
||||
}()
|
||||
if devRes.Ref == nil {
|
||||
return nil, errors.Errorf("development gateway didn't return default result")
|
||||
}
|
||||
res, err := devRes.Ref.Result(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
workerRef, ok := res.Sys().(*worker.WorkerRef)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid ref: %T", res.Sys())
|
||||
}
|
||||
rootFS = workerRef.ImmutableRef
|
||||
config, ok := devRes.Metadata[exptypes.ExporterImageConfigKey]
|
||||
if ok {
|
||||
if err := json.Unmarshal(config, &img); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sourceRef, err := reference.ParseNormalizedNamed(source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dgst, config, err := llbBridge.ResolveImageConfig(ctx, reference.TagNameOnly(sourceRef).String(), llb.ResolveImageConfigOpt{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(config, &img); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dgst != "" {
|
||||
sourceRef, err = reference.WithDigest(sourceRef, dgst)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
src := llb.Image(sourceRef.String(), &markTypeFrontend{})
|
||||
|
||||
def, err := src.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := llbBridge.Solve(ctx, frontend.SolveRequest{
|
||||
Definition: def.ToPB(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
res.EachRef(func(ref solver.ResultProxy) error {
|
||||
return ref.Release(context.TODO())
|
||||
})
|
||||
}()
|
||||
if res.Ref == nil {
|
||||
return nil, errors.Errorf("gateway source didn't return default result")
|
||||
|
||||
}
|
||||
r, err := res.Ref.Result(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
workerRef, ok := r.Sys().(*worker.WorkerRef)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid ref: %T", r.Sys())
|
||||
}
|
||||
rootFS = workerRef.ImmutableRef
|
||||
}
|
||||
|
||||
lbf, ctx, err := newLLBBridgeForwarder(ctx, llbBridge, gf.workers, inputs)
|
||||
defer lbf.conn.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args := []string{"/run"}
|
||||
env := []string{}
|
||||
cwd := "/"
|
||||
if img.Config.Env != nil {
|
||||
env = img.Config.Env
|
||||
}
|
||||
if img.Config.Entrypoint != nil {
|
||||
args = img.Config.Entrypoint
|
||||
}
|
||||
if img.Config.WorkingDir != "" {
|
||||
cwd = img.Config.WorkingDir
|
||||
}
|
||||
i := 0
|
||||
for k, v := range opts {
|
||||
env = append(env, fmt.Sprintf("BUILDKIT_FRONTEND_OPT_%d", i)+"="+k+"="+v)
|
||||
i++
|
||||
}
|
||||
|
||||
env = append(env, "BUILDKIT_SESSION_ID="+sid)
|
||||
|
||||
dt, err := json.Marshal(gf.workers.WorkerInfos())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal workers array")
|
||||
}
|
||||
env = append(env, "BUILDKIT_WORKERS="+string(dt))
|
||||
|
||||
defer lbf.Discard()
|
||||
|
||||
env = append(env, "BUILDKIT_EXPORTEDPRODUCT="+apicaps.ExportedProduct)
|
||||
|
||||
meta := executor.Meta{
|
||||
Env: env,
|
||||
Args: args,
|
||||
Cwd: cwd,
|
||||
ReadonlyRootFS: readonly,
|
||||
}
|
||||
|
||||
if v, ok := img.Config.Labels["moby.buildkit.frontend.network.none"]; ok {
|
||||
if ok, _ := strconv.ParseBool(v); ok {
|
||||
meta.NetMode = opspb.NetMode_NONE
|
||||
}
|
||||
}
|
||||
|
||||
err = llbBridge.Exec(ctx, meta, rootFS, lbf.Stdin, lbf.Stdout, os.Stderr)
|
||||
|
||||
if err != nil {
|
||||
if errors.Cause(err) == context.Canceled && lbf.isErrServerClosed {
|
||||
err = errors.Errorf("frontend grpc server closed unexpectedly")
|
||||
}
|
||||
// An existing error (set via Return rpc) takes
|
||||
// precedence over this error, which in turn takes
|
||||
// precedence over a success reported via Return.
|
||||
lbf.mu.Lock()
|
||||
if lbf.err == nil {
|
||||
lbf.result = nil
|
||||
lbf.err = err
|
||||
}
|
||||
lbf.mu.Unlock()
|
||||
}
|
||||
|
||||
return lbf.Result()
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) Discard() {
|
||||
lbf.mu.Lock()
|
||||
defer lbf.mu.Unlock()
|
||||
for id, r := range lbf.refs {
|
||||
if lbf.err == nil && lbf.result != nil {
|
||||
keep := false
|
||||
lbf.result.EachRef(func(r2 solver.ResultProxy) error {
|
||||
if r == r2 {
|
||||
keep = true
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if keep {
|
||||
continue
|
||||
}
|
||||
}
|
||||
r.Release(context.TODO())
|
||||
delete(lbf.refs, id)
|
||||
}
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) Done() <-chan struct{} {
|
||||
return lbf.doneCh
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) setResult(r *frontend.Result, err error) (*pb.ReturnResponse, error) {
|
||||
lbf.mu.Lock()
|
||||
defer lbf.mu.Unlock()
|
||||
|
||||
if (r == nil) == (err == nil) {
|
||||
return nil, errors.New("gateway return must be either result or err")
|
||||
}
|
||||
|
||||
if lbf.result != nil || lbf.err != nil {
|
||||
return nil, errors.New("gateway result is already set")
|
||||
}
|
||||
|
||||
lbf.result = r
|
||||
lbf.err = err
|
||||
close(lbf.doneCh)
|
||||
return &pb.ReturnResponse{}, nil
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) Result() (*frontend.Result, error) {
|
||||
lbf.mu.Lock()
|
||||
defer lbf.mu.Unlock()
|
||||
|
||||
if lbf.result == nil && lbf.err == nil {
|
||||
return nil, errors.New("no result for incomplete build")
|
||||
}
|
||||
|
||||
if lbf.err != nil {
|
||||
return nil, lbf.err
|
||||
}
|
||||
|
||||
return lbf.result, nil
|
||||
}
|
||||
|
||||
func NewBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridge, workers frontend.WorkerInfos, inputs map[string]*opspb.Definition) *llbBridgeForwarder {
|
||||
lbf := &llbBridgeForwarder{
|
||||
callCtx: ctx,
|
||||
llbBridge: llbBridge,
|
||||
refs: map[string]solver.ResultProxy{},
|
||||
doneCh: make(chan struct{}),
|
||||
pipe: newPipe(),
|
||||
workers: workers,
|
||||
inputs: inputs,
|
||||
}
|
||||
return lbf
|
||||
}
|
||||
|
||||
func newLLBBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridge, workers frontend.WorkerInfos, inputs map[string]*opspb.Definition) (*llbBridgeForwarder, context.Context, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
lbf := NewBridgeForwarder(ctx, llbBridge, workers, inputs)
|
||||
server := grpc.NewServer()
|
||||
grpc_health_v1.RegisterHealthServer(server, health.NewServer())
|
||||
pb.RegisterLLBBridgeServer(server, lbf)
|
||||
|
||||
go func() {
|
||||
serve(ctx, server, lbf.conn)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
default:
|
||||
lbf.isErrServerClosed = true
|
||||
}
|
||||
cancel()
|
||||
}()
|
||||
|
||||
return lbf, ctx, nil
|
||||
}
|
||||
|
||||
type pipe struct {
|
||||
Stdin io.ReadCloser
|
||||
Stdout io.WriteCloser
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
func newPipe() *pipe {
|
||||
pr1, pw1, _ := os.Pipe()
|
||||
pr2, pw2, _ := os.Pipe()
|
||||
return &pipe{
|
||||
Stdin: pr1,
|
||||
Stdout: pw2,
|
||||
conn: &conn{
|
||||
Reader: pr2,
|
||||
Writer: pw1,
|
||||
Closer: pw2,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type conn struct {
|
||||
io.Reader
|
||||
io.Writer
|
||||
io.Closer
|
||||
}
|
||||
|
||||
func (s *conn) LocalAddr() net.Addr {
|
||||
return dummyAddr{}
|
||||
}
|
||||
func (s *conn) RemoteAddr() net.Addr {
|
||||
return dummyAddr{}
|
||||
}
|
||||
func (s *conn) SetDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
func (s *conn) SetReadDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
func (s *conn) SetWriteDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type dummyAddr struct {
|
||||
}
|
||||
|
||||
func (d dummyAddr) Network() string {
|
||||
return "pipe"
|
||||
}
|
||||
|
||||
func (d dummyAddr) String() string {
|
||||
return "localhost"
|
||||
}
|
||||
|
||||
type LLBBridgeForwarder interface {
|
||||
pb.LLBBridgeServer
|
||||
Done() <-chan struct{}
|
||||
Result() (*frontend.Result, error)
|
||||
}
|
||||
|
||||
type llbBridgeForwarder struct {
|
||||
mu sync.Mutex
|
||||
callCtx context.Context
|
||||
llbBridge frontend.FrontendLLBBridge
|
||||
refs map[string]solver.ResultProxy
|
||||
// lastRef solver.CachedResult
|
||||
// lastRefs map[string]solver.CachedResult
|
||||
// err error
|
||||
doneCh chan struct{} // closed when result or err become valid through a call to a Return
|
||||
result *frontend.Result
|
||||
err error
|
||||
exporterAttr map[string][]byte
|
||||
workers frontend.WorkerInfos
|
||||
inputs map[string]*opspb.Definition
|
||||
isErrServerClosed bool
|
||||
*pipe
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) ResolveImageConfig(ctx context.Context, req *pb.ResolveImageConfigRequest) (*pb.ResolveImageConfigResponse, error) {
|
||||
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx)
|
||||
var platform *specs.Platform
|
||||
if p := req.Platform; p != nil {
|
||||
platform = &specs.Platform{
|
||||
OS: p.OS,
|
||||
Architecture: p.Architecture,
|
||||
Variant: p.Variant,
|
||||
OSVersion: p.OSVersion,
|
||||
OSFeatures: p.OSFeatures,
|
||||
}
|
||||
}
|
||||
dgst, dt, err := lbf.llbBridge.ResolveImageConfig(ctx, req.Ref, llb.ResolveImageConfigOpt{
|
||||
Platform: platform,
|
||||
ResolveMode: req.ResolveMode,
|
||||
LogName: req.LogName,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.ResolveImageConfigResponse{
|
||||
Digest: dgst,
|
||||
Config: dt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func translateLegacySolveRequest(req *pb.SolveRequest) error {
|
||||
// translates ImportCacheRefs to new CacheImports (v0.4.0)
|
||||
for _, legacyImportRef := range req.ImportCacheRefsDeprecated {
|
||||
im := &pb.CacheOptionsEntry{
|
||||
Type: "registry",
|
||||
Attrs: map[string]string{"ref": legacyImportRef},
|
||||
}
|
||||
// FIXME(AkihiroSuda): skip append if already exists
|
||||
req.CacheImports = append(req.CacheImports, im)
|
||||
}
|
||||
req.ImportCacheRefsDeprecated = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) Solve(ctx context.Context, req *pb.SolveRequest) (*pb.SolveResponse, error) {
|
||||
if err := translateLegacySolveRequest(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var cacheImports []frontend.CacheOptionsEntry
|
||||
for _, e := range req.CacheImports {
|
||||
cacheImports = append(cacheImports, frontend.CacheOptionsEntry{
|
||||
Type: e.Type,
|
||||
Attrs: e.Attrs,
|
||||
})
|
||||
}
|
||||
|
||||
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx)
|
||||
res, err := lbf.llbBridge.Solve(ctx, frontend.SolveRequest{
|
||||
Definition: req.Definition,
|
||||
Frontend: req.Frontend,
|
||||
FrontendOpt: req.FrontendOpt,
|
||||
FrontendInputs: req.FrontendInputs,
|
||||
CacheImports: cacheImports,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(res.Refs) > 0 && !req.AllowResultReturn {
|
||||
// this should never happen because old client shouldn't make a map request
|
||||
return nil, errors.Errorf("solve did not return default result")
|
||||
}
|
||||
|
||||
pbRes := &pb.Result{
|
||||
Metadata: res.Metadata,
|
||||
}
|
||||
var defaultID string
|
||||
|
||||
lbf.mu.Lock()
|
||||
if res.Refs != nil {
|
||||
ids := make(map[string]string, len(res.Refs))
|
||||
defs := make(map[string]*opspb.Definition, len(res.Refs))
|
||||
for k, ref := range res.Refs {
|
||||
id := identity.NewID()
|
||||
if ref == nil {
|
||||
id = ""
|
||||
} else {
|
||||
lbf.refs[id] = ref
|
||||
}
|
||||
ids[k] = id
|
||||
defs[k] = ref.Definition()
|
||||
}
|
||||
|
||||
if req.AllowResultArrayRef {
|
||||
refMap := make(map[string]*pb.Ref, len(res.Refs))
|
||||
for k, id := range ids {
|
||||
refMap[k] = &pb.Ref{Id: id, Def: defs[k]}
|
||||
}
|
||||
pbRes.Result = &pb.Result_Refs{Refs: &pb.RefMap{Refs: refMap}}
|
||||
} else {
|
||||
pbRes.Result = &pb.Result_RefsDeprecated{RefsDeprecated: &pb.RefMapDeprecated{Refs: ids}}
|
||||
}
|
||||
} else {
|
||||
ref := res.Ref
|
||||
id := identity.NewID()
|
||||
|
||||
var def *opspb.Definition
|
||||
if ref == nil {
|
||||
id = ""
|
||||
} else {
|
||||
def = ref.Definition()
|
||||
lbf.refs[id] = ref
|
||||
}
|
||||
defaultID = id
|
||||
|
||||
if req.AllowResultArrayRef {
|
||||
pbRes.Result = &pb.Result_Ref{Ref: &pb.Ref{Id: id, Def: def}}
|
||||
} else {
|
||||
pbRes.Result = &pb.Result_RefDeprecated{RefDeprecated: id}
|
||||
}
|
||||
}
|
||||
lbf.mu.Unlock()
|
||||
|
||||
// compatibility mode for older clients
|
||||
if req.Final {
|
||||
exp := map[string][]byte{}
|
||||
if err := json.Unmarshal(req.ExporterAttr, &exp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range res.Metadata {
|
||||
exp[k] = v
|
||||
}
|
||||
|
||||
lbf.mu.Lock()
|
||||
lbf.result = &frontend.Result{
|
||||
Ref: lbf.refs[defaultID],
|
||||
Metadata: exp,
|
||||
}
|
||||
lbf.mu.Unlock()
|
||||
}
|
||||
|
||||
resp := &pb.SolveResponse{
|
||||
Result: pbRes,
|
||||
}
|
||||
|
||||
if !req.AllowResultReturn {
|
||||
resp.Ref = defaultID
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
func (lbf *llbBridgeForwarder) ReadFile(ctx context.Context, req *pb.ReadFileRequest) (*pb.ReadFileResponse, error) {
|
||||
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx)
|
||||
lbf.mu.Lock()
|
||||
ref, ok := lbf.refs[req.Ref]
|
||||
lbf.mu.Unlock()
|
||||
if !ok {
|
||||
return nil, errors.Errorf("no such ref: %v", req.Ref)
|
||||
}
|
||||
if ref == nil {
|
||||
return nil, errors.Wrapf(os.ErrNotExist, "%s not found", req.FilePath)
|
||||
}
|
||||
r, err := ref.Result(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
workerRef, ok := r.Sys().(*worker.WorkerRef)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid ref: %T", r.Sys())
|
||||
}
|
||||
|
||||
newReq := cacheutil.ReadRequest{
|
||||
Filename: req.FilePath,
|
||||
}
|
||||
if r := req.Range; r != nil {
|
||||
newReq.Range = &cacheutil.FileRange{
|
||||
Offset: int(r.Offset),
|
||||
Length: int(r.Length),
|
||||
}
|
||||
}
|
||||
|
||||
dt, err := cacheutil.ReadFile(ctx, workerRef.ImmutableRef, newReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.ReadFileResponse{Data: dt}, nil
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) ReadDir(ctx context.Context, req *pb.ReadDirRequest) (*pb.ReadDirResponse, error) {
|
||||
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx)
|
||||
lbf.mu.Lock()
|
||||
ref, ok := lbf.refs[req.Ref]
|
||||
lbf.mu.Unlock()
|
||||
if !ok {
|
||||
return nil, errors.Errorf("no such ref: %v", req.Ref)
|
||||
}
|
||||
if ref == nil {
|
||||
return nil, errors.Wrapf(os.ErrNotExist, "%s not found", req.DirPath)
|
||||
}
|
||||
r, err := ref.Result(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
workerRef, ok := r.Sys().(*worker.WorkerRef)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid ref: %T", r.Sys())
|
||||
}
|
||||
|
||||
newReq := cacheutil.ReadDirRequest{
|
||||
Path: req.DirPath,
|
||||
IncludePattern: req.IncludePattern,
|
||||
}
|
||||
entries, err := cacheutil.ReadDir(ctx, workerRef.ImmutableRef, newReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.ReadDirResponse{Entries: entries}, nil
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) StatFile(ctx context.Context, req *pb.StatFileRequest) (*pb.StatFileResponse, error) {
|
||||
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx)
|
||||
lbf.mu.Lock()
|
||||
ref, ok := lbf.refs[req.Ref]
|
||||
lbf.mu.Unlock()
|
||||
if !ok {
|
||||
return nil, errors.Errorf("no such ref: %v", req.Ref)
|
||||
}
|
||||
if ref == nil {
|
||||
return nil, errors.Wrapf(os.ErrNotExist, "%s not found", req.Path)
|
||||
}
|
||||
r, err := ref.Result(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
workerRef, ok := r.Sys().(*worker.WorkerRef)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid ref: %T", r.Sys())
|
||||
}
|
||||
|
||||
st, err := cacheutil.StatFile(ctx, workerRef.ImmutableRef, req.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.StatFileResponse{Stat: st}, nil
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) Ping(context.Context, *pb.PingRequest) (*pb.PongResponse, error) {
|
||||
|
||||
workers := lbf.workers.WorkerInfos()
|
||||
pbWorkers := make([]*apitypes.WorkerRecord, 0, len(workers))
|
||||
for _, w := range workers {
|
||||
pbWorkers = append(pbWorkers, &apitypes.WorkerRecord{
|
||||
ID: w.ID,
|
||||
Labels: w.Labels,
|
||||
Platforms: opspb.PlatformsFromSpec(w.Platforms),
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.PongResponse{
|
||||
FrontendAPICaps: pb.Caps.All(),
|
||||
Workers: pbWorkers,
|
||||
LLBCaps: opspb.Caps.All(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) Return(ctx context.Context, in *pb.ReturnRequest) (*pb.ReturnResponse, error) {
|
||||
if in.Error != nil {
|
||||
return lbf.setResult(nil, status.ErrorProto(&spb.Status{
|
||||
Code: in.Error.Code,
|
||||
Message: in.Error.Message,
|
||||
// Details: in.Error.Details,
|
||||
}))
|
||||
} else {
|
||||
r := &frontend.Result{
|
||||
Metadata: in.Result.Metadata,
|
||||
}
|
||||
|
||||
switch res := in.Result.Result.(type) {
|
||||
case *pb.Result_RefDeprecated:
|
||||
ref, err := lbf.convertRef(res.RefDeprecated)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.Ref = ref
|
||||
case *pb.Result_RefsDeprecated:
|
||||
m := map[string]solver.ResultProxy{}
|
||||
for k, id := range res.RefsDeprecated.Refs {
|
||||
ref, err := lbf.convertRef(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m[k] = ref
|
||||
}
|
||||
r.Refs = m
|
||||
case *pb.Result_Ref:
|
||||
ref, err := lbf.convertRef(res.Ref.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.Ref = ref
|
||||
case *pb.Result_Refs:
|
||||
m := map[string]solver.ResultProxy{}
|
||||
for k, ref := range res.Refs.Refs {
|
||||
ref, err := lbf.convertRef(ref.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m[k] = ref
|
||||
}
|
||||
r.Refs = m
|
||||
}
|
||||
return lbf.setResult(r, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) Inputs(ctx context.Context, in *pb.InputsRequest) (*pb.InputsResponse, error) {
|
||||
return &pb.InputsResponse{
|
||||
Definitions: lbf.inputs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (lbf *llbBridgeForwarder) convertRef(id string) (solver.ResultProxy, error) {
|
||||
if id == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
lbf.mu.Lock()
|
||||
defer lbf.mu.Unlock()
|
||||
|
||||
r, ok := lbf.refs[id]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("return reference %s not found", id)
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func serve(ctx context.Context, grpcServer *grpc.Server, conn net.Conn) {
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
conn.Close()
|
||||
}()
|
||||
logrus.Debugf("serving grpc connection")
|
||||
(&http2.Server{}).ServeConn(conn, &http2.ServeConnOpts{Handler: grpcServer})
|
||||
}
|
||||
|
||||
type markTypeFrontend struct{}
|
||||
|
||||
func (*markTypeFrontend) SetImageOption(ii *llb.ImageInfo) {
|
||||
ii.RecordType = string(client.UsageRecordTypeFrontend)
|
||||
}
|
591
vendor/github.com/moby/buildkit/frontend/gateway/grpcclient/client.go
generated
vendored
591
vendor/github.com/moby/buildkit/frontend/gateway/grpcclient/client.go
generated
vendored
@@ -1,591 +0,0 @@
|
||||
package grpcclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/googleapis/google/rpc"
|
||||
"github.com/moby/buildkit/client/llb"
|
||||
"github.com/moby/buildkit/frontend/gateway/client"
|
||||
pb "github.com/moby/buildkit/frontend/gateway/pb"
|
||||
opspb "github.com/moby/buildkit/solver/pb"
|
||||
"github.com/moby/buildkit/util/apicaps"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
fstypes "github.com/tonistiigi/fsutil/types"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const frontendPrefix = "BUILDKIT_FRONTEND_OPT_"
|
||||
|
||||
type GrpcClient interface {
|
||||
Run(context.Context, client.BuildFunc) error
|
||||
}
|
||||
|
||||
func New(ctx context.Context, opts map[string]string, session, product string, c pb.LLBBridgeClient, w []client.WorkerInfo) (GrpcClient, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
resp, err := c.Ping(ctx, &pb.PingRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.FrontendAPICaps == nil {
|
||||
resp.FrontendAPICaps = defaultCaps()
|
||||
}
|
||||
|
||||
if resp.LLBCaps == nil {
|
||||
resp.LLBCaps = defaultLLBCaps()
|
||||
}
|
||||
|
||||
return &grpcClient{
|
||||
client: c,
|
||||
opts: opts,
|
||||
sessionID: session,
|
||||
workers: w,
|
||||
product: product,
|
||||
caps: pb.Caps.CapSet(resp.FrontendAPICaps),
|
||||
llbCaps: opspb.Caps.CapSet(resp.LLBCaps),
|
||||
requests: map[string]*pb.SolveRequest{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func current() (GrpcClient, error) {
|
||||
if ep := product(); ep != "" {
|
||||
apicaps.ExportedProduct = ep
|
||||
}
|
||||
|
||||
ctx, conn, err := grpcClientConn(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return New(ctx, opts(), sessionID(), product(), pb.NewLLBBridgeClient(conn), workers())
|
||||
}
|
||||
|
||||
func convertRef(ref client.Reference) (*pb.Ref, error) {
|
||||
if ref == nil {
|
||||
return &pb.Ref{}, nil
|
||||
}
|
||||
r, ok := ref.(*reference)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid return reference type %T", ref)
|
||||
}
|
||||
return &pb.Ref{Id: r.id, Def: r.def}, nil
|
||||
}
|
||||
|
||||
func RunFromEnvironment(ctx context.Context, f client.BuildFunc) error {
|
||||
client, err := current()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to initialize client from environment")
|
||||
}
|
||||
return client.Run(ctx, f)
|
||||
}
|
||||
|
||||
func (c *grpcClient) Run(ctx context.Context, f client.BuildFunc) (retError error) {
|
||||
export := c.caps.Supports(pb.CapReturnResult) == nil
|
||||
|
||||
var (
|
||||
res *client.Result
|
||||
err error
|
||||
)
|
||||
if export {
|
||||
defer func() {
|
||||
req := &pb.ReturnRequest{}
|
||||
if retError == nil {
|
||||
if res == nil {
|
||||
res = &client.Result{}
|
||||
}
|
||||
pbRes := &pb.Result{
|
||||
Metadata: res.Metadata,
|
||||
}
|
||||
if res.Refs != nil {
|
||||
if c.caps.Supports(pb.CapProtoRefArray) == nil {
|
||||
m := map[string]*pb.Ref{}
|
||||
for k, r := range res.Refs {
|
||||
pbRef, err := convertRef(r)
|
||||
if err != nil {
|
||||
retError = err
|
||||
continue
|
||||
}
|
||||
m[k] = pbRef
|
||||
}
|
||||
pbRes.Result = &pb.Result_Refs{Refs: &pb.RefMap{Refs: m}}
|
||||
} else {
|
||||
// Server doesn't support the new wire format for refs, so we construct
|
||||
// a deprecated result ref map.
|
||||
m := map[string]string{}
|
||||
for k, r := range res.Refs {
|
||||
pbRef, err := convertRef(r)
|
||||
if err != nil {
|
||||
retError = err
|
||||
continue
|
||||
}
|
||||
m[k] = pbRef.Id
|
||||
}
|
||||
pbRes.Result = &pb.Result_RefsDeprecated{RefsDeprecated: &pb.RefMapDeprecated{Refs: m}}
|
||||
}
|
||||
} else {
|
||||
pbRef, err := convertRef(res.Ref)
|
||||
if err != nil {
|
||||
retError = err
|
||||
} else {
|
||||
if c.caps.Supports(pb.CapProtoRefArray) == nil {
|
||||
pbRes.Result = &pb.Result_Ref{Ref: pbRef}
|
||||
} else {
|
||||
// Server doesn't support the new wire format for refs, so we construct
|
||||
// a deprecated result ref.
|
||||
pbRes.Result = &pb.Result_RefDeprecated{RefDeprecated: pbRef.Id}
|
||||
}
|
||||
}
|
||||
}
|
||||
if retError == nil {
|
||||
req.Result = pbRes
|
||||
}
|
||||
}
|
||||
if retError != nil {
|
||||
st, _ := status.FromError(errors.Cause(retError))
|
||||
stp := st.Proto()
|
||||
req.Error = &rpc.Status{
|
||||
Code: stp.Code,
|
||||
Message: stp.Message,
|
||||
// Details: stp.Details,
|
||||
}
|
||||
}
|
||||
if _, err := c.client.Return(ctx, req); err != nil && retError == nil {
|
||||
retError = err
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if res, err = f(ctx, c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.caps.Supports(pb.CapReturnMap); len(res.Refs) > 1 && err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !export {
|
||||
exportedAttrBytes, err := json.Marshal(res.Metadata)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to marshal return metadata")
|
||||
}
|
||||
|
||||
req, err := c.requestForRef(res.Ref)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to find return ref")
|
||||
}
|
||||
|
||||
req.Final = true
|
||||
req.ExporterAttr = exportedAttrBytes
|
||||
|
||||
if _, err := c.client.Solve(ctx, req); err != nil {
|
||||
return errors.Wrapf(err, "failed to solve")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultCaps returns the capabilities that were implemented when capabilities
|
||||
// support was added. This list is frozen and should never be changed.
|
||||
func defaultCaps() []apicaps.PBCap {
|
||||
return []apicaps.PBCap{
|
||||
{ID: string(pb.CapSolveBase), Enabled: true},
|
||||
{ID: string(pb.CapSolveInlineReturn), Enabled: true},
|
||||
{ID: string(pb.CapResolveImage), Enabled: true},
|
||||
{ID: string(pb.CapReadFile), Enabled: true},
|
||||
}
|
||||
}
|
||||
|
||||
// defaultLLBCaps returns the LLB capabilities that were implemented when capabilities
|
||||
// support was added. This list is frozen and should never be changed.
|
||||
func defaultLLBCaps() []apicaps.PBCap {
|
||||
return []apicaps.PBCap{
|
||||
{ID: string(opspb.CapSourceImage), Enabled: true},
|
||||
{ID: string(opspb.CapSourceLocal), Enabled: true},
|
||||
{ID: string(opspb.CapSourceLocalUnique), Enabled: true},
|
||||
{ID: string(opspb.CapSourceLocalSessionID), Enabled: true},
|
||||
{ID: string(opspb.CapSourceLocalIncludePatterns), Enabled: true},
|
||||
{ID: string(opspb.CapSourceLocalFollowPaths), Enabled: true},
|
||||
{ID: string(opspb.CapSourceLocalExcludePatterns), Enabled: true},
|
||||
{ID: string(opspb.CapSourceLocalSharedKeyHint), Enabled: true},
|
||||
{ID: string(opspb.CapSourceGit), Enabled: true},
|
||||
{ID: string(opspb.CapSourceGitKeepDir), Enabled: true},
|
||||
{ID: string(opspb.CapSourceGitFullURL), Enabled: true},
|
||||
{ID: string(opspb.CapSourceHTTP), Enabled: true},
|
||||
{ID: string(opspb.CapSourceHTTPChecksum), Enabled: true},
|
||||
{ID: string(opspb.CapSourceHTTPPerm), Enabled: true},
|
||||
{ID: string(opspb.CapSourceHTTPUIDGID), Enabled: true},
|
||||
{ID: string(opspb.CapBuildOpLLBFileName), Enabled: true},
|
||||
{ID: string(opspb.CapExecMetaBase), Enabled: true},
|
||||
{ID: string(opspb.CapExecMetaProxy), Enabled: true},
|
||||
{ID: string(opspb.CapExecMountBind), Enabled: true},
|
||||
{ID: string(opspb.CapExecMountCache), Enabled: true},
|
||||
{ID: string(opspb.CapExecMountCacheSharing), Enabled: true},
|
||||
{ID: string(opspb.CapExecMountSelector), Enabled: true},
|
||||
{ID: string(opspb.CapExecMountTmpfs), Enabled: true},
|
||||
{ID: string(opspb.CapExecMountSecret), Enabled: true},
|
||||
{ID: string(opspb.CapConstraints), Enabled: true},
|
||||
{ID: string(opspb.CapPlatform), Enabled: true},
|
||||
{ID: string(opspb.CapMetaIgnoreCache), Enabled: true},
|
||||
{ID: string(opspb.CapMetaDescription), Enabled: true},
|
||||
{ID: string(opspb.CapMetaExportCache), Enabled: true},
|
||||
}
|
||||
}
|
||||
|
||||
type grpcClient struct {
|
||||
client pb.LLBBridgeClient
|
||||
opts map[string]string
|
||||
sessionID string
|
||||
product string
|
||||
workers []client.WorkerInfo
|
||||
caps apicaps.CapSet
|
||||
llbCaps apicaps.CapSet
|
||||
requests map[string]*pb.SolveRequest
|
||||
}
|
||||
|
||||
func (c *grpcClient) requestForRef(ref client.Reference) (*pb.SolveRequest, error) {
|
||||
emptyReq := &pb.SolveRequest{
|
||||
Definition: &opspb.Definition{},
|
||||
}
|
||||
if ref == nil {
|
||||
return emptyReq, nil
|
||||
}
|
||||
r, ok := ref.(*reference)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("return reference has invalid type %T", ref)
|
||||
}
|
||||
if r.id == "" {
|
||||
return emptyReq, nil
|
||||
}
|
||||
req, ok := c.requests[r.id]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("did not find request for return reference %s", r.id)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (c *grpcClient) Solve(ctx context.Context, creq client.SolveRequest) (*client.Result, error) {
|
||||
if creq.Definition != nil {
|
||||
for _, md := range creq.Definition.Metadata {
|
||||
for cap := range md.Caps {
|
||||
if err := c.llbCaps.Supports(cap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var (
|
||||
// old API
|
||||
legacyRegistryCacheImports []string
|
||||
// new API (CapImportCaches)
|
||||
cacheImports []*pb.CacheOptionsEntry
|
||||
)
|
||||
supportCapImportCaches := c.caps.Supports(pb.CapImportCaches) == nil
|
||||
for _, im := range creq.CacheImports {
|
||||
if !supportCapImportCaches && im.Type == "registry" {
|
||||
legacyRegistryCacheImports = append(legacyRegistryCacheImports, im.Attrs["ref"])
|
||||
} else {
|
||||
cacheImports = append(cacheImports, &pb.CacheOptionsEntry{
|
||||
Type: im.Type,
|
||||
Attrs: im.Attrs,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
req := &pb.SolveRequest{
|
||||
Definition: creq.Definition,
|
||||
Frontend: creq.Frontend,
|
||||
FrontendOpt: creq.FrontendOpt,
|
||||
FrontendInputs: creq.FrontendInputs,
|
||||
AllowResultReturn: true,
|
||||
AllowResultArrayRef: true,
|
||||
// old API
|
||||
ImportCacheRefsDeprecated: legacyRegistryCacheImports,
|
||||
// new API
|
||||
CacheImports: cacheImports,
|
||||
}
|
||||
|
||||
// backwards compatibility with inline return
|
||||
if c.caps.Supports(pb.CapReturnResult) != nil {
|
||||
req.ExporterAttr = []byte("{}")
|
||||
}
|
||||
|
||||
resp, err := c.client.Solve(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := &client.Result{}
|
||||
|
||||
if resp.Result == nil {
|
||||
if id := resp.Ref; id != "" {
|
||||
c.requests[id] = req
|
||||
}
|
||||
res.SetRef(&reference{id: resp.Ref, c: c})
|
||||
} else {
|
||||
res.Metadata = resp.Result.Metadata
|
||||
switch pbRes := resp.Result.Result.(type) {
|
||||
case *pb.Result_RefDeprecated:
|
||||
if id := pbRes.RefDeprecated; id != "" {
|
||||
res.SetRef(&reference{id: id, c: c})
|
||||
}
|
||||
case *pb.Result_RefsDeprecated:
|
||||
for k, v := range pbRes.RefsDeprecated.Refs {
|
||||
ref := &reference{id: v, c: c}
|
||||
if v == "" {
|
||||
ref = nil
|
||||
}
|
||||
res.AddRef(k, ref)
|
||||
}
|
||||
case *pb.Result_Ref:
|
||||
if pbRes.Ref.Id != "" {
|
||||
ref, err := newReference(c, pbRes.Ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.SetRef(ref)
|
||||
}
|
||||
case *pb.Result_Refs:
|
||||
for k, v := range pbRes.Refs.Refs {
|
||||
var ref *reference
|
||||
if v.Id != "" {
|
||||
ref, err = newReference(c, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
res.AddRef(k, ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *grpcClient) ResolveImageConfig(ctx context.Context, ref string, opt llb.ResolveImageConfigOpt) (digest.Digest, []byte, error) {
|
||||
var p *opspb.Platform
|
||||
if platform := opt.Platform; platform != nil {
|
||||
p = &opspb.Platform{
|
||||
OS: platform.OS,
|
||||
Architecture: platform.Architecture,
|
||||
Variant: platform.Variant,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
}
|
||||
}
|
||||
resp, err := c.client.ResolveImageConfig(ctx, &pb.ResolveImageConfigRequest{Ref: ref, Platform: p, ResolveMode: opt.ResolveMode, LogName: opt.LogName})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return resp.Digest, resp.Config, nil
|
||||
}
|
||||
|
||||
func (c *grpcClient) BuildOpts() client.BuildOpts {
|
||||
return client.BuildOpts{
|
||||
Opts: c.opts,
|
||||
SessionID: c.sessionID,
|
||||
Workers: c.workers,
|
||||
Product: c.product,
|
||||
LLBCaps: c.llbCaps,
|
||||
Caps: c.caps,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *grpcClient) Inputs(ctx context.Context) (map[string]llb.State, error) {
|
||||
err := c.caps.Supports(pb.CapFrontendInputs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.client.Inputs(ctx, &pb.InputsRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inputs := make(map[string]llb.State)
|
||||
for key, def := range resp.Definitions {
|
||||
op, err := llb.NewDefinitionOp(def)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inputs[key] = llb.NewState(op)
|
||||
}
|
||||
return inputs, nil
|
||||
|
||||
}
|
||||
|
||||
type reference struct {
|
||||
c *grpcClient
|
||||
id string
|
||||
def *opspb.Definition
|
||||
output llb.Output
|
||||
}
|
||||
|
||||
func newReference(c *grpcClient, ref *pb.Ref) (*reference, error) {
|
||||
return &reference{c: c, id: ref.Id, def: ref.Def}, nil
|
||||
}
|
||||
|
||||
func (r *reference) ToState() (st llb.State, err error) {
|
||||
err = r.c.caps.Supports(pb.CapReferenceOutput)
|
||||
if err != nil {
|
||||
return st, err
|
||||
}
|
||||
|
||||
if r.def == nil {
|
||||
return st, errors.Errorf("gateway did not return reference with definition")
|
||||
}
|
||||
|
||||
defop, err := llb.NewDefinitionOp(r.def)
|
||||
if err != nil {
|
||||
return st, err
|
||||
}
|
||||
|
||||
return llb.NewState(defop), nil
|
||||
}
|
||||
|
||||
func (r *reference) ReadFile(ctx context.Context, req client.ReadRequest) ([]byte, error) {
|
||||
rfr := &pb.ReadFileRequest{FilePath: req.Filename, Ref: r.id}
|
||||
if r := req.Range; r != nil {
|
||||
rfr.Range = &pb.FileRange{
|
||||
Offset: int64(r.Offset),
|
||||
Length: int64(r.Length),
|
||||
}
|
||||
}
|
||||
resp, err := r.c.client.ReadFile(ctx, rfr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Data, nil
|
||||
}
|
||||
|
||||
func (r *reference) ReadDir(ctx context.Context, req client.ReadDirRequest) ([]*fstypes.Stat, error) {
|
||||
if err := r.c.caps.Supports(pb.CapReadDir); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rdr := &pb.ReadDirRequest{
|
||||
DirPath: req.Path,
|
||||
IncludePattern: req.IncludePattern,
|
||||
Ref: r.id,
|
||||
}
|
||||
resp, err := r.c.client.ReadDir(ctx, rdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Entries, nil
|
||||
}
|
||||
|
||||
func (r *reference) StatFile(ctx context.Context, req client.StatRequest) (*fstypes.Stat, error) {
|
||||
if err := r.c.caps.Supports(pb.CapStatFile); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rdr := &pb.StatFileRequest{
|
||||
Path: req.Path,
|
||||
Ref: r.id,
|
||||
}
|
||||
resp, err := r.c.client.StatFile(ctx, rdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Stat, nil
|
||||
}
|
||||
|
||||
func grpcClientConn(ctx context.Context) (context.Context, *grpc.ClientConn, error) {
|
||||
dialOpt := grpc.WithDialer(func(addr string, d time.Duration) (net.Conn, error) {
|
||||
return stdioConn(), nil
|
||||
})
|
||||
|
||||
cc, err := grpc.DialContext(ctx, "", dialOpt, grpc.WithInsecure())
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to create grpc client")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
_ = cancel
|
||||
// go monitorHealth(ctx, cc, cancel)
|
||||
|
||||
return ctx, cc, nil
|
||||
}
|
||||
|
||||
func stdioConn() net.Conn {
|
||||
return &conn{os.Stdin, os.Stdout, os.Stdout}
|
||||
}
|
||||
|
||||
type conn struct {
|
||||
io.Reader
|
||||
io.Writer
|
||||
io.Closer
|
||||
}
|
||||
|
||||
func (s *conn) LocalAddr() net.Addr {
|
||||
return dummyAddr{}
|
||||
}
|
||||
func (s *conn) RemoteAddr() net.Addr {
|
||||
return dummyAddr{}
|
||||
}
|
||||
func (s *conn) SetDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
func (s *conn) SetReadDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
func (s *conn) SetWriteDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type dummyAddr struct {
|
||||
}
|
||||
|
||||
func (d dummyAddr) Network() string {
|
||||
return "pipe"
|
||||
}
|
||||
|
||||
func (d dummyAddr) String() string {
|
||||
return "localhost"
|
||||
}
|
||||
|
||||
func opts() map[string]string {
|
||||
opts := map[string]string{}
|
||||
for _, env := range os.Environ() {
|
||||
parts := strings.SplitN(env, "=", 2)
|
||||
k := parts[0]
|
||||
v := ""
|
||||
if len(parts) == 2 {
|
||||
v = parts[1]
|
||||
}
|
||||
if !strings.HasPrefix(k, frontendPrefix) {
|
||||
continue
|
||||
}
|
||||
parts = strings.SplitN(v, "=", 2)
|
||||
v = ""
|
||||
if len(parts) == 2 {
|
||||
v = parts[1]
|
||||
}
|
||||
opts[parts[0]] = v
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func sessionID() string {
|
||||
return os.Getenv("BUILDKIT_SESSION_ID")
|
||||
}
|
||||
|
||||
func workers() []client.WorkerInfo {
|
||||
var c []client.WorkerInfo
|
||||
if err := json.Unmarshal([]byte(os.Getenv("BUILDKIT_WORKERS")), &c); err != nil {
|
||||
return nil
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func product() string {
|
||||
return os.Getenv("BUILDKIT_EXPORTEDPRODUCT")
|
||||
}
|
139
vendor/github.com/moby/buildkit/frontend/gateway/pb/caps.go
generated
vendored
139
vendor/github.com/moby/buildkit/frontend/gateway/pb/caps.go
generated
vendored
@@ -1,139 +0,0 @@
|
||||
package moby_buildkit_v1_frontend
|
||||
|
||||
import "github.com/moby/buildkit/util/apicaps"
|
||||
|
||||
var Caps apicaps.CapList
|
||||
|
||||
// Every backwards or forwards non-compatible change needs to add a new capability row.
|
||||
// By default new capabilities should be experimental. After merge a capability is
|
||||
// considered immutable. After a capability is marked stable it should not be disabled.
|
||||
|
||||
const (
|
||||
CapSolveBase apicaps.CapID = "solve.base"
|
||||
CapSolveInlineReturn apicaps.CapID = "solve.inlinereturn"
|
||||
CapResolveImage apicaps.CapID = "resolveimage"
|
||||
CapResolveImageResolveMode apicaps.CapID = "resolveimage.resolvemode"
|
||||
CapReadFile apicaps.CapID = "readfile"
|
||||
CapReturnResult apicaps.CapID = "return"
|
||||
CapReturnMap apicaps.CapID = "returnmap"
|
||||
CapReadDir apicaps.CapID = "readdir"
|
||||
CapStatFile apicaps.CapID = "statfile"
|
||||
CapImportCaches apicaps.CapID = "importcaches"
|
||||
|
||||
// CapProtoRefArray is a capability to return arrays of refs instead of single
|
||||
// refs. This capability is only for the wire format change and shouldn't be
|
||||
// used in frontends for feature detection.
|
||||
CapProtoRefArray apicaps.CapID = "proto.refarray"
|
||||
|
||||
// CapReferenceOutput is a capability to use a reference of a solved result as
|
||||
// an llb.Output.
|
||||
CapReferenceOutput apicaps.CapID = "reference.output"
|
||||
|
||||
// CapFrontendInputs is a capability to request frontend inputs from the
|
||||
// LLBBridge GRPC server.
|
||||
CapFrontendInputs apicaps.CapID = "frontend.inputs"
|
||||
|
||||
// CapGatewaySolveMetadata can be used to check if solve calls from gateway reliably return metadata
|
||||
CapGatewaySolveMetadata apicaps.CapID = "gateway.solve.metadata"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapSolveBase,
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapSolveInlineReturn,
|
||||
Name: "inline return from solve",
|
||||
Enabled: true,
|
||||
Deprecated: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapResolveImage,
|
||||
Name: "resolve remote image config",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapResolveImageResolveMode,
|
||||
Name: "resolve remote image config with custom resolvemode",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapReadFile,
|
||||
Name: "read static file",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapReturnResult,
|
||||
Name: "return solve result",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapReturnMap,
|
||||
Name: "return reference map",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapReadDir,
|
||||
Name: "read static directory",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapStatFile,
|
||||
Name: "stat a file",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapImportCaches,
|
||||
Name: "import caches",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapProtoRefArray,
|
||||
Name: "wire format ref arrays",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapReferenceOutput,
|
||||
Name: "reference output",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapFrontendInputs,
|
||||
Name: "frontend inputs",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapGatewaySolveMetadata,
|
||||
Name: "gateway metadata",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
}
|
7008
vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.pb.go
generated
vendored
7008
vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
164
vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.proto
generated
vendored
164
vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.proto
generated
vendored
@@ -1,164 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package moby.buildkit.v1.frontend;
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
import "github.com/gogo/googleapis/google/rpc/status.proto";
|
||||
import "github.com/moby/buildkit/solver/pb/ops.proto";
|
||||
import "github.com/moby/buildkit/api/types/worker.proto";
|
||||
import "github.com/moby/buildkit/util/apicaps/pb/caps.proto";
|
||||
import "github.com/tonistiigi/fsutil/types/stat.proto";
|
||||
|
||||
option (gogoproto.sizer_all) = true;
|
||||
option (gogoproto.marshaler_all) = true;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
|
||||
service LLBBridge {
|
||||
// apicaps:CapResolveImage
|
||||
rpc ResolveImageConfig(ResolveImageConfigRequest) returns (ResolveImageConfigResponse);
|
||||
// apicaps:CapSolveBase
|
||||
rpc Solve(SolveRequest) returns (SolveResponse);
|
||||
// apicaps:CapReadFile
|
||||
rpc ReadFile(ReadFileRequest) returns (ReadFileResponse);
|
||||
// apicaps:CapReadDir
|
||||
rpc ReadDir(ReadDirRequest) returns (ReadDirResponse);
|
||||
// apicaps:CapStatFile
|
||||
rpc StatFile(StatFileRequest) returns (StatFileResponse);
|
||||
rpc Ping(PingRequest) returns (PongResponse);
|
||||
rpc Return(ReturnRequest) returns (ReturnResponse);
|
||||
// apicaps:CapFrontendInputs
|
||||
rpc Inputs(InputsRequest) returns (InputsResponse);
|
||||
}
|
||||
|
||||
message Result {
|
||||
oneof result {
|
||||
// Deprecated non-array refs.
|
||||
string refDeprecated = 1;
|
||||
RefMapDeprecated refsDeprecated = 2;
|
||||
|
||||
Ref ref = 3;
|
||||
RefMap refs = 4;
|
||||
}
|
||||
map<string, bytes> metadata = 10;
|
||||
}
|
||||
|
||||
message RefMapDeprecated {
|
||||
map<string, string> refs = 1;
|
||||
}
|
||||
|
||||
message Ref {
|
||||
string id = 1;
|
||||
pb.Definition def = 2;
|
||||
}
|
||||
|
||||
message RefMap {
|
||||
map<string, Ref> refs = 1;
|
||||
}
|
||||
|
||||
message ReturnRequest {
|
||||
Result result = 1;
|
||||
google.rpc.Status error = 2;
|
||||
}
|
||||
|
||||
message ReturnResponse {
|
||||
}
|
||||
|
||||
message InputsRequest {
|
||||
}
|
||||
|
||||
message InputsResponse {
|
||||
map<string, pb.Definition> Definitions = 1;
|
||||
}
|
||||
|
||||
message ResolveImageConfigRequest {
|
||||
string Ref = 1;
|
||||
pb.Platform Platform = 2;
|
||||
string ResolveMode = 3;
|
||||
string LogName = 4;
|
||||
}
|
||||
|
||||
message ResolveImageConfigResponse {
|
||||
string Digest = 1 [(gogoproto.customtype) = "github.com/opencontainers/go-digest.Digest", (gogoproto.nullable) = false];
|
||||
bytes Config = 2;
|
||||
}
|
||||
|
||||
message SolveRequest {
|
||||
pb.Definition Definition = 1;
|
||||
string Frontend = 2;
|
||||
map<string, string> FrontendOpt = 3;
|
||||
// ImportCacheRefsDeprecated is deprecated in favor or the new Imports since BuildKit v0.4.0.
|
||||
// When ImportCacheRefsDeprecated is set, the solver appends
|
||||
// {.Type = "registry", .Attrs = {"ref": importCacheRef}}
|
||||
// for each of the ImportCacheRefs entry to CacheImports for compatibility. (planned to be removed)
|
||||
repeated string ImportCacheRefsDeprecated = 4;
|
||||
bool allowResultReturn = 5;
|
||||
bool allowResultArrayRef = 6;
|
||||
|
||||
// apicaps.CapSolveInlineReturn deprecated
|
||||
bool Final = 10;
|
||||
bytes ExporterAttr = 11;
|
||||
// CacheImports was added in BuildKit v0.4.0.
|
||||
// apicaps:CapImportCaches
|
||||
repeated CacheOptionsEntry CacheImports = 12;
|
||||
|
||||
// apicaps:CapFrontendInputs
|
||||
map<string, pb.Definition> FrontendInputs = 13;
|
||||
}
|
||||
|
||||
// CacheOptionsEntry corresponds to the control.CacheOptionsEntry
|
||||
message CacheOptionsEntry {
|
||||
string Type = 1;
|
||||
map<string, string> Attrs = 2;
|
||||
}
|
||||
|
||||
message SolveResponse {
|
||||
// deprecated
|
||||
string ref = 1; // can be used by readfile request
|
||||
// deprecated
|
||||
/* bytes ExporterAttr = 2;*/
|
||||
|
||||
// these fields are returned when allowMapReturn was set
|
||||
Result result = 3;
|
||||
}
|
||||
|
||||
message ReadFileRequest {
|
||||
string Ref = 1;
|
||||
string FilePath = 2;
|
||||
FileRange Range = 3;
|
||||
}
|
||||
|
||||
message FileRange {
|
||||
int64 Offset = 1;
|
||||
int64 Length = 2;
|
||||
}
|
||||
|
||||
message ReadFileResponse {
|
||||
bytes Data = 1;
|
||||
}
|
||||
|
||||
message ReadDirRequest {
|
||||
string Ref = 1;
|
||||
string DirPath = 2;
|
||||
string IncludePattern = 3;
|
||||
}
|
||||
|
||||
message ReadDirResponse {
|
||||
repeated fsutil.types.Stat entries = 1;
|
||||
}
|
||||
|
||||
message StatFileRequest {
|
||||
string Ref = 1;
|
||||
string Path = 2;
|
||||
}
|
||||
|
||||
message StatFileResponse {
|
||||
fsutil.types.Stat stat = 1;
|
||||
}
|
||||
|
||||
message PingRequest{
|
||||
}
|
||||
message PongResponse{
|
||||
repeated moby.buildkit.v1.apicaps.APICap FrontendAPICaps = 1 [(gogoproto.nullable) = false];
|
||||
repeated moby.buildkit.v1.apicaps.APICap LLBCaps = 2 [(gogoproto.nullable) = false];
|
||||
repeated moby.buildkit.v1.types.WorkerRecord Workers = 3;
|
||||
}
|
3
vendor/github.com/moby/buildkit/frontend/gateway/pb/generate.go
generated
vendored
3
vendor/github.com/moby/buildkit/frontend/gateway/pb/generate.go
generated
vendored
@@ -1,3 +0,0 @@
|
||||
package moby_buildkit_v1_frontend
|
||||
|
||||
//go:generate protoc -I=. -I=../../../vendor/ -I=../../../../../../ --gogo_out=plugins=grpc:. gateway.proto
|
Reference in New Issue
Block a user