Repository: compose-spec/compose-go
Pull request #627 (2024-05-14 11:35:54)

Add driver_opts to services.networks
It's possible to set driver options when creating a network using compose ... [compose spec](https://github.com/robmry/compose-go/blob/b08e2159a8b1fd78444c2ef434bd4913d74697d1/schema/compose-spec.json#L637-L641) / [engine API](https://github.com/moby/moby/blob/9d07820b221db010bf1bdc26ca904468804ca712/api/swagger.yaml#L10134-L10138).

But, not when connecting an endpoint to a network ... [compose spec](https://github.com/robmry/compose-go/blob/b08e2159a8b1fd78444c2ef434bd4913d74697d1/schema/compose-spec.json#L293-L300) / [engine API](https://github.com/moby/moby/blob/9d07820b221db010bf1bdc26ca904468804ca712/api/swagger.yaml#L2541-L2544).

The API field isn't new, but upcoming change https://github.com/moby/moby/pull/47686 means it'll be useful for setting per-interface sysctls.

This PR adds the field.
- A corresponding change will be needed in `compose-spec`, and
- `compose` will need an update to copy the driver options into the engine API's `EndpointSettings`.


Patch:
diff --git a/schema/compose-spec.json b/schema/compose-spec.json
index cbe51db..33a79e9 100644
--- a/schema/compose-spec.json
+++ b/schema/compose-spec.json
@@ -296,6 +296,12 @@
                         "ipv6_address": {"type": "string"},
                         "link_local_ips": {"$ref": "#/definitions/list_of_strings"},
                         "mac_address": {"type": "string"},
+                        "driver_opts": {
+                          "type": "object",
+                          "patternProperties": {
+                            "^.+$": {"type": ["string", "number"]}
+                          }
+                        },
                         "priority": {"type": "number"}
                       },
                       "additionalProperties": false,
diff --git a/types/types.go b/types/types.go
index 466454c..00b1ac1 100644
--- a/types/types.go
+++ b/types/types.go
@@ -453,6 +453,7 @@ type ServiceNetworkConfig struct {
 	Ipv6Address  string   `yaml:"ipv6_address,omitempty" json:"ipv6_address,omitempty"`
 	LinkLocalIPs []string `yaml:"link_local_ips,omitempty" json:"link_local_ips,omitempty"`
 	MacAddress   string   `yaml:"mac_address,omitempty" json:"mac_address,omitempty"`
+	DriverOpts   Options  `yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"`
 
 	Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 }


Test patch:
diff --git a/loader/loader_test.go b/loader/loader_test.go
index df6beb9..cfaba03 100644
--- a/loader/loader_test.go
+++ b/loader/loader_test.go
@@ -1727,6 +1727,49 @@ networks:
 	assert.DeepEqual(t, config, expected, cmpopts.EquateEmpty())
 }
 
+func TestLoadServiceNetworkDriverOpts(t *testing.T) {
+	config, err := loadYAML(`
+name: load-service-network-driver-opts
+services:
+  foo:
+    image: alpine
+    networks:
+      network1:
+        driver_opts:
+          com.docker.network.endpoint.sysctls: "ipv6.conf.accept_ra=0"
+networks:
+  network1:
+`)
+	assert.NilError(t, err)
+
+	workingDir, err := os.Getwd()
+	assert.NilError(t, err)
+	expected := &types.Project{
+		Name:       "load-service-network-driver-opts",
+		WorkingDir: workingDir,
+		Services: types.Services{
+			"foo": {
+				Name:  "foo",
+				Image: "alpine",
+				Networks: map[string]*types.ServiceNetworkConfig{
+					"network1": {
+						DriverOpts: types.Options{
+							"com.docker.network.endpoint.sysctls": "ipv6.conf.accept_ra=0",
+						},
+					},
+				},
+			},
+		},
+		Networks: map[string]types.NetworkConfig{
+			"network1": {},
+		},
+		Environment: types.Mapping{
+			"COMPOSE_PROJECT_NAME": "load-service-network-driver-opts",
+		},
+	}
+	assert.DeepEqual(t, config, expected, cmpopts.EquateEmpty())
+}
+
 func TestLoadInit(t *testing.T) {
 	booleanTrue := true
 	booleanFalse := false