Skip to content

Commit af16b82

Browse files
committed
wip: exporter: new gateway exporter
Signed-off-by: Justin Chadwell <me@jedevc.com>
1 parent 877093a commit af16b82

File tree

49 files changed

+4525
-770
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+4525
-770
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.pb.go linguist-generated=true
2+
*.pb.go -diff

.github/workflows/buildkit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
- binaries
113113
with:
114114
cache_scope: build-integration-tests
115-
pkgs: ./client ./cmd/buildctl ./worker/containerd ./solver ./frontend
115+
pkgs: ./client ./cmd/buildctl ./worker/containerd ./solver ./frontend ./exporter
116116
kinds: integration
117117
codecov_flags: core
118118
includes: |

TODO.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# TODO
2+
3+
<https://github.com/moby/buildkit/issues/3037>
4+
5+
- [x] Basic tests for current behavior
6+
- [x] exportprovider
7+
- [ ] Double release errors
8+
- XXXs
9+
- [x] Attestation support
10+
11+
## Follow-ups
12+
13+
- [ ] Secrets

api/services/control/control.pb.go

Lines changed: 200 additions & 127 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/services/control/control.proto

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,20 @@ message BuildResultInfo {
244244
map<int64, Descriptor> Results = 3;
245245
}
246246

247+
enum ExporterTarget {
248+
UNKNOWN = 0;
249+
NONE = 1;
250+
FILE = 2;
251+
DIRECTORY = 3;
252+
STORE = 4;
253+
}
254+
247255
// Exporter describes the output exporter
248256
message Exporter {
249257
// Type identifies the exporter
250258
string Type = 1;
251259
// Attrs specifies exporter configuration
252260
map<string, string> Attrs = 2;
261+
// Target indicates the target type of the exporter
262+
ExporterTarget Target = 3;
253263
}

api/services/control/control_vtproto.pb.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/services/control/converters.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package moby_buildkit_v1 //nolint:revive,staticcheck
2+
3+
import (
4+
"github.com/moby/buildkit/exporter/containerimage/exptypes"
5+
)
6+
7+
func ExporterTargetFromPB(target ExporterTarget) exptypes.ExporterTarget {
8+
switch target {
9+
case ExporterTarget_UNKNOWN:
10+
return exptypes.ExporterTargetUnknown
11+
case ExporterTarget_NONE:
12+
return exptypes.ExporterTargetNone
13+
case ExporterTarget_FILE:
14+
return exptypes.ExporterTargetFile
15+
case ExporterTarget_DIRECTORY:
16+
return exptypes.ExporterTargetDirectory
17+
case ExporterTarget_STORE:
18+
return exptypes.ExporterTargetStore
19+
default:
20+
return exptypes.ExporterTargetUnknown
21+
}
22+
}
23+
24+
func ExporterTargetToPB(target exptypes.ExporterTarget) ExporterTarget {
25+
switch target {
26+
case exptypes.ExporterTargetUnknown:
27+
return ExporterTarget_UNKNOWN
28+
case exptypes.ExporterTargetNone:
29+
return ExporterTarget_NONE
30+
case exptypes.ExporterTargetFile:
31+
return ExporterTarget_FILE
32+
case exptypes.ExporterTargetDirectory:
33+
return ExporterTarget_DIRECTORY
34+
case exptypes.ExporterTargetStore:
35+
return ExporterTarget_STORE
36+
default:
37+
return ExporterTarget_UNKNOWN
38+
}
39+
}

client/build.go

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ import (
99
"github.com/moby/buildkit/frontend/gateway/grpcclient"
1010
gatewayapi "github.com/moby/buildkit/frontend/gateway/pb"
1111
"github.com/moby/buildkit/session"
12+
"github.com/moby/buildkit/session/exporter"
13+
"github.com/moby/buildkit/session/exporter/exporterprovider"
1214
"github.com/moby/buildkit/util/apicaps"
1315
"github.com/pkg/errors"
1416
"google.golang.org/grpc"
1517
)
1618

