gateway: allow access to current frontend definition
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>master
parent
0ad26d49f2
commit
0364e00aac
|
@ -7,12 +7,15 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
|
"github.com/docker/docker/pkg/idtools"
|
||||||
"github.com/gogo/googleapis/google/rpc"
|
"github.com/gogo/googleapis/google/rpc"
|
||||||
gogotypes "github.com/gogo/protobuf/types"
|
gogotypes "github.com/gogo/protobuf/types"
|
||||||
"github.com/golang/protobuf/ptypes/any"
|
"github.com/golang/protobuf/ptypes/any"
|
||||||
|
@ -28,6 +31,7 @@ import (
|
||||||
pb "github.com/moby/buildkit/frontend/gateway/pb"
|
pb "github.com/moby/buildkit/frontend/gateway/pb"
|
||||||
"github.com/moby/buildkit/identity"
|
"github.com/moby/buildkit/identity"
|
||||||
"github.com/moby/buildkit/session"
|
"github.com/moby/buildkit/session"
|
||||||
|
"github.com/moby/buildkit/snapshot"
|
||||||
"github.com/moby/buildkit/solver"
|
"github.com/moby/buildkit/solver"
|
||||||
"github.com/moby/buildkit/solver/errdefs"
|
"github.com/moby/buildkit/solver/errdefs"
|
||||||
llberrdefs "github.com/moby/buildkit/solver/llbsolver/errdefs"
|
llberrdefs "github.com/moby/buildkit/solver/llbsolver/errdefs"
|
||||||
|
@ -88,6 +92,8 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
||||||
var rootFS cache.MutableRef
|
var rootFS cache.MutableRef
|
||||||
var readonly bool // TODO: try to switch to read-only by default.
|
var readonly bool // TODO: try to switch to read-only by default.
|
||||||
|
|
||||||
|
var frontendDef *opspb.Definition
|
||||||
|
|
||||||
if isDevel {
|
if isDevel {
|
||||||
devRes, err := llbBridge.Solve(ctx,
|
devRes, err := llbBridge.Solve(ctx,
|
||||||
frontend.SolveRequest{
|
frontend.SolveRequest{
|
||||||
|
@ -106,10 +112,12 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
||||||
if devRes.Ref == nil {
|
if devRes.Ref == nil {
|
||||||
return nil, errors.Errorf("development gateway didn't return default result")
|
return nil, errors.Errorf("development gateway didn't return default result")
|
||||||
}
|
}
|
||||||
|
frontendDef = devRes.Ref.Definition()
|
||||||
res, err := devRes.Ref.Result(ctx)
|
res, err := devRes.Ref.Result(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
workerRef, ok := res.Sys().(*worker.WorkerRef)
|
workerRef, ok := res.Sys().(*worker.WorkerRef)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("invalid ref: %T", res.Sys())
|
return nil, errors.Errorf("invalid ref: %T", res.Sys())
|
||||||
|
@ -171,6 +179,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
||||||
return nil, errors.Errorf("gateway source didn't return default result")
|
return nil, errors.Errorf("gateway source didn't return default result")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
frontendDef = res.Ref.Definition()
|
||||||
r, err := res.Ref.Result(ctx)
|
r, err := res.Ref.Result(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -252,7 +261,19 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w.Executor().Run(ctx, "", mountWithSession(rootFS, session.NewGroup(sid)), nil, executor.ProcessInfo{Meta: meta, Stdin: lbf.Stdin, Stdout: lbf.Stdout, Stderr: os.Stderr}, nil)
|
mdmnt, release, err := metadataMount(frontendDef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if release != nil {
|
||||||
|
defer release()
|
||||||
|
}
|
||||||
|
var mnts []executor.Mount
|
||||||
|
if mdmnt != nil {
|
||||||
|
mnts = append(mnts, *mdmnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.Executor().Run(ctx, "", mountWithSession(rootFS, session.NewGroup(sid)), mnts, executor.ProcessInfo{Meta: meta, Stdin: lbf.Stdin, Stdout: lbf.Stdout, Stderr: os.Stderr}, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errdefs.IsCanceled(err) && lbf.isErrServerClosed {
|
if errdefs.IsCanceled(err) && lbf.isErrServerClosed {
|
||||||
|
@ -272,6 +293,53 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
||||||
return lbf.Result()
|
return lbf.Result()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func metadataMount(def *opspb.Definition) (*executor.Mount, func(), error) {
|
||||||
|
dt, err := def.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
dir, err := os.MkdirTemp("", "buildkit-metadata")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile(filepath.Join(dir, "frontend.bin"), dt, 0400); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &executor.Mount{
|
||||||
|
Src: &bind{dir},
|
||||||
|
Dest: "/run/config/buildkit/metadata",
|
||||||
|
Readonly: true,
|
||||||
|
}, func() {
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type bind struct {
|
||||||
|
dir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *bind) Mount(ctx context.Context, readonly bool) (snapshot.Mountable, error) {
|
||||||
|
return &bindMount{b.dir, readonly}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type bindMount struct {
|
||||||
|
dir string
|
||||||
|
readonly bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *bindMount) Mount() ([]mount.Mount, func() error, error) {
|
||||||
|
return []mount.Mount{{
|
||||||
|
Type: "bind",
|
||||||
|
Source: b.dir,
|
||||||
|
Options: []string{"bind", "ro"},
|
||||||
|
}}, func() error { return nil }, nil
|
||||||
|
}
|
||||||
|
func (b *bindMount) IdentityMapping() *idtools.IdentityMapping {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (lbf *llbBridgeForwarder) Discard() {
|
func (lbf *llbBridgeForwarder) Discard() {
|
||||||
lbf.mu.Lock()
|
lbf.mu.Lock()
|
||||||
defer lbf.mu.Unlock()
|
defer lbf.mu.Unlock()
|
||||||
|
|
|
@ -457,6 +457,27 @@ func (c *grpcClient) BuildOpts() client.BuildOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *grpcClient) CurrentFrontend() (*llb.State, error) {
|
||||||
|
fp := "/run/config/buildkit/metadata/frontend.bin"
|
||||||
|
if _, err := os.Stat(fp); err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
dt, err := os.ReadFile(fp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var def opspb.Definition
|
||||||
|
if err := def.Unmarshal(dt); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
op, err := llb.NewDefinitionOp(&def)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
st := llb.NewState(op)
|
||||||
|
return &st, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *grpcClient) Inputs(ctx context.Context) (map[string]llb.State, error) {
|
func (c *grpcClient) Inputs(ctx context.Context) (map[string]llb.State, error) {
|
||||||
err := c.caps.Supports(pb.CapFrontendInputs)
|
err := c.caps.Supports(pb.CapFrontendInputs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue