mirror of
https://github.com/moby/buildkit.git
synced 2026-08-04 14:50:21 +00:00
In these cases, we can just call digest.Encoded(), instead of needing to play around with removing the prefix. Signed-off-by: Justin Chadwell <me@jedevc.com>
127 lines
2.8 KiB
Go
127 lines
2.8 KiB
Go
package ops
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/moby/buildkit/session"
|
|
"github.com/moby/buildkit/solver"
|
|
"github.com/moby/buildkit/solver/llbsolver/ops/opsutils"
|
|
"github.com/moby/buildkit/solver/pb"
|
|
"github.com/moby/buildkit/source"
|
|
"github.com/moby/buildkit/worker"
|
|
digest "github.com/opencontainers/go-digest"
|
|
"golang.org/x/sync/semaphore"
|
|
)
|
|
|
|
const sourceCacheType = "buildkit.source.v0"
|
|
|
|
type SourceOp struct {
|
|
mu sync.Mutex
|
|
op *pb.Op_Source
|
|
platform *pb.Platform
|
|
sm *source.Manager
|
|
src source.SourceInstance
|
|
sessM *session.Manager
|
|
w worker.Worker
|
|
vtx solver.Vertex
|
|
parallelism *semaphore.Weighted
|
|
pin string
|
|
id source.Identifier
|
|
}
|
|
|
|
var _ solver.Op = &SourceOp{}
|
|
|
|
func NewSourceOp(vtx solver.Vertex, op *pb.Op_Source, platform *pb.Platform, sm *source.Manager, parallelism *semaphore.Weighted, sessM *session.Manager, w worker.Worker) (*SourceOp, error) {
|
|
if err := opsutils.Validate(&pb.Op{Op: op}); err != nil {
|
|
return nil, err
|
|
}
|
|
return &SourceOp{
|
|
op: op,
|
|
sm: sm,
|
|
w: w,
|
|
sessM: sessM,
|
|
platform: platform,
|
|
vtx: vtx,
|
|
parallelism: parallelism,
|
|
}, nil
|
|
}
|
|
|
|
func (s *SourceOp) IsProvenanceProvider() {}
|
|
|
|
func (s *SourceOp) Pin() (source.Identifier, string) {
|
|
return s.id, s.pin
|
|
}
|
|
|
|
func (s *SourceOp) instance(ctx context.Context) (source.SourceInstance, error) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
if s.src != nil {
|
|
return s.src, nil
|
|
}
|
|
id, err := s.sm.Identifier(s.op, s.platform)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
src, err := s.sm.Resolve(ctx, id, s.sessM, s.vtx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s.src = src
|
|
s.id = id
|
|
return s.src, nil
|
|
}
|
|
|
|
func (s *SourceOp) CacheMap(ctx context.Context, g session.Group, index int) (*solver.CacheMap, bool, error) {
|
|
src, err := s.instance(ctx)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
k, pin, cacheOpts, done, err := src.CacheKey(ctx, g, index)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
if s.pin == "" {
|
|
s.pin = pin
|
|
}
|
|
|
|
dgst := digest.FromBytes([]byte(sourceCacheType + ":" + k))
|
|
if strings.HasPrefix(k, "session:") {
|
|
dgst = digest.Digest("random:" + dgst.Encoded())
|
|
}
|
|
|
|
return &solver.CacheMap{
|
|
// TODO: add os/arch
|
|
Digest: dgst,
|
|
Opts: cacheOpts,
|
|
}, done, nil
|
|
}
|
|
|
|
func (s *SourceOp) Exec(ctx context.Context, g session.Group, _ []solver.Result) (outputs []solver.Result, err error) {
|
|
src, err := s.instance(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ref, err := src.Snapshot(ctx, g)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []solver.Result{worker.NewWorkerRefResult(ref, s.w)}, nil
|
|
}
|
|
|
|
func (s *SourceOp) Acquire(ctx context.Context) (solver.ReleaseFunc, error) {
|
|
if s.parallelism == nil {
|
|
return func() {}, nil
|
|
}
|
|
err := s.parallelism.Acquire(ctx, 1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return func() {
|
|
s.parallelism.Release(1)
|
|
}, nil
|
|
}
|