solver: simplify solver public api
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>docker-18.09
parent
7d0fea5b60
commit
23a114a977
|
@ -45,6 +45,7 @@ func NewController(opt Opt) (*Controller, error) {
|
|||
Worker: opt.Worker,
|
||||
InstructionCache: opt.InstructionCache,
|
||||
ImageSource: opt.ImageSource,
|
||||
Frontends: opt.Frontends,
|
||||
}),
|
||||
}
|
||||
return c, nil
|
||||
|
@ -105,7 +106,12 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*
|
|||
}
|
||||
}
|
||||
|
||||
if err := c.solver.Solve(ctx, req.Ref, frontend, req.Definition, expi, req.FrontendAttrs, c.opt.Frontends); err != nil {
|
||||
if err := c.solver.Solve(ctx, req.Ref, solver.SolveRequest{
|
||||
Frontend: frontend,
|
||||
Definition: req.Definition,
|
||||
Exporter: expi,
|
||||
FrontendOpt: req.FrontendAttrs,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &controlapi.SolveResponse{}, nil
|
||||
|
|
|
@ -53,7 +53,9 @@ func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBr
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
ref, _, err := llbBridge.Solve(ctx, def.ToPB(), "", nil)
|
||||
ref, _, err := llbBridge.Solve(ctx, frontend.SolveRequest{
|
||||
Definition: def.ToPB(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -112,7 +114,9 @@ func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBr
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
retRef, _, err = llbBridge.Solve(ctx, def.ToPB(), "", nil)
|
||||
retRef, _, err = llbBridge.Solve(ctx, frontend.SolveRequest{
|
||||
Definition: def.ToPB(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
@ -15,7 +15,13 @@ type Frontend interface {
|
|||
}
|
||||
|
||||
type FrontendLLBBridge interface {
|
||||
Solve(ctx context.Context, def *pb.Definition, frontend string, opts map[string]string) (cache.ImmutableRef, map[string][]byte, error)
|
||||
Solve(ctx context.Context, req SolveRequest) (cache.ImmutableRef, map[string][]byte, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
|
||||
Exec(ctx context.Context, meta worker.Meta, rootfs cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error
|
||||
}
|
||||
|
||||
type SolveRequest struct {
|
||||
Definition *pb.Definition
|
||||
Frontend string
|
||||
FrontendOpt map[string]string
|
||||
}
|
||||
|
|
|
@ -67,7 +67,11 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
|||
var rootFS cache.ImmutableRef
|
||||
|
||||
if isDevel {
|
||||
ref, exp, err := llbBridge.Solve(session.NewContext(ctx, "gateway:"+sid), nil, source, filterPrefix(opts, "gateway-"))
|
||||
ref, exp, err := llbBridge.Solve(session.NewContext(ctx, "gateway:"+sid),
|
||||
frontend.SolveRequest{
|
||||
Frontend: source,
|
||||
FrontendOpt: filterPrefix(opts, "gateway-"),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -105,7 +109,9 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
ref, _, err := llbBridge.Solve(ctx, def.ToPB(), "", nil)
|
||||
ref, _, err := llbBridge.Solve(ctx, frontend.SolveRequest{
|
||||
Definition: def.ToPB(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -240,7 +246,10 @@ func (lbf *llbBrideForwarder) ResolveImageConfig(ctx context.Context, req *pb.Re
|
|||
}
|
||||
|
||||
func (lbf *llbBrideForwarder) Solve(ctx context.Context, req *pb.SolveRequest) (*pb.SolveResponse, error) {
|
||||
ref, expResp, err := lbf.llbBridge.Solve(ctx, req.Definition, req.Frontend, nil)
|
||||
ref, expResp, err := lbf.llbBridge.Solve(ctx, frontend.SolveRequest{
|
||||
Definition: req.Definition,
|
||||
Frontend: req.Frontend,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
121
solver/solver.go
121
solver/solver.go
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/exporter"
|
||||
"github.com/moby/buildkit/frontend"
|
||||
"github.com/moby/buildkit/identity"
|
||||
"github.com/moby/buildkit/solver/pb"
|
||||
"github.com/moby/buildkit/source"
|
||||
"github.com/moby/buildkit/util/bgfunc"
|
||||
|
@ -26,10 +25,11 @@ import (
|
|||
|
||||
type LLBOpt struct {
|
||||
SourceManager *source.Manager
|
||||
CacheManager cache.Manager // TODO: this shouldn't be needed before instruction cache
|
||||
CacheManager cache.Manager
|
||||
Worker worker.Worker
|
||||
InstructionCache InstructionCache
|
||||
ImageSource source.Source
|
||||
Frontends map[string]frontend.Frontend // used by nested invocations
|
||||
}
|
||||
|
||||
func NewLLBSolver(opt LLBOpt) *Solver {
|
||||
|
@ -45,7 +45,7 @@ func NewLLBSolver(opt LLBOpt) *Solver {
|
|||
default:
|
||||
return nil, nil
|
||||
}
|
||||
}, opt.InstructionCache, opt.ImageSource, opt.Worker, opt.CacheManager)
|
||||
}, opt.InstructionCache, opt.ImageSource, opt.Worker, opt.CacheManager, opt.Frontends)
|
||||
return s
|
||||
}
|
||||
|
||||
|
@ -79,46 +79,55 @@ type Solver struct {
|
|||
imageSource source.Source
|
||||
worker worker.Worker
|
||||
cm cache.Manager // TODO: remove with immutableRef.New()
|
||||
frontends map[string]frontend.Frontend
|
||||
}
|
||||
|
||||
func New(resolve ResolveOpFunc, cache InstructionCache, imageSource source.Source, worker worker.Worker, cm cache.Manager) *Solver {
|
||||
return &Solver{resolve: resolve, jobs: newJobList(), cache: cache, imageSource: imageSource, worker: worker, cm: cm}
|
||||
func New(resolve ResolveOpFunc, cache InstructionCache, imageSource source.Source, worker worker.Worker, cm cache.Manager, f map[string]frontend.Frontend) *Solver {
|
||||
return &Solver{resolve: resolve, jobs: newJobList(), cache: cache, imageSource: imageSource, worker: worker, cm: cm, frontends: f}
|
||||
}
|
||||
|
||||
func (s *Solver) Solve(ctx context.Context, id string, f frontend.Frontend, def *pb.Definition, exp exporter.ExporterInstance, frontendOpt map[string]string, allFrontends map[string]frontend.Frontend) error {
|
||||
type SolveRequest struct {
|
||||
Definition *pb.Definition
|
||||
Frontend frontend.Frontend
|
||||
Exporter exporter.ExporterInstance
|
||||
FrontendOpt map[string]string
|
||||
}
|
||||
|
||||
func (s *Solver) solve(ctx context.Context, j *job, req SolveRequest) (Reference, map[string][]byte, error) {
|
||||
if req.Definition == nil {
|
||||
if req.Frontend == nil {
|
||||
return nil, nil, errors.Errorf("invalid request: no definition nor frontend")
|
||||
}
|
||||
return req.Frontend.Solve(ctx, s.llbBridge(j), req.FrontendOpt)
|
||||
}
|
||||
|
||||
inp, err := j.load(req.Definition, s.resolve)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ref, err := j.getRef(ctx, inp.Vertex.(*vertex), inp.Index)
|
||||
return ref, nil, err
|
||||
}
|
||||
|
||||
func (s *Solver) llbBridge(j *job) *llbBridge {
|
||||
return &llbBridge{job: j, Solver: s, resolveImageConfig: s.imageSource.(resolveImageConfig)}
|
||||
}
|
||||
|
||||
func (s *Solver) Solve(ctx context.Context, id string, req SolveRequest) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
pr, ctx, closeProgressWriter := progress.NewContext(ctx)
|
||||
|
||||
defer closeProgressWriter()
|
||||
|
||||
// register a build job. vertex needs to be loaded to a job to run
|
||||
ctx, j, err := s.jobs.new(ctx, id, pr, s.cache)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ref Reference
|
||||
var exporterOpt map[string][]byte
|
||||
if def != nil {
|
||||
var inp *Input
|
||||
inp, err = j.load(def, s.resolve)
|
||||
if err != nil {
|
||||
j.discard()
|
||||
return err
|
||||
}
|
||||
ref, err = j.getRef(ctx, inp.Vertex.(*vertex), inp.Index)
|
||||
} else {
|
||||
ref, exporterOpt, err = f.Solve(ctx, &llbBridge{
|
||||
worker: s.worker,
|
||||
job: j,
|
||||
cm: s.cm,
|
||||
resolveOp: s.resolve,
|
||||
resolveImageConfig: s.imageSource.(resolveImageConfig),
|
||||
allFrontends: allFrontends,
|
||||
}, frontendOpt)
|
||||
}
|
||||
j.discard()
|
||||
ref, exporterOpt, err := s.solve(ctx, j, req)
|
||||
defer j.discard()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -135,19 +144,10 @@ func (s *Solver) Solve(ctx context.Context, id string, f frontend.Frontend, def
|
|||
return err
|
||||
}
|
||||
|
||||
if exp != nil {
|
||||
v := client.Vertex{
|
||||
Digest: digest.FromBytes([]byte(identity.NewID())),
|
||||
Name: exp.Name(),
|
||||
}
|
||||
notifyStarted(ctx, &v)
|
||||
pw, _, ctx := progress.FromContext(ctx, progress.WithMetadata("vertex", v.Digest))
|
||||
defer pw.Close()
|
||||
err := exp.Export(ctx, immutable, exporterOpt)
|
||||
notifyCompleted(ctx, &v, err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exp := req.Exporter; exp != nil {
|
||||
return inVertexContext(ctx, exp.Name(), func(ctx context.Context) error {
|
||||
return exp.Export(ctx, immutable, exporterOpt)
|
||||
})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -571,39 +571,29 @@ type VertexResult struct {
|
|||
|
||||
// llbBridge is an helper used by frontends
|
||||
type llbBridge struct {
|
||||
*Solver
|
||||
job *job
|
||||
resolveImageConfig
|
||||
job *job
|
||||
resolveOp ResolveOpFunc
|
||||
worker worker.Worker
|
||||
allFrontends map[string]frontend.Frontend
|
||||
cm cache.Manager
|
||||
}
|
||||
|
||||
type resolveImageConfig interface {
|
||||
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
|
||||
}
|
||||
|
||||
func (s *llbBridge) Solve(ctx context.Context, def *pb.Definition, frontend string, opts map[string]string) (cache.ImmutableRef, map[string][]byte, error) {
|
||||
if def == nil {
|
||||
f, ok := s.allFrontends[frontend]
|
||||
func (s *llbBridge) Solve(ctx context.Context, req frontend.SolveRequest) (cache.ImmutableRef, map[string][]byte, error) {
|
||||
var f frontend.Frontend
|
||||
if req.Frontend != "" {
|
||||
var ok bool
|
||||
f, ok = s.frontends[req.Frontend]
|
||||
if !ok {
|
||||
return nil, nil, errors.Errorf("invalid frontend: %s", frontend)
|
||||
return nil, nil, errors.Errorf("invalid frontend: %s", req.Frontend)
|
||||
}
|
||||
ref, exporterOpt, err := f.Solve(ctx, s, opts)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
immutable, ok := toImmutableRef(ref)
|
||||
if !ok {
|
||||
return nil, nil, errors.Errorf("invalid reference for exporting: %T", ref)
|
||||
}
|
||||
return immutable, exporterOpt, nil
|
||||
}
|
||||
inp, err := s.job.load(def, s.resolveOp)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ref, err := s.job.getRef(ctx, inp.Vertex.(*vertex), inp.Index)
|
||||
ref, exp, err := s.solve(ctx, s.job, SolveRequest{
|
||||
Definition: req.Definition,
|
||||
Frontend: f,
|
||||
FrontendOpt: req.FrontendOpt,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -611,8 +601,7 @@ func (s *llbBridge) Solve(ctx context.Context, def *pb.Definition, frontend stri
|
|||
if !ok {
|
||||
return nil, nil, errors.Errorf("invalid reference for exporting: %T", ref)
|
||||
}
|
||||
|
||||
return immutable, nil, nil
|
||||
return immutable, exp, nil
|
||||
}
|
||||
|
||||
func (s *llbBridge) Exec(ctx context.Context, meta worker.Meta, rootFS cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error {
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package solver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/identity"
|
||||
"github.com/moby/buildkit/util/progress"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Vertex is one node in the build graph
|
||||
|
@ -112,3 +113,16 @@ func notifyCompleted(ctx context.Context, v *client.Vertex, err error) {
|
|||
}
|
||||
pw.Write(v.Digest.String(), *v)
|
||||
}
|
||||
|
||||
func inVertexContext(ctx context.Context, name string, f func(ctx context.Context) error) error {
|
||||
v := client.Vertex{
|
||||
Digest: digest.FromBytes([]byte(identity.NewID())),
|
||||
Name: name,
|
||||
}
|
||||
pw, _, ctx := progress.FromContext(ctx, progress.WithMetadata("vertex", v.Digest))
|
||||
notifyStarted(ctx, &v)
|
||||
defer pw.Close()
|
||||
err := f(ctx)
|
||||
notifyCompleted(ctx, &v, err)
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue