-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
llbbuild.go
115 lines (94 loc) · 2.37 KB
/
llbbuild.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package llbbuild
import (
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/util/apicaps"
digest "github.com/opencontainers/go-digest"
)
func Build(opt ...BuildOption) llb.StateOption {
return func(s llb.State) llb.State {
return s.WithOutput(NewBuildOp(s.Output(), opt...).Output())
}
}
func NewBuildOp(source llb.Output, opt ...BuildOption) llb.Vertex {
info := &BuildInfo{}
for _, o := range opt {
o(info)
}
return &build{source: source, info: info, constraints: info.Constraints}
}
type build struct {
llb.MarshalCache
source llb.Output
info *BuildInfo
cachedPBDigest digest.Digest
cachedPB []byte
constraints llb.Constraints
}
func (b *build) ToInput(c *llb.Constraints) (*pb.Input, error) {
dgst, _, _, err := b.Marshal(c)
if err != nil {
return nil, err
}
return &pb.Input{Digest: dgst, Index: pb.OutputIndex(0)}, nil
}
func (b *build) Vertex() llb.Vertex {
return b
}
func (b *build) Validate() error {
return nil
}
func (b *build) Marshal(c *llb.Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) {
if b.Cached(c) {
return b.Load()
}
pbo := &pb.BuildOp{
Builder: pb.LLBBuilder,
Inputs: map[string]*pb.BuildInput{
pb.LLBDefinitionInput: {Input: pb.InputIndex(0)}},
}
pbo.Attrs = map[string]string{}
if b.info.DefinitionFilename != "" {
pbo.Attrs[pb.AttrLLBDefinitionFilename] = b.info.DefinitionFilename
}
if b.constraints.Metadata.Caps == nil {
b.constraints.Metadata.Caps = make(map[apicaps.CapID]bool)
}
b.constraints.Metadata.Caps[pb.CapBuildOpLLBFileName] = true
pop, md := llb.MarshalConstraints(c, &b.constraints)
pop.Op = &pb.Op_Build{
Build: pbo,
}
inp, err := b.source.ToInput(c)
if err != nil {
return "", nil, nil, err
}
pop.Inputs = append(pop.Inputs, inp)
dt, err := pop.Marshal()
if err != nil {
return "", nil, nil, err
}
b.Store(dt, md, c)
return b.Load()
}
func (b *build) Output() llb.Output {
return b
}
func (b *build) Inputs() []llb.Output {
return []llb.Output{b.source}
}
type BuildInfo struct {
llb.Constraints
DefinitionFilename string
}
type BuildOption func(*BuildInfo)
func WithFilename(fn string) BuildOption {
return func(b *BuildInfo) {
b.DefinitionFilename = fn
}
}
func WithConstraints(co llb.ConstraintsOpt) BuildOption {
return func(b *BuildInfo) {
co.SetConstraintsOption(&b.Constraints)
}
}