Merge pull request #1049 from tonistiigi/llb-validation
llbsolver: add more llb validationdocker-19.03
commit
fe8289063b
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/moby/buildkit/frontend"
|
||||
"github.com/moby/buildkit/snapshot"
|
||||
"github.com/moby/buildkit/solver"
|
||||
"github.com/moby/buildkit/solver/llbsolver"
|
||||
"github.com/moby/buildkit/solver/pb"
|
||||
"github.com/moby/buildkit/worker"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
|
@ -25,6 +26,9 @@ type buildOp struct {
|
|||
}
|
||||
|
||||
func NewBuildOp(v solver.Vertex, op *pb.Op_Build, b frontend.FrontendLLBBridge, _ worker.Worker) (solver.Op, error) {
|
||||
if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &buildOp{
|
||||
op: op.Build,
|
||||
b: b,
|
||||
|
|
|
@ -60,6 +60,9 @@ type execOp struct {
|
|||
}
|
||||
|
||||
func NewExecOp(v solver.Vertex, op *pb.Op_Exec, platform *pb.Platform, cm cache.Manager, sm *session.Manager, md *metadata.Store, exec executor.Executor, w worker.Worker) (solver.Op, error) {
|
||||
if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &execOp{
|
||||
op: op.Exec,
|
||||
cm: cm,
|
||||
|
|
|
@ -35,6 +35,9 @@ type fileOp struct {
|
|||
}
|
||||
|
||||
func NewFileOp(v solver.Vertex, op *pb.Op_File, cm cache.Manager, md *metadata.Store, w worker.Worker) (solver.Op, error) {
|
||||
if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &fileOp{
|
||||
op: op.File,
|
||||
md: md,
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/solver"
|
||||
"github.com/moby/buildkit/solver/llbsolver"
|
||||
"github.com/moby/buildkit/solver/pb"
|
||||
"github.com/moby/buildkit/source"
|
||||
"github.com/moby/buildkit/worker"
|
||||
|
@ -26,6 +27,9 @@ type sourceOp struct {
|
|||
}
|
||||
|
||||
func NewSourceOp(_ solver.Vertex, op *pb.Op_Source, platform *pb.Platform, sm *source.Manager, sessM *session.Manager, w worker.Worker) (solver.Op, error) {
|
||||
if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sourceOp{
|
||||
op: op,
|
||||
sm: sm,
|
||||
|
|
|
@ -188,8 +188,15 @@ func loadLLB(def *pb.Definition, fn func(digest.Digest, *pb.Op, func(digest.Dige
|
|||
allOps[dgst] = &op
|
||||
}
|
||||
|
||||
if len(allOps) < 2 {
|
||||
return solver.Edge{}, errors.Errorf("invalid LLB with %d vertexes", len(allOps))
|
||||
}
|
||||
|
||||
lastOp := allOps[dgst]
|
||||
delete(allOps, dgst)
|
||||
if len(lastOp.Inputs) == 0 {
|
||||
return solver.Edge{}, errors.Errorf("invalid LLB with no inputs on last vertex")
|
||||
}
|
||||
dgst = lastOp.Inputs[0].Digest
|
||||
|
||||
cache := make(map[digest.Digest]solver.Vertex)
|
||||
|
@ -203,6 +210,11 @@ func loadLLB(def *pb.Definition, fn func(digest.Digest, *pb.Op, func(digest.Dige
|
|||
if !ok {
|
||||
return nil, errors.Errorf("invalid missing input digest %s", dgst)
|
||||
}
|
||||
|
||||
if err := ValidateOp(op); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v, err := fn(dgst, op, rec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -240,6 +252,55 @@ func llbOpName(op *pb.Op) string {
|
|||
}
|
||||
}
|
||||
|
||||
func ValidateOp(op *pb.Op) error {
|
||||
if op == nil {
|
||||
return errors.Errorf("invalid nil op")
|
||||
}
|
||||
|
||||
switch op := op.Op.(type) {
|
||||
case *pb.Op_Source:
|
||||
if op.Source == nil {
|
||||
return errors.Errorf("invalid nil source op")
|
||||
}
|
||||
case *pb.Op_Exec:
|
||||
if op.Exec == nil {
|
||||
return errors.Errorf("invalid nil exec op")
|
||||
}
|
||||
if op.Exec.Meta == nil {
|
||||
return errors.Errorf("invalid exec op with no meta")
|
||||
}
|
||||
if len(op.Exec.Meta.Args) == 0 {
|
||||
return errors.Errorf("invalid exec op with no args")
|
||||
}
|
||||
if len(op.Exec.Mounts) == 0 {
|
||||
return errors.Errorf("invalid exec op with no mounts")
|
||||
}
|
||||
|
||||
isRoot := false
|
||||
for _, m := range op.Exec.Mounts {
|
||||
if m.Dest == pb.RootMount {
|
||||
isRoot = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isRoot {
|
||||
return errors.Errorf("invalid exec op with no rootfs")
|
||||
}
|
||||
case *pb.Op_File:
|
||||
if op.File == nil {
|
||||
return errors.Errorf("invalid nil file op")
|
||||
}
|
||||
if len(op.File.Actions) == 0 {
|
||||
return errors.Errorf("invalid file op with no actions")
|
||||
}
|
||||
case *pb.Op_Build:
|
||||
if op.Build == nil {
|
||||
return errors.Errorf("invalid nil build op")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fileOpName(actions []*pb.FileAction) string {
|
||||
names := make([]string, 0, len(actions))
|
||||
for _, action := range actions {
|
||||
|
|
Loading…
Reference in New Issue