2018-04-19 13:07:27 -04:00
|
|
|
package llb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
|
2018-06-29 11:17:00 -04:00
|
|
|
"github.com/containerd/containerd/platforms"
|
2018-04-19 13:07:27 -04:00
|
|
|
"github.com/moby/buildkit/solver/pb"
|
|
|
|
digest "github.com/opencontainers/go-digest"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Definition is the LLB definition structure with per-vertex metadata entries
|
|
|
|
// Corresponds to the Definition structure defined in solver/pb.Definition.
|
|
|
|
type Definition struct {
|
|
|
|
Def [][]byte
|
2018-06-29 11:17:00 -04:00
|
|
|
Metadata map[digest.Digest]pb.OpMetadata
|
2018-04-19 13:07:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (def *Definition) ToPB() *pb.Definition {
|
2018-06-29 11:17:00 -04:00
|
|
|
md := make(map[digest.Digest]pb.OpMetadata)
|
2018-04-19 13:07:27 -04:00
|
|
|
for k, v := range def.Metadata {
|
|
|
|
md[k] = v
|
|
|
|
}
|
|
|
|
return &pb.Definition{
|
|
|
|
Def: def.Def,
|
|
|
|
Metadata: md,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (def *Definition) FromPB(x *pb.Definition) {
|
|
|
|
def.Def = x.Def
|
2018-06-29 11:17:00 -04:00
|
|
|
def.Metadata = make(map[digest.Digest]pb.OpMetadata)
|
2018-04-19 13:07:27 -04:00
|
|
|
for k, v := range x.Metadata {
|
|
|
|
def.Metadata[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func WriteTo(def *Definition, w io.Writer) error {
|
|
|
|
b, err := def.ToPB().Marshal()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
_, err = w.Write(b)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func ReadFrom(r io.Reader) (*Definition, error) {
|
|
|
|
b, err := ioutil.ReadAll(r)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var pbDef pb.Definition
|
|
|
|
if err := pbDef.Unmarshal(b); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var def Definition
|
|
|
|
def.FromPB(&pbDef)
|
|
|
|
return &def, nil
|
|
|
|
}
|
2018-06-29 11:17:00 -04:00
|
|
|
|
|
|
|
func MarshalConstraints(base, override *Constraints) (*pb.Op, *pb.OpMetadata) {
|
|
|
|
c := *base
|
|
|
|
c.WorkerConstraints = append([]string{}, c.WorkerConstraints...)
|
|
|
|
|
|
|
|
if p := override.Platform; p != nil {
|
|
|
|
c.Platform = p
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, wc := range override.WorkerConstraints {
|
|
|
|
c.WorkerConstraints = append(c.WorkerConstraints, wc)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Metadata = mergeMetadata(c.Metadata, override.Metadata)
|
|
|
|
|
|
|
|
if c.Platform == nil {
|
|
|
|
defaultPlatform := platforms.Normalize(platforms.DefaultSpec())
|
|
|
|
c.Platform = &defaultPlatform
|
|
|
|
}
|
|
|
|
|
|
|
|
return &pb.Op{
|
|
|
|
Platform: &pb.Platform{
|
|
|
|
OS: c.Platform.OS,
|
|
|
|
Architecture: c.Platform.Architecture,
|
|
|
|
Variant: c.Platform.Variant,
|
|
|
|
OSVersion: c.Platform.OSVersion,
|
|
|
|
OSFeatures: c.Platform.OSFeatures,
|
|
|
|
},
|
|
|
|
Constraints: &pb.WorkerConstraints{
|
|
|
|
Filter: c.WorkerConstraints,
|
|
|
|
},
|
|
|
|
}, &c.Metadata
|
|
|
|
}
|
|
|
|
|
|
|
|
type MarshalCache struct {
|
|
|
|
digest digest.Digest
|
|
|
|
dt []byte
|
|
|
|
md *pb.OpMetadata
|
|
|
|
constraints *Constraints
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mc *MarshalCache) Cached(c *Constraints) bool {
|
|
|
|
return mc.dt != nil && mc.constraints == c
|
|
|
|
}
|
|
|
|
func (mc *MarshalCache) Load() (digest.Digest, []byte, *pb.OpMetadata, error) {
|
|
|
|
return mc.digest, mc.dt, mc.md, nil
|
|
|
|
}
|
|
|
|
func (mc *MarshalCache) Store(dt []byte, md *pb.OpMetadata, c *Constraints) {
|
|
|
|
mc.digest = digest.FromBytes(dt)
|
|
|
|
mc.dt = dt
|
|
|
|
mc.md = md
|
|
|
|
mc.constraints = c
|
|
|
|
}
|