17-
func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildFunc gateway.BuildFunc, statusChan chan *SolveStatus) (*SolveResponse, error) {
19+
func (c *Client) BuildExport(ctx context.Context, opt SolveOpt, product string, buildFunc gateway.BuildFunc, exportFunc gateway.ExportFunc, statusChan chan *SolveStatus) (*SolveResponse, error) {
1820
defer func() {
1921
if statusChan != nil {
2022
close(statusChan)
@@ -42,21 +44,35 @@ func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildF
4244
})
4345
}
4446

47+
var g grpcclient.GrpcClient
48+
if exportFunc != nil {
49+
opt.EnableSessionExporter = true
50+
exporter := exporterprovider.New(func(ctx context.Context, _ map[string][]byte, _ []string) ([]*exporter.ExporterRequest, error) {
51+
if g == nil {
52+
return nil, errors.New("no build session found for export")
53+
}
54+
return nil, g.Export(ctx, c.conn, exportFunc)
55+
})
56+
opt.Session = append(opt.Session, exporter)
57+
}
58+
4559
cb := func(ref string, s *session.Session, opts map[string]string) error {
4660
if feOpts == nil {
4761
feOpts = map[string]string{}
4862
}
4963
maps.Copy(feOpts, opts)
5064
gwClient := c.gatewayClientForBuild(ref)
51-
g, err := grpcclient.New(ctx, feOpts, s.ID(), product, gwClient, gworkers)
65+
var err error
66+
g, err = grpcclient.New(ctx, feOpts, s.ID(), product, gwClient, gworkers)
5267
if err != nil {
5368
return err
5469
}
5570

5671
caps := g.BuildOpts().Caps
5772
gwClient.caps = &caps
5873

59-
if err := g.Run(ctx, buildFunc); err != nil {
74+
err = g.Build(ctx, buildFunc)
75+
if err != nil {
6076
return errors.Wrap(err, "failed to run Build function")
6177
}
6278
return nil
@@ -65,6 +81,10 @@ func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildF
6581
return c.solve(ctx, nil, cb, opt, statusChan)
6682
}
6783

84+
func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildFunc gateway.BuildFunc, statusChan chan *SolveStatus) (*SolveResponse, error) {
85+
return c.BuildExport(ctx, opt, product, buildFunc, nil, statusChan)
86+
}
87+
6888
func (c *Client) gatewayClientForBuild(buildid string) *gatewayClientForBuild {
6989
g := gatewayapi.NewLLBBridgeClient(c.conn)
7090
return &gatewayClientForBuild{
@@ -138,6 +158,11 @@ func (g *gatewayClientForBuild) Evaluate(ctx context.Context, in *gatewayapi.Eva
138158
return g.gateway.Evaluate(ctx, in, opts...)
139159
}
140160

161+
func (g *gatewayClientForBuild) GetRemote(ctx context.Context, in *gatewayapi.GetRemoteRequest, opts ...grpc.CallOption) (*gatewayapi.GetRemoteResponse, error) {
162+
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
163+
return g.gateway.GetRemote(ctx, in, opts...)
164+
}
165+
141166
func (g *gatewayClientForBuild) Ping(ctx context.Context, in *gatewayapi.PingRequest, opts ...grpc.CallOption) (*gatewayapi.PongResponse, error) {
142167
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
143168
return g.gateway.Ping(ctx, in, opts...)
@@ -148,6 +173,11 @@ func (g *gatewayClientForBuild) Return(ctx context.Context, in *gatewayapi.Retur
148173
return g.gateway.Return(ctx, in, opts...)
149174
}
150175

176+
func (g *gatewayClientForBuild) GetReturn(ctx context.Context, in *gatewayapi.GetReturnRequest, opts ...grpc.CallOption) (*gatewayapi.GetReturnResponse, error) {
177+
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
178+
return g.gateway.GetReturn(ctx, in, opts...)
179+
}
180+
151181
func (g *gatewayClientForBuild) Inputs(ctx context.Context, in *gatewayapi.InputsRequest, opts ...grpc.CallOption) (*gatewayapi.InputsResponse, error) {
152182
if g.caps != nil {
153183
if err := g.caps.Supports(gatewayapi.CapFrontendInputs); err != nil {

client/exporters.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package client
22

33
const (
4-
ExporterImage = "image"
5-
ExporterLocal = "local"
6-
ExporterTar = "tar"
7-
ExporterOCI = "oci"
8-
ExporterDocker = "docker"
4+
ExporterImage = "image"
5+
ExporterLocal = "local"
6+
ExporterTar = "tar"
7+
ExporterOCI = "oci"
8+
ExporterDocker = "docker"
9+
ExporterGateway = "gateway"
910
)

client/solve.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
168168
if supportFile && supportStore {
169169
return nil, errors.Errorf("both file and store output is not supported by %s exporter", ex.Type)
170170
}
171+
case ExporterGateway:
172+
supportFile = ex.Output != nil
173+
supportDir = ex.OutputDir != ""
171174
}
172175
if !supportFile && ex.Output != nil {
173176
return nil, errors.Errorf("output file writer is not supported by %s exporter", ex.Type)
@@ -274,9 +277,24 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
274277
exportDeprecated = exp.Type
275278
exportAttrDeprecated = exp.Attrs
276279
}
280+
target := controlapi.ExporterTarget_NONE
281+
switch {
282+
case exp.Output != nil:
283+
target = controlapi.ExporterTarget_FILE
284+
case exp.OutputDir != "":
285+
switch exp.Type {
286+
case ExporterOCI, ExporterDocker:
287+
target = controlapi.ExporterTarget_STORE
288+
default:
289+
target = controlapi.ExporterTarget_DIRECTORY
290+
}
291+
case exp.OutputStore != nil:
292+
target = controlapi.ExporterTarget_STORE
293+
}
277294
exports = append(exports, &controlapi.Exporter{
278-
Type: exp.Type,
279-
Attrs: exp.Attrs,
295+
Type: exp.Type,
296+
Attrs: exp.Attrs,
297+
Target: target,
280298
})
281299
}
282300

0 commit comments

Comments
 (0)