llbsolver: validate runtime platforms for exec op

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2018-06-22 17:31:55 -07:00
parent 19612b901f
commit b444b9f323
10 changed files with 65 additions and 13 deletions

View File

@ -37,7 +37,10 @@ type Controller struct { // TODO: ControlService
}
func NewController(opt Opt) (*Controller, error) {
solver := llbsolver.New(opt.WorkerController, opt.Frontends, opt.CacheKeyStorage, opt.CacheImporter)
solver, err := llbsolver.New(opt.WorkerController, opt.Frontends, opt.CacheKeyStorage, opt.CacheImporter)
if err != nil {
return nil, errors.Wrap(err, "failed to create solver")
}
c := &Controller{
opt: opt,

View File

@ -24,7 +24,7 @@ func main() {
bk := buildkit(opt)
out := bk.Run(llb.Shlex("ls -l /bin")) // debug output
dt, err := out.Marshal()
dt, err := out.Marshal(llb.LinuxAmd64)
if err != nil {
panic(err)
}

View File

@ -24,7 +24,7 @@ func main() {
bk := buildkit(opt)
out := bk.Run(llb.Shlex("ls -l /bin")) // debug output
dt, err := out.Marshal()
dt, err := out.Marshal(llb.LinuxAmd64)
if err != nil {
panic(err)
}

View File

@ -24,7 +24,7 @@ func main() {
bk := buildkit(opt)
out := bk.Run(llb.Shlex("ls -l /bin")) // debug output
dt, err := out.Marshal()
dt, err := out.Marshal(llb.LinuxAmd64)
if err != nil {
panic(err)
}

View File

@ -25,7 +25,7 @@ func main() {
bk := buildkit(opt)
out := bk
dt, err := out.Marshal()
dt, err := out.Marshal(llb.LinuxAmd64)
if err != nil {
panic(err)
}

View File

@ -68,7 +68,7 @@ func run() error {
// With(copyAll(*buildkitd, "/")).
With(copyAll(*runc, "/"))
dt, err := sc.Marshal()
dt, err := sc.Marshal(llb.LinuxAmd64)
if err != nil {
panic(err)
}

View File

@ -23,7 +23,7 @@ func main() {
built := pb.With(llbbuild.Build())
dt, err := llb.Image("docker.io/library/alpine:latest").Run(llb.Shlex("ls -l /out"), llb.AddMount("/out", built, llb.Readonly)).Marshal()
dt, err := llb.Image("docker.io/library/alpine:latest").Run(llb.Shlex("ls -l /out"), llb.AddMount("/out", built, llb.Readonly)).Marshal(llb.LinuxAmd64)
if err != nil {
panic(err)
}

View File

@ -15,6 +15,7 @@ import (
"github.com/moby/buildkit/util/tracing"
"github.com/moby/buildkit/worker"
digest "github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@ -25,6 +26,7 @@ type llbBridge struct {
ci *remotecache.CacheImporter
cms map[string]solver.CacheManager
cmsMu sync.Mutex
platforms []specs.Platform
}
func (b *llbBridge) Solve(ctx context.Context, req frontend.SolveRequest) (res solver.CachedResult, exp map[string][]byte, err error) {
@ -59,7 +61,7 @@ func (b *llbBridge) Solve(ctx context.Context, req frontend.SolveRequest) (res s
}
if req.Definition != nil && req.Definition.Def != nil {
edge, err := Load(req.Definition, WithCacheSources(cms))
edge, err := Load(req.Definition, WithCacheSources(cms), RuntimePlatforms(b.platforms))
if err != nil {
return nil, nil, err
}

View File

@ -13,6 +13,7 @@ import (
"github.com/moby/buildkit/solver"
"github.com/moby/buildkit/util/progress"
"github.com/moby/buildkit/worker"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@ -30,9 +31,10 @@ type Solver struct {
resolveWorker ResolveWorkerFunc
frontends map[string]frontend.Frontend
ci *remotecache.CacheImporter
platforms []specs.Platform
}
func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solver.CacheKeyStorage, ci *remotecache.CacheImporter) *Solver {
func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solver.CacheKeyStorage, ci *remotecache.CacheImporter) (*Solver, error) {
s := &Solver{
resolveWorker: defaultResolver(wc),
frontends: f,
@ -43,11 +45,18 @@ func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solve
cache := solver.NewCacheManager("local", cacheStore, results)
// executing is currently only allowed on default worker
w, err := wc.GetDefault()
if err != nil {
return nil, err
}
s.platforms = w.Platforms()
s.solver = solver.NewSolver(solver.SolverOpt{
ResolveOpFunc: s.resolver(),
DefaultCache: cache,
})
return s
return s, nil
}
func (s *Solver) resolver() solver.ResolveOpFunc {
@ -67,6 +76,7 @@ func (s *Solver) Bridge(b solver.Builder) frontend.FrontendLLBBridge {
resolveWorker: s.resolveWorker,
ci: s.ci,
cms: map[string]solver.CacheManager{},
platforms: s.platforms,
}
}

View File

@ -3,10 +3,12 @@ package llbsolver
import (
"strings"
"github.com/containerd/containerd/platforms"
"github.com/moby/buildkit/solver"
"github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/source"
digest "github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@ -38,11 +40,44 @@ func (v *vertex) Name() string {
return v.name
}
type LoadOpt func(*solver.VertexOptions)
type LoadOpt func(*pb.Op, *pb.OpMetadata, *solver.VertexOptions) error
func WithCacheSources(cms []solver.CacheManager) LoadOpt {
return func(opt *solver.VertexOptions) {
return func(_ *pb.Op, _ *pb.OpMetadata, opt *solver.VertexOptions) error {
opt.CacheSources = cms
return nil
}
}
func RuntimePlatforms(p []specs.Platform) LoadOpt {
var defaultPlatform *pb.Platform
for i := range p {
p[i] = platforms.Normalize(p[i])
}
return func(op *pb.Op, _ *pb.OpMetadata, opt *solver.VertexOptions) error {
if op.Platform == nil {
if defaultPlatform == nil {
p := platforms.DefaultSpec()
defaultPlatform = &pb.Platform{
OS: p.OS,
Architecture: p.Architecture,
}
}
op.Platform = defaultPlatform
}
if _, ok := op.Op.(*pb.Op_Exec); ok {
var found bool
for _, pp := range p {
if pp.OS == op.Platform.OS && pp.Architecture == op.Platform.Architecture && pp.Variant == op.Platform.Variant {
found = true
break
}
}
if !found {
return errors.Errorf("runtime execution on platform %s not supported", platforms.Format(specs.Platform{OS: op.Platform.OS, Architecture: op.Platform.Architecture, Variant: op.Platform.Variant}))
}
}
return nil
}
}
@ -67,7 +102,9 @@ func newVertex(dgst digest.Digest, op *pb.Op, opMeta *pb.OpMetadata, load func(d
}
}
for _, fn := range opts {
fn(&opt)
if err := fn(op, opMeta, &opt); err != nil {
return nil, err
}
}
vtx := &vertex{sys: op, options: opt, digest: dgst, name: llbOpName(op)}
for _, in := range op.Inputs {