2017-07-06 04:25:51 +00:00
|
|
|
package solver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/moby/buildkit/client"
|
2017-10-05 05:31:18 +00:00
|
|
|
"github.com/moby/buildkit/identity"
|
2017-07-06 04:25:51 +00:00
|
|
|
"github.com/moby/buildkit/util/progress"
|
|
|
|
digest "github.com/opencontainers/go-digest"
|
2017-10-05 05:31:18 +00:00
|
|
|
"golang.org/x/net/context"
|
2017-07-06 04:25:51 +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{}
|
2017-10-02 04:59:34 +00:00
|
|
|
Metadata() Metadata
|
2017-07-06 04:25:51 +00:00
|
|
|
// Array of vertexes current vertex depends on.
|
|
|
|
Inputs() []Input
|
|
|
|
Name() string // change this to general metadata
|
|
|
|
}
|
|
|
|
|
2017-10-02 04:59:34 +00:00
|
|
|
// Metadata is per-vertex metadata, implemented by *pb.OpMetadata
|
|
|
|
type Metadata interface {
|
|
|
|
GetIgnoreCache() bool
|
|
|
|
}
|
|
|
|
|
2017-07-31 22:06:59 +00:00
|
|
|
type Index int
|
|
|
|
|
2017-07-06 04:25:51 +00:00
|
|
|
// Input is an pointer to a single reference from a vertex by an index.
|
|
|
|
type Input struct {
|
2017-07-31 22:06:59 +00:00
|
|
|
Index Index
|
2017-07-06 04:25:51 +00:00
|
|
|
Vertex Vertex
|
|
|
|
}
|
|
|
|
|
|
|
|
type input struct {
|
2017-07-31 22:06:59 +00:00
|
|
|
index Index
|
2017-07-06 04:25:51 +00:00
|
|
|
vertex *vertex
|
|
|
|
}
|
|
|
|
|
|
|
|
type vertex struct {
|
|
|
|
mu sync.Mutex
|
|
|
|
sys interface{}
|
2017-10-02 04:59:34 +00:00
|
|
|
metadata Metadata
|
2017-07-06 04:25:51 +00:00
|
|
|
inputs []*input
|
|
|
|
err error
|
|
|
|
digest digest.Digest
|
|
|
|
clientVertex client.Vertex
|
|
|
|
name string
|
2017-08-10 01:20:33 +00:00
|
|
|
notifyMu sync.Mutex
|
2017-07-06 04:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *vertex) initClientVertex() {
|
|
|
|
inputDigests := make([]digest.Digest, 0, len(v.inputs))
|
|
|
|
for _, inp := range v.inputs {
|
|
|
|
inputDigests = append(inputDigests, inp.vertex.Digest())
|
|
|
|
}
|
|
|
|
v.clientVertex = client.Vertex{
|
|
|
|
Inputs: inputDigests,
|
|
|
|
Name: v.Name(),
|
|
|
|
Digest: v.digest,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *vertex) Digest() digest.Digest {
|
|
|
|
return v.digest
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *vertex) Sys() interface{} {
|
|
|
|
return v.sys
|
|
|
|
}
|
|
|
|
|
2017-10-02 04:59:34 +00:00
|
|
|
func (v *vertex) Metadata() Metadata {
|
|
|
|
return v.metadata
|
|
|
|
}
|
|
|
|
|
2017-07-06 04:25:51 +00:00
|
|
|
func (v *vertex) Inputs() (inputs []Input) {
|
2017-08-10 01:20:33 +00:00
|
|
|
inputs = make([]Input, 0, len(v.inputs))
|
2017-07-06 04:25:51 +00:00
|
|
|
for _, i := range v.inputs {
|
|
|
|
inputs = append(inputs, Input{i.index, i.vertex})
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *vertex) Name() string {
|
|
|
|
return v.name
|
|
|
|
}
|
|
|
|
|
2017-09-26 03:57:38 +00:00
|
|
|
func notifyStarted(ctx context.Context, v *client.Vertex) {
|
2017-07-06 04:25:51 +00:00
|
|
|
pw, _, _ := progress.FromContext(ctx)
|
|
|
|
defer pw.Close()
|
|
|
|
now := time.Now()
|
2017-09-26 03:57:38 +00:00
|
|
|
v.Started = &now
|
|
|
|
v.Completed = nil
|
|
|
|
pw.Write(v.Digest.String(), *v)
|
2017-07-06 04:25:51 +00:00
|
|
|
}
|
|
|
|
|
2017-09-26 03:57:38 +00:00
|
|
|
func notifyCompleted(ctx context.Context, v *client.Vertex, err error) {
|
2017-07-06 04:25:51 +00:00
|
|
|
pw, _, _ := progress.FromContext(ctx)
|
|
|
|
defer pw.Close()
|
|
|
|
now := time.Now()
|
2017-09-26 03:57:38 +00:00
|
|
|
if v.Started == nil {
|
|
|
|
v.Started = &now
|
2017-07-06 20:15:54 +00:00
|
|
|
}
|
2017-09-26 03:57:38 +00:00
|
|
|
v.Completed = &now
|
|
|
|
v.Cached = false
|
2017-07-06 04:25:51 +00:00
|
|
|
if err != nil {
|
2017-09-26 03:57:38 +00:00
|
|
|
v.Error = err.Error()
|
2017-07-06 04:25:51 +00:00
|
|
|
}
|
2017-09-26 03:57:38 +00:00
|
|
|
pw.Write(v.Digest.String(), *v)
|
2017-07-06 20:15:54 +00:00
|
|
|
}
|
2017-10-05 05:31:18 +00:00
|
|
|
|
|
|
|
func inVertexContext(ctx context.Context, name string, f func(ctx context.Context) error) error {
|
|
|
|
v := client.Vertex{
|
|
|
|
Digest: digest.FromBytes([]byte(identity.NewID())),
|
|
|
|
Name: name,
|
|
|
|
}
|
|
|
|
pw, _, ctx := progress.FromContext(ctx, progress.WithMetadata("vertex", v.Digest))
|
|
|
|
notifyStarted(ctx, &v)
|
|
|
|
defer pw.Close()
|
|
|
|
err := f(ctx)
|
|
|
|
notifyCompleted(ctx, &v, err)
|
|
|
|
return err
|
|
|
|
}
|