2018-01-02 18:06:50 +00:00
|
|
|
package solver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2018-02-02 00:10:38 +00:00
|
|
|
"time"
|
2018-01-02 18:06:50 +00:00
|
|
|
|
2018-02-13 23:54:00 +00:00
|
|
|
"github.com/containerd/containerd/content"
|
2018-01-02 18:06:50 +00:00
|
|
|
digest "github.com/opencontainers/go-digest"
|
2018-02-13 23:54:00 +00:00
|
|
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
2018-01-02 18:06:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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{}
|
2018-02-01 23:41:14 +00:00
|
|
|
Options() VertexOptions
|
2018-01-02 18:06:50 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2018-02-01 23:41:14 +00:00
|
|
|
// VertexOptions has optional metadata for the vertex that is not contained in digest
|
|
|
|
type VertexOptions struct {
|
2018-04-25 17:49:15 +00:00
|
|
|
IgnoreCache bool
|
|
|
|
CacheSources []CacheManager
|
|
|
|
Description map[string]string // text values with no special meaning for solver
|
|
|
|
ExportCache *bool
|
2018-02-01 22:23:42 +00:00
|
|
|
// WorkerConstraint
|
|
|
|
}
|
|
|
|
|
2018-01-02 18:06:50 +00:00
|
|
|
// 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
|
2018-07-23 21:27:35 +00:00
|
|
|
CacheKeys() []ExportableCacheKey
|
2018-02-13 23:54:00 +00:00
|
|
|
}
|
|
|
|
|
2018-05-09 04:52:30 +00:00
|
|
|
// CacheExportMode is the type for setting cache exporting modes
|
2018-05-07 21:19:02 +00:00
|
|
|
type CacheExportMode int
|
|
|
|
|
|
|
|
const (
|
2018-05-09 04:52:30 +00:00
|
|
|
// CacheExportModeMin exports a topmost allowed vertex and its dependencies
|
|
|
|
// that already have transferable layers
|
2018-05-07 21:19:02 +00:00
|
|
|
CacheExportModeMin CacheExportMode = iota
|
2018-05-09 04:52:30 +00:00
|
|
|
// CacheExportModeMax exports all possible non-root vertexes
|
2018-05-07 21:19:02 +00:00
|
|
|
CacheExportModeMax
|
2018-05-09 04:52:30 +00:00
|
|
|
// CacheExportModeRemoteOnly only exports vertexes that already have
|
|
|
|
// transferable layers
|
2018-05-07 23:17:03 +00:00
|
|
|
CacheExportModeRemoteOnly
|
2018-05-07 21:19:02 +00:00
|
|
|
)
|
|
|
|
|
2018-05-09 04:52:30 +00:00
|
|
|
// CacheExportOpt defines options for exporting build cache
|
2018-05-07 21:19:02 +00:00
|
|
|
type CacheExportOpt struct {
|
2018-05-09 04:52:30 +00:00
|
|
|
// Convert can convert a build result to transferable object
|
2018-05-07 21:19:02 +00:00
|
|
|
Convert func(context.Context, Result) (*Remote, error)
|
2018-05-09 04:52:30 +00:00
|
|
|
// Mode defines a cache export algorithm
|
|
|
|
Mode CacheExportMode
|
2018-05-07 21:19:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// CacheExporter can export the artifacts of the build chain
|
|
|
|
type CacheExporter interface {
|
|
|
|
ExportTo(ctx context.Context, t CacheExporterTarget, opt CacheExportOpt) ([]CacheExporterRecord, error)
|
2018-02-13 23:54:00 +00:00
|
|
|
}
|
|
|
|
|
2018-05-07 21:19:02 +00:00
|
|
|
// CacheExporterTarget defines object capable of receiving exports
|
|
|
|
type CacheExporterTarget interface {
|
|
|
|
Add(dgst digest.Digest) CacheExporterRecord
|
2018-04-13 20:52:27 +00:00
|
|
|
Visit(interface{})
|
|
|
|
Visited(interface{}) bool
|
|
|
|
}
|
|
|
|
|
2018-05-07 21:19:02 +00:00
|
|
|
// CacheExporterRecord is a single object being exported
|
|
|
|
type CacheExporterRecord interface {
|
2018-04-13 20:52:27 +00:00
|
|
|
AddResult(createdAt time.Time, result *Remote)
|
2018-05-07 21:19:02 +00:00
|
|
|
LinkFrom(src CacheExporterRecord, index int, selector string)
|
2018-02-13 23:54:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remote is a descriptor or a list of stacked descriptors that can be pulled
|
|
|
|
// from a content provider
|
2018-04-13 20:52:27 +00:00
|
|
|
// TODO: add closer to keep referenced data from getting deleted
|
2018-02-13 23:54:00 +00:00
|
|
|
type Remote struct {
|
|
|
|
Descriptors []ocispec.Descriptor
|
|
|
|
Provider content.Provider
|
|
|
|
}
|
|
|
|
|
|
|
|
// CacheLink is a link between two cache records
|
|
|
|
type CacheLink struct {
|
2018-04-13 20:52:27 +00:00
|
|
|
Source digest.Digest `json:",omitempty"`
|
|
|
|
Input Index `json:",omitempty"`
|
|
|
|
Output Index `json:",omitempty"`
|
|
|
|
Base digest.Digest `json:",omitempty"`
|
|
|
|
Selector digest.Digest `json:",omitempty"`
|
2018-01-02 18:06:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Op is an implementation for running a vertex
|
|
|
|
type Op interface {
|
2018-04-24 19:01:50 +00:00
|
|
|
// CacheMap returns structure describing how the operation is cached.
|
|
|
|
// Currently only roots are allowed to return multiple cache maps per op.
|
|
|
|
CacheMap(context.Context, int) (*CacheMap, bool, error)
|
2018-01-02 18:06:50 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-13 23:54:00 +00:00
|
|
|
// ExportableCacheKey is a cache key connected with an exporter that can export
|
|
|
|
// a chain of cacherecords pointing to that key
|
|
|
|
type ExportableCacheKey struct {
|
2018-04-13 20:52:27 +00:00
|
|
|
*CacheKey
|
2018-05-07 21:19:02 +00:00
|
|
|
Exporter CacheExporter
|
2018-02-13 23:54:00 +00:00
|
|
|
}
|
|
|
|
|
2018-01-02 18:06:50 +00:00
|
|
|
// CacheRecord is an identifier for loading in cache
|
|
|
|
type CacheRecord struct {
|
2018-04-13 20:52:27 +00:00
|
|
|
ID string
|
|
|
|
Size int
|
2018-02-02 00:10:38 +00:00
|
|
|
CreatedAt time.Time
|
|
|
|
Priority int
|
2018-04-13 20:52:27 +00:00
|
|
|
|
|
|
|
cacheManager *cacheManager
|
|
|
|
key *CacheKey
|
2018-01-02 18:06:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// CacheManager implements build cache backend
|
|
|
|
type CacheManager interface {
|
2018-02-01 22:23:42 +00:00
|
|
|
// 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.
|
2018-04-13 20:52:27 +00:00
|
|
|
Query(inp []CacheKeyWithSelector, inputIndex Index, dgst digest.Digest, outputIndex Index) ([]*CacheKey, error)
|
|
|
|
Records(ck *CacheKey) ([]*CacheRecord, error)
|
2018-01-02 18:06:50 +00:00
|
|
|
// Load pulls and returns the cached result
|
|
|
|
Load(ctx context.Context, rec *CacheRecord) (Result, error)
|
|
|
|
// Save saves a result based on a cache key
|
2018-04-13 20:52:27 +00:00
|
|
|
Save(key *CacheKey, s Result) (*ExportableCacheKey, error)
|
2018-02-13 23:54:00 +00:00
|
|
|
}
|