buildkit/solver-next/types.go

201 lines
5.6 KiB
Go

package solver
import (
"context"
"sync"
"time"
"github.com/containerd/containerd/content"
digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// Vertex is one node in the build graph
type Vertex interface {
// Digest is a content-addressable vertex identifier
Digest() digest.Digest
// Sys returns an internal value that is used to execute the vertex. Usually
// this is capured by the operation resolver method during solve.
Sys() interface{}
Options() VertexOptions
// Array of edges current vertex depends on.
Inputs() []Edge
Name() string
}
// Index is a index value for output edge
type Index int
// Edge is a path to a specific output of the vertex
type Edge struct {
Index Index
Vertex Vertex
}
// VertexOptions has optional metadata for the vertex that is not contained in digest
type VertexOptions struct {
IgnoreCache bool
CacheSource CacheManager
Description map[string]string // text values with no special meaning for solver
// WorkerConstraint
}
// Result is an abstract return value for a solve
type Result interface {
ID() string
Release(context.Context) error
Sys() interface{}
}
// CachedResult is a result connected with its cache key
type CachedResult interface {
Result
CacheKey() ExportableCacheKey
Export(ctx context.Context, converter func(context.Context, Result) (*Remote, error)) ([]ExportRecord, error)
}
// Exporter can export the artifacts of the build chain
type Exporter interface {
Export(ctx context.Context, m map[digest.Digest]*ExportRecord, converter func(context.Context, Result) (*Remote, error)) (*ExportRecord, error)
}
// ExportRecord defines a single record in the exported cache chain
type ExportRecord struct {
Digest digest.Digest
Links map[CacheLink]struct{}
Remote *Remote
}
// Remote is a descriptor or a list of stacked descriptors that can be pulled
// from a content provider
type Remote struct {
Descriptors []ocispec.Descriptor
Provider content.Provider
}
// CacheLink is a link between two cache records
type CacheLink struct {
Source digest.Digest
Input Index
Output Index
Base digest.Digest
Selector digest.Digest
}
// Op is an implementation for running a vertex
type Op interface {
// CacheMap returns structure describing how the operation is cached
CacheMap(context.Context) (*CacheMap, error)
// Exec runs an operation given results from previous operations.
Exec(ctx context.Context, inputs []Result) (outputs []Result, err error)
}
type ResultBasedCacheFunc func(context.Context, Result) (digest.Digest, error)
type CacheMap struct {
// Digest is a base digest for operation that needs to be combined with
// inputs cache or selectors for dependencies.
Digest digest.Digest
Deps []struct {
// Optional digest that is merged with the cache key of the input
Selector digest.Digest
// Optional function that returns a digest for the input based on its
// return value
ComputeDigestFunc ResultBasedCacheFunc
}
}
// ExportableCacheKey is a cache key connected with an exporter that can export
// a chain of cacherecords pointing to that key
type ExportableCacheKey struct {
CacheKey
Exporter
}
// CacheKey is an identifier for storing/loading build cache
type CacheKey interface {
// Deps are dependant cache keys
Deps() []CacheKeyWithSelector
// Base digest for operation. Usually CacheMap.Digest
Digest() digest.Digest
// Index for the output that is cached
Output() Index
// Helpers for implementations for adding internal metadata
SetValue(key, value interface{})
GetValue(key interface{}) interface{}
}
// CacheRecord is an identifier for loading in cache
type CacheRecord struct {
ID string
CacheKey ExportableCacheKey
CacheManager CacheManager
Loadable bool
// Size int
CreatedAt time.Time
Priority int
}
// CacheManager implements build cache backend
type CacheManager interface {
// ID is used to identify cache providers that are backed by same source
// to avoid duplicate calls to the same provider
ID() string
// Query searches for cache paths from one cache key to the output of a
// possible match.
Query(inp []ExportableCacheKey, inputIndex Index, dgst digest.Digest, outputIndex Index, selector digest.Digest) ([]*CacheRecord, error)
// Load pulls and returns the cached result
Load(ctx context.Context, rec *CacheRecord) (Result, error)
// Save saves a result based on a cache key
Save(key CacheKey, s Result) (ExportableCacheKey, error)
}
// NewCacheKey creates a new cache key for a specific output index
func NewCacheKey(dgst digest.Digest, index Index, deps []CacheKeyWithSelector) CacheKey {
return &cacheKey{
dgst: dgst,
deps: deps,
index: index,
values: &sync.Map{},
}
}
// CacheKeyWithSelector combines a cache key with an optional selector digest.
// Used to limit the matches for dependency cache key.
type CacheKeyWithSelector struct {
Selector digest.Digest
CacheKey ExportableCacheKey
}
type cacheKey struct {
dgst digest.Digest
index Index
deps []CacheKeyWithSelector
values *sync.Map
}
func (ck *cacheKey) SetValue(key, value interface{}) {
ck.values.Store(key, value)
}
func (ck *cacheKey) GetValue(key interface{}) interface{} {
v, _ := ck.values.Load(key)
return v
}
func (ck *cacheKey) Deps() []CacheKeyWithSelector {
return ck.deps
}
func (ck *cacheKey) Digest() digest.Digest {
return ck.dgst
}
func (ck *cacheKey) Output() Index {
return ck.index
}
func (ck *cacheKey) Export(ctx context.Context, converter func(context.Context, Result) ([]ocispec.Descriptor, content.Provider, error)) ([]ExportRecord, content.Provider, error) {
return nil, nil, nil
}