mirror of
https://github.com/moby/buildkit.git
synced 2026-08-04 14:50:21 +00:00
Remove gogoproto in favor of the standard protobuf compiler. This removes any nonstandard extensions that were part of gogoproto such as the custom types. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
package ops
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
|
|
"github.com/moby/buildkit/worker"
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/moby/buildkit/cache"
|
|
"github.com/moby/buildkit/session"
|
|
"github.com/moby/buildkit/solver"
|
|
"github.com/moby/buildkit/solver/llbsolver/ops/opsutils"
|
|
"github.com/moby/buildkit/solver/pb"
|
|
digest "github.com/opencontainers/go-digest"
|
|
)
|
|
|
|
const diffCacheType = "buildkit.diff.v0"
|
|
|
|
type diffOp struct {
|
|
op *pb.DiffOp
|
|
worker worker.Worker
|
|
vtx solver.Vertex
|
|
}
|
|
|
|
func NewDiffOp(v solver.Vertex, op *pb.Op_Diff, w worker.Worker) (solver.Op, error) {
|
|
if err := opsutils.Validate(&pb.Op{Op: op}); err != nil {
|
|
return nil, err
|
|
}
|
|
return &diffOp{
|
|
op: op.Diff,
|
|
worker: w,
|
|
vtx: v,
|
|
}, nil
|
|
}
|
|
|
|
func (d *diffOp) CacheMap(ctx context.Context, group session.Group, index int) (*solver.CacheMap, bool, error) {
|
|
dt, err := json.Marshal(struct {
|
|
Type string
|
|
Diff *pb.DiffOp
|
|
}{
|
|
Type: diffCacheType,
|
|
Diff: d.op,
|
|
})
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
var depCount int
|
|
if d.op.Lower.Input != int64(pb.Empty) {
|
|
depCount++
|
|
}
|
|
if d.op.Upper.Input != int64(pb.Empty) {
|
|
depCount++
|
|
}
|
|
|
|
cm := &solver.CacheMap{
|
|
Digest: digest.FromBytes(dt),
|
|
Deps: make([]struct {
|
|
Selector digest.Digest
|
|
ComputeDigestFunc solver.ResultBasedCacheFunc
|
|
PreprocessFunc solver.PreprocessFunc
|
|
}, depCount),
|
|
}
|
|
|
|
return cm, true, nil
|
|
}
|
|
|
|
func (d *diffOp) Exec(ctx context.Context, g session.Group, inputs []solver.Result) ([]solver.Result, error) {
|
|
var curInput int
|
|
|
|
var lowerRef cache.ImmutableRef
|
|
if d.op.Lower.Input != int64(pb.Empty) {
|
|
if lowerInp := inputs[curInput]; lowerInp != nil {
|
|
wref, ok := lowerInp.Sys().(*worker.WorkerRef)
|
|
if !ok {
|
|
return nil, errors.Errorf("invalid lower reference for diff op %T", lowerInp.Sys())
|
|
}
|
|
lowerRef = wref.ImmutableRef
|
|
} else {
|
|
return nil, errors.New("invalid nil lower input for diff op")
|
|
}
|
|
curInput++
|
|
}
|
|
|
|
var upperRef cache.ImmutableRef
|
|
if d.op.Upper.Input != int64(pb.Empty) {
|
|
if upperInp := inputs[curInput]; upperInp != nil {
|
|
wref, ok := upperInp.Sys().(*worker.WorkerRef)
|
|
if !ok {
|
|
return nil, errors.Errorf("invalid upper reference for diff op %T", upperInp.Sys())
|
|
}
|
|
upperRef = wref.ImmutableRef
|
|
} else {
|
|
return nil, errors.New("invalid nil upper input for diff op")
|
|
}
|
|
}
|
|
|
|
if lowerRef == nil {
|
|
if upperRef == nil {
|
|
// The diff of nothing and nothing is nothing. Just return an empty ref.
|
|
return []solver.Result{worker.NewWorkerRefResult(nil, d.worker)}, nil
|
|
}
|
|
// The diff of nothing and upper is upper. Just return a clone of upper
|
|
return []solver.Result{worker.NewWorkerRefResult(upperRef.Clone(), d.worker)}, nil
|
|
}
|
|
if upperRef != nil && lowerRef.ID() == upperRef.ID() {
|
|
// The diff of a ref and itself is nothing, return an empty ref.
|
|
return []solver.Result{worker.NewWorkerRefResult(nil, d.worker)}, nil
|
|
}
|
|
|
|
diffRef, err := d.worker.CacheManager().Diff(ctx, lowerRef, upperRef, solver.ProgressControllerFromContext(ctx),
|
|
cache.WithDescription(d.vtx.Name()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return []solver.Result{worker.NewWorkerRefResult(diffRef, d.worker)}, nil
|
|
}
|
|
|
|
func (d *diffOp) Acquire(ctx context.Context) (release solver.ReleaseFunc, err error) {
|
|
return func() {}, nil
|
|
}
|