mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 09:17:49 +08:00

Integrates vtproto into buildx. The generated files dockerfile has been modified to copy the buildkit equivalent file to ensure files are laid out in the appropriate way for imports. An import has also been included to change the grpc codec to the version in buildkit that supports vtproto. This will allow buildx to utilize the speed and memory improvements from that. Also updates the gc control options for prune. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
154 lines
3.6 KiB
Go
154 lines
3.6 KiB
Go
package llb
|
|
|
|
import (
|
|
"io"
|
|
"sync"
|
|
|
|
cerrdefs "github.com/containerd/errdefs"
|
|
"github.com/containerd/platforms"
|
|
"github.com/moby/buildkit/solver/pb"
|
|
digest "github.com/opencontainers/go-digest"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
// 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]OpMetadata
|
|
Source *pb.Source
|
|
Constraints *Constraints
|
|
}
|
|
|
|
func (def *Definition) ToPB() *pb.Definition {
|
|
metas := make(map[string]*pb.OpMetadata, len(def.Metadata))
|
|
for dgst, meta := range def.Metadata {
|
|
metas[string(dgst)] = meta.ToPB()
|
|
}
|
|
return &pb.Definition{
|
|
Def: def.Def,
|
|
Source: def.Source,
|
|
Metadata: metas,
|
|
}
|
|
}
|
|
|
|
func (def *Definition) FromPB(x *pb.Definition) {
|
|
def.Def = x.Def
|
|
def.Source = x.Source
|
|
def.Metadata = make(map[digest.Digest]OpMetadata, len(x.Metadata))
|
|
for dgst, meta := range x.Metadata {
|
|
def.Metadata[digest.Digest(dgst)] = NewOpMetadata(meta)
|
|
}
|
|
}
|
|
|
|
func (def *Definition) Head() (digest.Digest, error) {
|
|
if len(def.Def) == 0 {
|
|
return "", nil
|
|
}
|
|
|
|
last := def.Def[len(def.Def)-1]
|
|
|
|
var pop pb.Op
|
|
if err := pop.UnmarshalVT(last); err != nil {
|
|
return "", err
|
|
}
|
|
if len(pop.Inputs) == 0 {
|
|
return "", nil
|
|
}
|
|
|
|
return digest.Digest(pop.Inputs[0].Digest), nil
|
|
}
|
|
|
|
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 := io.ReadAll(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var pbDef pb.Definition
|
|
if err := pbDef.UnmarshalVT(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
|
|
}
|
|
|
|
c.WorkerConstraints = append(c.WorkerConstraints, override.WorkerConstraints...)
|
|
c.Metadata = mergeMetadata(c.Metadata, override.Metadata)
|
|
|
|
if c.Platform == nil {
|
|
defaultPlatform := platforms.Normalize(platforms.DefaultSpec())
|
|
c.Platform = &defaultPlatform
|
|
}
|
|
|
|
opPlatform := pb.Platform{
|
|
OS: c.Platform.OS,
|
|
Architecture: c.Platform.Architecture,
|
|
Variant: c.Platform.Variant,
|
|
OSVersion: c.Platform.OSVersion,
|
|
}
|
|
if c.Platform.OSFeatures != nil {
|
|
opPlatform.OSFeatures = append([]string{}, c.Platform.OSFeatures...)
|
|
}
|
|
|
|
return &pb.Op{
|
|
Platform: &opPlatform,
|
|
Constraints: &pb.WorkerConstraints{
|
|
Filter: c.WorkerConstraints,
|
|
},
|
|
}, c.Metadata.ToPB()
|
|
}
|
|
|
|
type MarshalCache struct {
|
|
cache sync.Map
|
|
}
|
|
|
|
func (mc *MarshalCache) Load(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, []*SourceLocation, error) {
|
|
v, ok := mc.cache.Load(c)
|
|
if !ok {
|
|
return "", nil, nil, nil, cerrdefs.ErrNotFound
|
|
}
|
|
|
|
res := v.(*marshalCacheResult)
|
|
return res.digest, res.dt, res.md, res.srcs, nil
|
|
}
|
|
|
|
func (mc *MarshalCache) Store(dt []byte, md *pb.OpMetadata, srcs []*SourceLocation, c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, []*SourceLocation, error) {
|
|
res := &marshalCacheResult{
|
|
digest: digest.FromBytes(dt),
|
|
dt: dt,
|
|
md: md,
|
|
srcs: srcs,
|
|
}
|
|
mc.cache.Store(c, res)
|
|
return res.digest, res.dt, res.md, res.srcs, nil
|
|
}
|
|
|
|
type marshalCacheResult struct {
|
|
digest digest.Digest
|
|
dt []byte
|
|
md *pb.OpMetadata
|
|
srcs []*SourceLocation
|
|
}
|
|
|
|
func deterministicMarshal[Message proto.Message](m Message) ([]byte, error) {
|
|
return proto.MarshalOptions{Deterministic: true}.Marshal(m)
|
|
}
|