From 94f9de59280a6147516ed0fcfc915ebf9eb0e563 Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Fri, 7 Jun 2024 09:13:21 +0100 Subject: [PATCH] Handle networks.driver_opts for a service These are endpoint-specific driver options... services: myservice: image: myimage networks: mynet: driver_opts: "option1": "value1" The API has had support for a long time, it's only recently been added to compose (unreleased right now). Signed-off-by: Rob Murray --- cli/compose/convert/service.go | 7 +++++-- cli/compose/convert/service_test.go | 8 ++++++++ cli/compose/loader/full-example.yml | 3 +++ cli/compose/loader/full-struct_test.go | 4 ++++ cli/compose/loader/testdata/full-example.json.golden | 6 +++++- cli/compose/loader/testdata/full-example.yaml.golden | 3 +++ cli/compose/schema/data/config_schema_v3.13.json | 6 ++++++ cli/compose/types/types.go | 7 ++++--- 8 files changed, 38 insertions(+), 6 deletions(-) diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index 4cc4e4a143..ccff547ce9 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -215,16 +215,19 @@ func convertServiceNetworks( return nil, errors.Errorf("undefined network %q", networkName) } var aliases []string + var driverOpts map[string]string if network != nil { aliases = network.Aliases + driverOpts = network.DriverOpts } target := namespace.Scope(networkName) if networkConfig.Name != "" { target = networkConfig.Name } netAttachConfig := swarm.NetworkAttachmentConfig{ - Target: target, - Aliases: aliases, + Target: target, + Aliases: aliases, + DriverOpts: driverOpts, } // Only add default aliases to user defined networks. Other networks do // not support aliases. diff --git a/cli/compose/convert/service_test.go b/cli/compose/convert/service_test.go index c4a01d8bf2..22f585f87c 100644 --- a/cli/compose/convert/service_test.go +++ b/cli/compose/convert/service_test.go @@ -240,6 +240,10 @@ func TestConvertServiceNetworks(t *testing.T) { networks := map[string]*composetypes.ServiceNetworkConfig{ "front": { Aliases: []string{"something"}, + DriverOpts: map[string]string{ + "driver.opt1": "optval1", + "driver.opt2": "optval2", + }, }, "back": { Aliases: []string{"other"}, @@ -257,6 +261,10 @@ func TestConvertServiceNetworks(t *testing.T) { { Target: "fronttier", Aliases: []string{"something", "service"}, + DriverOpts: map[string]string{ + "driver.opt1": "optval1", + "driver.opt2": "optval2", + }, }, } diff --git a/cli/compose/loader/full-example.yml b/cli/compose/loader/full-example.yml index 542f7706bd..36ebf833e7 100644 --- a/cli/compose/loader/full-example.yml +++ b/cli/compose/loader/full-example.yml @@ -207,6 +207,9 @@ services: aliases: - alias1 - alias3 + driver_opts: + "driveropt1": "optval1" + "driveropt2": "optval2" other-network: ipv4_address: 172.16.238.10 ipv6_address: 2001:3984:3989::10 diff --git a/cli/compose/loader/full-struct_test.go b/cli/compose/loader/full-struct_test.go index 1487e8adc6..cd3304eff3 100644 --- a/cli/compose/loader/full-struct_test.go +++ b/cli/compose/loader/full-struct_test.go @@ -190,6 +190,10 @@ func services(workingDir, homeDir string) []types.ServiceConfig { Aliases: []string{"alias1", "alias3"}, Ipv4Address: "", Ipv6Address: "", + DriverOpts: map[string]string{ + "driveropt1": "optval1", + "driveropt2": "optval2", + }, }, "other-network": { Ipv4Address: "172.16.238.10", diff --git a/cli/compose/loader/testdata/full-example.json.golden b/cli/compose/loader/testdata/full-example.json.golden index 758777d33f..c0ef39dabe 100644 --- a/cli/compose/loader/testdata/full-example.json.golden +++ b/cli/compose/loader/testdata/full-example.json.golden @@ -285,7 +285,11 @@ "aliases": [ "alias1", "alias3" - ] + ], + "driver_opts": { + "driveropt1": "optval1", + "driveropt2": "optval2" + } } }, "pid": "host", diff --git a/cli/compose/loader/testdata/full-example.yaml.golden b/cli/compose/loader/testdata/full-example.yaml.golden index 546d1764aa..ec925790ad 100644 --- a/cli/compose/loader/testdata/full-example.yaml.golden +++ b/cli/compose/loader/testdata/full-example.yaml.golden @@ -152,6 +152,9 @@ services: aliases: - alias1 - alias3 + driver_opts: + driveropt1: optval1 + driveropt2: optval2 pid: host ports: - mode: ingress diff --git a/cli/compose/schema/data/config_schema_v3.13.json b/cli/compose/schema/data/config_schema_v3.13.json index 3fd3672204..0a85b3e6c5 100644 --- a/cli/compose/schema/data/config_schema_v3.13.json +++ b/cli/compose/schema/data/config_schema_v3.13.json @@ -197,6 +197,12 @@ "type": "object", "properties": { "aliases": {"$ref": "#/definitions/list_of_strings"}, + "driver_opts": { + "type": "object", + "patternProperties": { + "^.+$": { "type": ["string", "number"] } + } + }, "ipv4_address": {"type": "string"}, "ipv6_address": {"type": "string"} }, diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index f6954ff7f0..f2f68641d3 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -374,9 +374,10 @@ type PlacementPreferences struct { // ServiceNetworkConfig is the network configuration for a service type ServiceNetworkConfig struct { - Aliases []string `yaml:",omitempty" json:"aliases,omitempty"` - Ipv4Address string `mapstructure:"ipv4_address" yaml:"ipv4_address,omitempty" json:"ipv4_address,omitempty"` - Ipv6Address string `mapstructure:"ipv6_address" yaml:"ipv6_address,omitempty" json:"ipv6_address,omitempty"` + Aliases []string `yaml:",omitempty" json:"aliases,omitempty"` + DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` + Ipv4Address string `mapstructure:"ipv4_address" yaml:"ipv4_address,omitempty" json:"ipv4_address,omitempty"` + Ipv6Address string `mapstructure:"ipv6_address" yaml:"ipv6_address,omitempty" json:"ipv6_address,omitempty"` } // ServicePortConfig is the port configuration for a service