Repository: compose-spec/compose-go
Pull request #730 (2025-01-22 10:28:05)

Add enable_ipv4 (for moby 28.0)
- related to https://github.com/compose-spec/compose-spec/pull/551

Add `enable_ipv4` - coming in moby 28.0.


Patch:
diff --git a/loader/interpolate.go b/loader/interpolate.go
index a1cef1e..481c66b 100644
--- a/loader/interpolate.go
+++ b/loader/interpolate.go
@@ -64,6 +64,7 @@ var interpolateTypeCastMapping = map[tree.Path]interp.Cast{
 	iPath("networks", tree.PathMatchAll, "external"):               toBoolean,
 	iPath("networks", tree.PathMatchAll, "internal"):               toBoolean,
 	iPath("networks", tree.PathMatchAll, "attachable"):             toBoolean,
+	iPath("networks", tree.PathMatchAll, "enable_ipv4"):            toBoolean,
 	iPath("networks", tree.PathMatchAll, "enable_ipv6"):            toBoolean,
 	iPath("volumes", tree.PathMatchAll, "external"):                toBoolean,
 	iPath("secrets", tree.PathMatchAll, "external"):                toBoolean,
diff --git a/schema/compose-spec.json b/schema/compose-spec.json
index f95a7b9..a228d19 100644
--- a/schema/compose-spec.json
+++ b/schema/compose-spec.json
@@ -743,6 +743,7 @@
           "patternProperties": {"^x-": {}}
         },
         "internal": {"type": ["boolean", "string"]},
+        "enable_ipv4": {"type": ["boolean", "string"]},
         "enable_ipv6": {"type": ["boolean", "string"]},
         "attachable": {"type": ["boolean", "string"]},
         "labels": {"$ref": "#/definitions/list_or_dict"}
diff --git a/types/derived.gen.go b/types/derived.gen.go
index f4f2db5..445d1cd 100644
--- a/types/derived.gen.go
+++ b/types/derived.gen.go
@@ -1452,6 +1452,12 @@ func deriveDeepCopy_24(dst, src *NetworkConfig) {
 	} else {
 		dst.CustomLabels = nil
 	}
+	if src.EnableIPv4 == nil {
+		dst.EnableIPv4 = nil
+	} else {
+		dst.EnableIPv4 = new(bool)
+		*dst.EnableIPv4 = *src.EnableIPv4
+	}
 	if src.EnableIPv6 == nil {
 		dst.EnableIPv6 = nil
 	} else {
diff --git a/types/types.go b/types/types.go
index 5da8b85..83ad830 100644
--- a/types/types.go
+++ b/types/types.go
@@ -688,6 +688,7 @@ type NetworkConfig struct {
 	Attachable   bool       `yaml:"attachable,omitempty" json:"attachable,omitempty"`
 	Labels       Labels     `yaml:"labels,omitempty" json:"labels,omitempty"`
 	CustomLabels Labels     `yaml:"-" json:"-"`
+	EnableIPv4   *bool      `yaml:"enable_ipv4,omitempty" json:"enable_ipv4,omitempty"`
 	EnableIPv6   *bool      `yaml:"enable_ipv6,omitempty" json:"enable_ipv6,omitempty"`
 	Extensions   Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 }


Test patch:
diff --git a/loader/loader_test.go b/loader/loader_test.go
index 2020954..fbe9387 100644
--- a/loader/loader_test.go
+++ b/loader/loader_test.go
@@ -1725,6 +1725,54 @@ networks:
 	assert.DeepEqual(t, config, expected, cmpopts.EquateEmpty())
 }
 
+func TestLoadIPv6Only(t *testing.T) {
+	config, err := loadYAML(`
+name: load-network-ipv6only
+services:
+  foo:
+    image: alpine
+    networks:
+      network1:
+networks:
+  network1:
+    driver: bridge
+    enable_ipv4: false
+    enable_ipv6: true
+    name: network1
+`)
+	assert.NilError(t, err)
+
+	workingDir, err := os.Getwd()
+	assert.NilError(t, err)
+	enableIPv4 := false
+	enableIPv6 := true
+	expected := &types.Project{
+		Name:       "load-network-ipv6only",
+		WorkingDir: workingDir,
+		Services: types.Services{
+			"foo": {
+				Name:  "foo",
+				Image: "alpine",
+				Networks: map[string]*types.ServiceNetworkConfig{
+					"network1": nil,
+				},
+			},
+		},
+		Networks: map[string]types.NetworkConfig{
+			"network1": {
+				Name:       "network1",
+				Driver:     "bridge",
+				EnableIPv4: &enableIPv4,
+				EnableIPv6: &enableIPv6,
+			},
+		},
+		Environment: types.Mapping{
+			"COMPOSE_PROJECT_NAME": "load-network-ipv6only",
+		},
+	}
+	assert.DeepEqual(t, config, expected, cmpopts.EquateEmpty())
+}
+
 func TestLoadNetworkLinkLocalIPs(t *testing.T) {
 	config, err := loadYAML(`
 name: load-network-link-local-ips