Skip to content

Commit 17df884

Browse files
committed
client: allow grpc dial option passthrough
This allows consumers of buildkit's client API to manually specify grpc options, such as underlying transport details, or creating interceptors for requests. All custom options are appended *after* the internal options, to allow for more specific overrides if desired. Additionally, to prevent accidentally overwriding the internal interceptors, we switch the client to using `WithChain{Unary,Stream}Interceptor` instead of the singular form, which will overwrite if multiple are specified. Signed-off-by: Justin Chadwell <[email protected]>
1 parent 1c6a500 commit 17df884

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

client/client.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
contentapi "github.com/containerd/containerd/api/services/content/v1"
1313
"github.com/containerd/containerd/defaults"
14-
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
1514
controlapi "github.com/moby/buildkit/api/services/control"
1615
"github.com/moby/buildkit/client/connhelper"
1716
"github.com/moby/buildkit/session"
@@ -54,6 +53,7 @@ func New(ctx context.Context, address string, opts ...ClientOpt) (*Client, error
5453
var tracerProvider trace.TracerProvider
5554
var tracerDelegate TracerDelegate
5655
var sessionDialer func(context.Context, string, map[string][]string) (net.Conn, error)
56+
var customDialOptions []grpc.DialOption
5757

5858
for _, o := range opts {
5959
if _, ok := o.(*withFailFast); ok {
@@ -82,6 +82,9 @@ func New(ctx context.Context, address string, opts ...ClientOpt) (*Client, error
8282
if sd, ok := o.(*withSessionDialer); ok {
8383
sessionDialer = sd.dialer
8484
}
85+
if opt, ok := o.(grpc.DialOption); ok {
86+
customDialOptions = append(customDialOptions, opt)
87+
}
8588
}
8689

8790
if !customTracer {
@@ -131,17 +134,9 @@ func New(ctx context.Context, address string, opts ...ClientOpt) (*Client, error
131134
unary = append(unary, grpcerrors.UnaryClientInterceptor)
132135
stream = append(stream, grpcerrors.StreamClientInterceptor)
133136

134-
if len(unary) == 1 {
135-
gopts = append(gopts, grpc.WithUnaryInterceptor(unary[0]))
136-
} else if len(unary) > 1 {
137-
gopts = append(gopts, grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(unary...)))
138-
}
139-
140-
if len(stream) == 1 {
141-
gopts = append(gopts, grpc.WithStreamInterceptor(stream[0]))
142-
} else if len(stream) > 1 {
143-
gopts = append(gopts, grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(stream...)))
144-
}
137+
gopts = append(gopts, grpc.WithChainUnaryInterceptor(unary...))
138+
gopts = append(gopts, grpc.WithChainStreamInterceptor(stream...))
139+
gopts = append(gopts, customDialOptions...)
145140

146141
conn, err := grpc.DialContext(ctx, address, gopts...)
147142
if err != nil {

client/client_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import (
6565
"github.com/stretchr/testify/require"
6666
"golang.org/x/crypto/ssh/agent"
6767
"golang.org/x/sync/errgroup"
68+
"google.golang.org/grpc"
6869
)
6970

7071
func init() {
@@ -195,6 +196,7 @@ func TestIntegration(t *testing.T) {
195196
testMountStubsTimestamp,
196197
testSourcePolicy,
197198
testLLBMountPerformance,
199+
testClientCustomGRPCOpts,
198200
)
199201
}
200202

@@ -9020,3 +9022,22 @@ func testLLBMountPerformance(t *testing.T, sb integration.Sandbox) {
90209022
_, err = c.Solve(timeoutCtx, def, SolveOpt{}, nil)
90219023
require.NoError(t, err)
90229024
}
9025+
9026+
func testClientCustomGRPCOpts(t *testing.T, sb integration.Sandbox) {
9027+
var interceptedMethods []string
9028+
intercept := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
9029+
interceptedMethods = append(interceptedMethods, method)
9030+
return invoker(ctx, method, req, reply, cc, opts...)
9031+
}
9032+
c, err := New(sb.Context(), sb.Address(), grpc.WithChainUnaryInterceptor(intercept))
9033+
require.NoError(t, err)
9034+
defer c.Close()
9035+
9036+
st := llb.Image("busybox:latest")
9037+
def, err := st.Marshal(sb.Context())
9038+
require.NoError(t, err)
9039+
_, err = c.Solve(sb.Context(), def, SolveOpt{}, nil)
9040+
require.NoError(t, err)
9041+
9042+
require.Contains(t, interceptedMethods, "/moby.buildkit.v1.Control/Solve")
9043+
}

0 commit comments

Comments
 (0)