From cc8d86b37009c78269992be15108151ec52ff678 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Thu, 12 Oct 2023 19:49:49 +0200 Subject: [PATCH] driver(docker): opt to set additional dial meta to the client Signed-off-by: CrazyMax --- builder/builder.go | 4 ++-- builder/node.go | 17 ++++++++++++----- commands/create.go | 2 +- driver/docker-container/driver.go | 4 ++-- driver/docker-container/factory.go | 2 +- driver/docker/driver.go | 15 ++++++++++----- driver/docker/factory.go | 9 +++++++-- driver/driver.go | 4 ++-- driver/kubernetes/driver.go | 4 ++-- driver/kubernetes/factory.go | 2 +- driver/manager.go | 16 ++++++++++++---- driver/remote/driver.go | 4 ++-- driver/remote/factory.go | 2 +- 13 files changed, 55 insertions(+), 30 deletions(-) diff --git a/builder/builder.go b/builder/builder.go index 5a877ae86c20..0ff7d93b60c3 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -208,7 +208,7 @@ type driverFactory struct { } // Factory returns the driver factory. -func (b *Builder) Factory(ctx context.Context) (_ driver.Factory, err error) { +func (b *Builder) Factory(ctx context.Context, dialMeta map[string][]string) (_ driver.Factory, err error) { b.driverFactory.once.Do(func() { if b.Driver != "" { b.driverFactory.Factory, err = driver.GetFactory(b.Driver, true) @@ -231,7 +231,7 @@ func (b *Builder) Factory(ctx context.Context) (_ driver.Factory, err error) { if _, err = dockerapi.Ping(ctx); err != nil { return } - b.driverFactory.Factory, err = driver.GetDefaultFactory(ctx, ep, dockerapi, false) + b.driverFactory.Factory, err = driver.GetDefaultFactory(ctx, ep, dockerapi, false, dialMeta) if err != nil { return } diff --git a/builder/node.go b/builder/node.go index edd47e9b1abc..d497decf8960 100644 --- a/builder/node.go +++ b/builder/node.go @@ -47,6 +47,7 @@ type LoadNodesOption func(*loadNodesOptions) type loadNodesOptions struct { data bool cachedClient bool + dialMeta map[string][]string } func WithData() LoadNodesOption { @@ -61,6 +62,12 @@ func WithCachedClient(enabled bool) LoadNodesOption { } } +func WithDialMeta(dialMeta map[string][]string) LoadNodesOption { + return func(o *loadNodesOptions) { + o.dialMeta = dialMeta + } +} + // LoadNodes loads and returns nodes for this builder. // TODO: this should be a method on a Node object and lazy load data for each driver. func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []Node, err error) { @@ -81,7 +88,7 @@ func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []N } }() - factory, err := b.Factory(ctx) + factory, err := b.Factory(ctx, lno.dialMeta) if err != nil { return nil, err } @@ -149,7 +156,7 @@ func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []N node.ImageOpt = imageopt if lno.data { - if err := node.loadData(ctx, lno.cachedClient); err != nil { + if err := node.loadData(ctx, lno); err != nil { node.Err = err } } @@ -200,7 +207,7 @@ func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []N return b.nodes, nil } -func (n *Node) loadData(ctx context.Context, cachedClient bool) error { +func (n *Node) loadData(ctx context.Context, lno loadNodesOptions) error { if n.Driver == nil { return nil } @@ -210,11 +217,11 @@ func (n *Node) loadData(ctx context.Context, cachedClient bool) error { } n.DriverInfo = info if n.DriverInfo.Status == driver.Running { - c, err := n.Driver.Client(ctx, driver.WithCachedClient(cachedClient)) + c, err := n.Driver.Client(ctx, driver.WithCachedClient(lno.cachedClient), driver.WithDialMeta(lno.dialMeta)) if err != nil { return err } - if !cachedClient { + if !lno.cachedClient { defer c.Close() } diff --git a/commands/create.go b/commands/create.go index 874dccd57492..94c122efdacb 100644 --- a/commands/create.go +++ b/commands/create.go @@ -123,7 +123,7 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error { if len(args) > 0 { arg = args[0] } - f, err := driver.GetDefaultFactory(ctx, arg, dockerCli.Client(), true) + f, err := driver.GetDefaultFactory(ctx, arg, dockerCli.Client(), true, nil) if err != nil { return err } diff --git a/driver/docker-container/driver.go b/driver/docker-container/driver.go index 9d9b76099464..53e1fb089c24 100644 --- a/driver/docker-container/driver.go +++ b/driver/docker-container/driver.go @@ -390,7 +390,7 @@ func (d *Driver) Factory() driver.Factory { return d.factory } -func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { +func (d *Driver) Features(ctx context.Context, copts ...driver.ClientOption) map[driver.Feature]bool { return map[driver.Feature]bool{ driver.OCIExporter: true, driver.DockerExporter: true, @@ -399,7 +399,7 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { } } -func (d *Driver) HostGatewayIP(ctx context.Context) (net.IP, error) { +func (d *Driver) HostGatewayIP(ctx context.Context, copts ...driver.ClientOption) (net.IP, error) { return nil, errors.New("host-gateway is not supported by the docker-container driver") } diff --git a/driver/docker-container/factory.go b/driver/docker-container/factory.go index 118d9c5a3c84..1f63df2a026b 100644 --- a/driver/docker-container/factory.go +++ b/driver/docker-container/factory.go @@ -28,7 +28,7 @@ func (*factory) Usage() string { return "docker-container" } -func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient) int { +func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient, copts ...driver.ClientOption) int { if api == nil { return priorityUnsupported } diff --git a/driver/docker/driver.go b/driver/docker/driver.go index 85065ef42b0d..8d625296998f 100644 --- a/driver/docker/driver.go +++ b/driver/docker/driver.go @@ -56,9 +56,14 @@ func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error { } func (d *Driver) Client(ctx context.Context, copts ...driver.ClientOption) (*client.Client, error) { + co := driver.ClientOptions{} + for _, opt := range copts { + opt(&co) + } + opts := []client.ClientOpt{ client.WithContextDialer(func(context.Context, string) (net.Conn, error) { - return d.DockerAPI.DialHijack(ctx, "/grpc", "h2c", nil) + return d.DockerAPI.DialHijack(ctx, "/grpc", "h2c", co.DialMeta) }), client.WithSessionDialer(func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) { return d.DockerAPI.DialHijack(ctx, "/session", proto, meta) }), @@ -79,10 +84,10 @@ type features struct { list map[driver.Feature]bool } -func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { +func (d *Driver) Features(ctx context.Context, copts ...driver.ClientOption) map[driver.Feature]bool { d.features.once.Do(func() { var useContainerdSnapshotter bool - if c, err := d.Client(ctx); err == nil { + if c, err := d.Client(ctx, copts...); err == nil { defer c.Close() workers, _ := c.ListWorkers(ctx) for _, w := range workers { @@ -107,9 +112,9 @@ type hostGateway struct { err error } -func (d *Driver) HostGatewayIP(ctx context.Context) (net.IP, error) { +func (d *Driver) HostGatewayIP(ctx context.Context, copts ...driver.ClientOption) (net.IP, error) { d.hostGateway.once.Do(func() { - c, err := d.Client(ctx) + c, err := d.Client(ctx, copts...) if err != nil { d.hostGateway.err = err return diff --git a/driver/docker/factory.go b/driver/docker/factory.go index 8f2e37bceddc..cea9907edc33 100644 --- a/driver/docker/factory.go +++ b/driver/docker/factory.go @@ -26,12 +26,17 @@ func (*factory) Usage() string { return "docker" } -func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient) int { +func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient, copts ...driver.ClientOption) int { if api == nil { return priorityUnsupported } - c, err := api.DialHijack(ctx, "/grpc", "h2c", nil) + co := driver.ClientOptions{} + for _, opt := range copts { + opt(&co) + } + + c, err := api.DialHijack(ctx, "/grpc", "h2c", co.DialMeta) if err != nil { return priorityUnsupported } diff --git a/driver/driver.go b/driver/driver.go index efd077338e4d..59c607e1a385 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -60,8 +60,8 @@ type Driver interface { Stop(ctx context.Context, force bool) error Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error Client(ctx context.Context, copts ...ClientOption) (*client.Client, error) - Features(ctx context.Context) map[Feature]bool - HostGatewayIP(ctx context.Context) (net.IP, error) + Features(ctx context.Context, copts ...ClientOption) map[Feature]bool + HostGatewayIP(ctx context.Context, copts ...ClientOption) (net.IP, error) IsMobyDriver() bool Config() InitConfig } diff --git a/driver/kubernetes/driver.go b/driver/kubernetes/driver.go index 52e481e35ce2..e7afe6365301 100644 --- a/driver/kubernetes/driver.go +++ b/driver/kubernetes/driver.go @@ -228,7 +228,7 @@ func (d *Driver) Factory() driver.Factory { return d.factory } -func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { +func (d *Driver) Features(ctx context.Context, copts ...driver.ClientOption) map[driver.Feature]bool { return map[driver.Feature]bool{ driver.OCIExporter: true, driver.DockerExporter: d.DockerAPI != nil, @@ -237,6 +237,6 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { } } -func (d *Driver) HostGatewayIP(ctx context.Context) (net.IP, error) { +func (d *Driver) HostGatewayIP(ctx context.Context, copts ...driver.ClientOption) (net.IP, error) { return nil, errors.New("host-gateway is not supported by the kubernetes driver") } diff --git a/driver/kubernetes/factory.go b/driver/kubernetes/factory.go index 044e192d8ad6..fbf5e68faa3f 100644 --- a/driver/kubernetes/factory.go +++ b/driver/kubernetes/factory.go @@ -34,7 +34,7 @@ func (*factory) Usage() string { return DriverName } -func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient) int { +func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient, copts ...driver.ClientOption) int { if api == nil { return priorityUnsupported } diff --git a/driver/manager.go b/driver/manager.go index 84c59e01a9ba..cd0f018b48ba 100644 --- a/driver/manager.go +++ b/driver/manager.go @@ -17,7 +17,7 @@ import ( type Factory interface { Name() string Usage() string - Priority(ctx context.Context, endpoint string, api dockerclient.APIClient) int + Priority(ctx context.Context, endpoint string, api dockerclient.APIClient, copts ...ClientOption) int New(ctx context.Context, cfg InitConfig) (Driver, error) AllowsInstances() bool } @@ -70,7 +70,7 @@ func Register(f Factory) { drivers[f.Name()] = f } -func GetDefaultFactory(ctx context.Context, ep string, c dockerclient.APIClient, instanceRequired bool) (Factory, error) { +func GetDefaultFactory(ctx context.Context, ep string, c dockerclient.APIClient, instanceRequired bool, dialMeta map[string][]string) (Factory, error) { if len(drivers) == 0 { return nil, errors.Errorf("no drivers available") } @@ -83,7 +83,7 @@ func GetDefaultFactory(ctx context.Context, ep string, c dockerclient.APIClient, if instanceRequired && !f.AllowsInstances() { continue } - dd = append(dd, p{f: f, priority: f.Priority(ctx, ep, c)}) + dd = append(dd, p{f: f, priority: f.Priority(ctx, ep, c, WithDialMeta(dialMeta))}) } sort.Slice(dd, func(i, j int) bool { return dd[i].priority < dd[j].priority @@ -118,7 +118,7 @@ func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string, } if f == nil { var err error - f, err = GetDefaultFactory(ctx, endpointAddr, api, false) + f, err = GetDefaultFactory(ctx, endpointAddr, api, false, nil) if err != nil { return nil, err } @@ -182,6 +182,8 @@ type ClientOption func(*ClientOptions) type ClientOptions struct { cachedClient bool + + DialMeta map[string][]string } func WithCachedClient(enabled bool) ClientOption { @@ -189,3 +191,9 @@ func WithCachedClient(enabled bool) ClientOption { o.cachedClient = enabled } } + +func WithDialMeta(dialMeta map[string][]string) ClientOption { + return func(o *ClientOptions) { + o.DialMeta = dialMeta + } +} diff --git a/driver/remote/driver.go b/driver/remote/driver.go index 2c96ad253816..75f9c9e1affc 100644 --- a/driver/remote/driver.go +++ b/driver/remote/driver.go @@ -84,7 +84,7 @@ func (d *Driver) Client(ctx context.Context, copts ...driver.ClientOption) (*cli return client.New(ctx, d.InitConfig.EndpointAddr, opts...) } -func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { +func (d *Driver) Features(ctx context.Context, copts ...driver.ClientOption) map[driver.Feature]bool { return map[driver.Feature]bool{ driver.OCIExporter: true, driver.DockerExporter: true, @@ -93,7 +93,7 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { } } -func (d *Driver) HostGatewayIP(ctx context.Context) (net.IP, error) { +func (d *Driver) HostGatewayIP(ctx context.Context, copts ...driver.ClientOption) (net.IP, error) { return nil, errors.New("host-gateway is not supported by the remote driver") } diff --git a/driver/remote/factory.go b/driver/remote/factory.go index 374d97d5b82b..09019f6cce61 100644 --- a/driver/remote/factory.go +++ b/driver/remote/factory.go @@ -35,7 +35,7 @@ func (*factory) Usage() string { return "remote" } -func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient) int { +func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient, copts ...driver.ClientOption) int { if util.IsValidEndpoint(endpoint) != nil { return priorityUnsupported }