1package solver 2 3import ( 4 "context" 5 "time" 6 7 "github.com/containerd/containerd/content" 8 "github.com/moby/buildkit/session" 9 "github.com/moby/buildkit/solver/pb" 10 digest "github.com/opencontainers/go-digest" 11 ocispec "github.com/opencontainers/image-spec/specs-go/v1" 12) 13 14// Vertex is a node in a build graph. It defines an interface for a 15// content-addressable operation and its inputs. 16type Vertex interface { 17 // Digest returns a checksum of the definition up to the vertex including 18 // all of its inputs. 19 Digest() digest.Digest 20 21 // Sys returns an object used to resolve the executor for this vertex. 22 // In LLB solver, this value would be of type `llb.Op`. 23 Sys() interface{} 24 25 // Options return metadata associated with the vertex that doesn't change the 26 // definition or equality check of it. 27 Options() VertexOptions 28 29 // Inputs returns an array of edges the vertex depends on. An input edge is 30 // a vertex and an index from the returned array of results from an executor 31 // returned by Sys(). A vertex may have zero inputs. 32 Inputs() []Edge 33 34 Name() string 35} 36 37// Index is an index value for the return array of an operation. Index starts 38// counting from zero. 39type Index int 40 41// Edge is a connection point between vertexes. An edge references a specific 42// output of a vertex's operation. Edges are used as inputs to other vertexes. 43type Edge struct { 44 Index Index 45 Vertex Vertex 46} 47 48// VertexOptions define optional metadata for a vertex that doesn't change the 49// definition or equality check of it. These options are not contained in the 50// vertex digest. 51type VertexOptions struct { 52 IgnoreCache bool 53 CacheSources []CacheManager 54 Description map[string]string // text values with no special meaning for solver 55 ExportCache *bool 56 // WorkerConstraint 57} 58 59// Result is an abstract return value for a solve 60type Result interface { 61 ID() string 62 Release(context.Context) error 63 Sys() interface{} 64 Clone() Result 65} 66 67// CachedResult is a result connected with its cache key 68type CachedResult interface { 69 Result 70 CacheKeys() []ExportableCacheKey 71} 72 73type ResultProxy interface { 74 Result(context.Context) (CachedResult, error) 75 Release(context.Context) error 76 Definition() *pb.Definition 77} 78 79// CacheExportMode is the type for setting cache exporting modes 80type CacheExportMode int 81 82const ( 83 // CacheExportModeMin exports a topmost allowed vertex and its dependencies 84 // that already have transferable layers 85 CacheExportModeMin CacheExportMode = iota 86 // CacheExportModeMax exports all possible non-root vertexes 87 CacheExportModeMax 88 // CacheExportModeRemoteOnly only exports vertexes that already have 89 // transferable layers 90 CacheExportModeRemoteOnly 91) 92 93// CacheExportOpt defines options for exporting build cache 94type CacheExportOpt struct { 95 // Convert can convert a build result to transferable object 96 Convert func(context.Context, Result) (*Remote, error) 97 // Mode defines a cache export algorithm 98 Mode CacheExportMode 99 // Session is the session group to client (for auth credentials etc) 100 Session session.Group 101} 102 103// CacheExporter can export the artifacts of the build chain 104type CacheExporter interface { 105 ExportTo(ctx context.Context, t CacheExporterTarget, opt CacheExportOpt) ([]CacheExporterRecord, error) 106} 107 108// CacheExporterTarget defines object capable of receiving exports 109type CacheExporterTarget interface { 110 Add(dgst digest.Digest) CacheExporterRecord 111 Visit(interface{}) 112 Visited(interface{}) bool 113} 114 115// CacheExporterRecord is a single object being exported 116type CacheExporterRecord interface { 117 AddResult(createdAt time.Time, result *Remote) 118 LinkFrom(src CacheExporterRecord, index int, selector string) 119} 120 121// Remote is a descriptor or a list of stacked descriptors that can be pulled 122// from a content provider 123// TODO: add closer to keep referenced data from getting deleted 124type Remote struct { 125 Descriptors []ocispec.Descriptor 126 Provider content.Provider 127} 128 129// CacheLink is a link between two cache records 130type CacheLink struct { 131 Source digest.Digest `json:",omitempty"` 132 Input Index `json:",omitempty"` 133 Output Index `json:",omitempty"` 134 Base digest.Digest `json:",omitempty"` 135 Selector digest.Digest `json:",omitempty"` 136} 137 138// Op defines how the solver can evaluate the properties of a vertex operation. 139// An op is executed in the worker, and is retrieved from the vertex by the 140// value of `vertex.Sys()`. The solver is configured with a resolve function to 141// convert a `vertex.Sys()` into an `Op`. 142type Op interface { 143 // CacheMap returns structure describing how the operation is cached. 144 // Currently only roots are allowed to return multiple cache maps per op. 145 CacheMap(context.Context, session.Group, int) (*CacheMap, bool, error) 146 147 // Exec runs an operation given results from previous operations. 148 Exec(ctx context.Context, g session.Group, inputs []Result) (outputs []Result, err error) 149} 150 151type ResultBasedCacheFunc func(context.Context, Result, session.Group) (digest.Digest, error) 152type PreprocessFunc func(context.Context, Result, session.Group) error 153 154// CacheMap is a description for calculating the cache key of an operation. 155type CacheMap struct { 156 // Digest returns a checksum for the operation. The operation result can be 157 // cached by a checksum that combines this digest and the cache keys of the 158 // operation's inputs. 159 // 160 // For example, in LLB this digest is a manifest digest for OCI images, or 161 // commit SHA for git sources. 162 Digest digest.Digest 163 164 // Deps contain optional selectors or content-based cache functions for its 165 // inputs. 166 Deps []struct { 167 // Selector is a digest that is merged with the cache key of the input. 168 // Selectors are not merged with the result of the `ComputeDigestFunc` for 169 // this input. 170 Selector digest.Digest 171 172 // ComputeDigestFunc should return a digest for the input based on its return 173 // value. 174 // 175 // For example, in LLB this is invoked to calculate the cache key based on 176 // the checksum of file contents from input snapshots. 177 ComputeDigestFunc ResultBasedCacheFunc 178 179 // PreprocessFunc is a function that runs on an input before it is passed to op 180 PreprocessFunc PreprocessFunc 181 } 182 183 // Opts specifies generic options that will be passed to cache load calls if/when 184 // the key associated with this CacheMap is used to load a ref. It allows options 185 // such as oci descriptor content providers and progress writers to be passed to 186 // the cache. Opts should not have any impact on the computed cache key. 187 Opts CacheOpts 188} 189 190// ExportableCacheKey is a cache key connected with an exporter that can export 191// a chain of cacherecords pointing to that key 192type ExportableCacheKey struct { 193 *CacheKey 194 Exporter CacheExporter 195} 196 197// CacheRecord is an identifier for loading in cache 198type CacheRecord struct { 199 ID string 200 Size int 201 CreatedAt time.Time 202 Priority int 203 204 cacheManager *cacheManager 205 key *CacheKey 206} 207 208// CacheManager determines if there is a result that matches the cache keys 209// generated during the build that could be reused instead of fully 210// reevaluating the vertex and its inputs. There can be multiple cache 211// managers, and specific managers can be defined per vertex using 212// `VertexOptions`. 213type CacheManager interface { 214 // ID is used to identify cache providers that are backed by same source 215 // to avoid duplicate calls to the same provider. 216 ID() string 217 218 // Query searches for cache paths from one cache key to the output of a 219 // possible match. 220 Query(inp []CacheKeyWithSelector, inputIndex Index, dgst digest.Digest, outputIndex Index) ([]*CacheKey, error) 221 Records(ck *CacheKey) ([]*CacheRecord, error) 222 223 // Load loads a cache record into a result reference. 224 Load(ctx context.Context, rec *CacheRecord) (Result, error) 225 226 // Save saves a result based on a cache key 227 Save(key *CacheKey, s Result, createdAt time.Time) (*ExportableCacheKey, error) 228} 229