| package llb |
| |
| import ( |
| "io" |
| "io/ioutil" |
| |
| "github.com/containerd/containerd/platforms" |
| "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 |
| Metadata map[digest.Digest]pb.OpMetadata |
| } |
| |
| func (def *Definition) ToPB() *pb.Definition { |
| md := make(map[digest.Digest]pb.OpMetadata) |
| 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 |
| def.Metadata = make(map[digest.Digest]pb.OpMetadata) |
| 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 |
| } |
| |
| 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 |
| } |