86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package ops
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/moby/buildkit/solver"
|
|
"github.com/moby/buildkit/solver/pb"
|
|
"github.com/moby/buildkit/source"
|
|
"github.com/moby/buildkit/worker"
|
|
digest "github.com/opencontainers/go-digest"
|
|
)
|
|
|
|
const sourceCacheType = "buildkit.source.v0"
|
|
|
|
type sourceOp struct {
|
|
mu sync.Mutex
|
|
op *pb.Op_Source
|
|
platform *pb.Platform
|
|
sm *source.Manager
|
|
src source.SourceInstance
|
|
w worker.Worker
|
|
}
|
|
|
|
func NewSourceOp(_ solver.Vertex, op *pb.Op_Source, platform *pb.Platform, sm *source.Manager, w worker.Worker) (solver.Op, error) {
|
|
return &sourceOp{
|
|
op: op,
|
|
sm: sm,
|
|
w: w,
|
|
platform: platform,
|
|
}, nil
|
|
}
|
|
|
|
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 := source.FromLLB(s.op, s.platform)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
src, err := s.sm.Resolve(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s.src = src
|
|
return s.src, nil
|
|
}
|
|
|
|
func (s *sourceOp) CacheMap(ctx context.Context, index int) (*solver.CacheMap, bool, error) {
|
|
src, err := s.instance(ctx)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
k, done, err := src.CacheKey(ctx, index)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
dgst := digest.FromBytes([]byte(sourceCacheType + ":" + k))
|
|
|
|
if strings.HasPrefix(k, "session:") {
|
|
dgst = digest.Digest("random:" + strings.TrimPrefix(dgst.String(), dgst.Algorithm().String()+":"))
|
|
}
|
|
|
|
return &solver.CacheMap{
|
|
// TODO: add os/arch
|
|
Digest: dgst,
|
|
}, done, nil
|
|
}
|
|
|
|
func (s *sourceOp) Exec(ctx context.Context, _ []solver.Result) (outputs []solver.Result, err error) {
|
|
src, err := s.instance(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ref, err := src.Snapshot(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []solver.Result{worker.NewWorkerRefResult(ref, s.w)}, nil
|
|
}
|