Files
buildkit/solver/llbsolver/ops/diff.go
Jonathan A. Sternberg 1a3fc0aa15 protobuf: remove gogoproto
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>
2024-09-26 12:57:45 -05:00

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
}