Skip to content

Commit

Permalink
Merge pull request #1088 from lisongmin/feat-default-net-behavior-compat
Browse files Browse the repository at this point in the history
Support docker-compose like default network behavior
  • Loading branch information
p12tic authored Dec 18, 2024
2 parents 376f081 + 420d19d commit d803c4c
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 5 deletions.
20 changes: 20 additions & 0 deletions docs/Extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@ x-podman:
By default `default_net_name_compat` is `false`. This will change to `true` at some point and the
setting will be removed.

## Compatibility of default network behavior between docker-compose and podman-compose

When there is no network defined (neither network-mode nor networks) in service,
The behavior of default network in docker-compose and podman-compose are different.

| Top-level networks | podman-compose | docker-compose |
| ------------------------------ | -------------------------- | -------------- |
| No networks | default | default |
| One network named net0 | net0 | default |
| Two networks named net0, net1 | podman(`--network=bridge`) | default |
| Contains network named default | default | default |

To enable compatibility between docker-compose and podman-compose, specify
`default_net_behavior_compat: true` under global `x-podman` key:

```yaml
x-podman:
default_net_behavior_compat: true
```

## Custom pods management

Podman-compose can have containers in pods. This can be controlled by extension key x-podman in_pod.
Expand Down
2 changes: 2 additions & 0 deletions newsfragments/default_net_behavior_compat.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Support docker-compose like default network behavior when no network defined in service via `default_net_behavior_compat` feature flag.

20 changes: 15 additions & 5 deletions podman_compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -1998,13 +1998,23 @@ def _parse_compose_file(self):
nets = compose.get("networks", {})
if not nets:
nets["default"] = None

self.networks = nets
if len(self.networks) == 1:
self.default_net = list(nets.keys())[0]
elif "default" in nets:
self.default_net = "default"
if compose.get("x-podman", {}).get("default_net_behavior_compat", False):
# If there is no network_mode and networks in service,
# docker-compose will create default network named '<project_name>_default'
# and add the service to the default network.
# So we always set `default_net = 'default'` for compatibility
if "default" not in self.networks:
self.networks["default"] = None
else:
self.default_net = None
if len(self.networks) == 1:
self.default_net = list(nets.keys())[0]
elif "default" in nets:
self.default_net = "default"
else:
self.default_net = None

allnets = set()
for name, srv in services.items():
srv_nets = srv.get("networks", self.default_net)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
web:
image: busybox
command: httpd -f -p 8123 -h /tmp/
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
web:
image: busybox
command: httpd -f -p 8123 -h /tmp/

x-podman:
default_net_behavior_compat: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
web:
image: busybox
command: httpd -f -p 8123 -h /tmp/

networks:
net0: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
web:
image: busybox
command: httpd -f -p 8123 -h /tmp/

networks:
net0: {}

x-podman:
default_net_behavior_compat: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
web:
image: busybox
command: httpd -f -p 8123 -h /tmp/

networks:
net0: {}
net1: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
web:
image: busybox
command: httpd -f -p 8123 -h /tmp/

networks:
net0: {}
net1: {}

x-podman:
default_net_behavior_compat: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
web:
image: busybox
command: httpd -f -p 8123 -h /tmp/

networks:
net0: {}
net1: {}
default: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
web:
image: busybox
command: httpd -f -p 8123 -h /tmp/

networks:
net0: {}
net1: {}
default: {}

x-podman:
default_net_behavior_compat: true
65 changes: 65 additions & 0 deletions tests/integration/test_podman_compose_default_net_behavior.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# SPDX-License-Identifier: GPL-2.0

import os
import unittest

from parameterized import parameterized

from tests.integration.test_podman_compose import podman_compose_path
from tests.integration.test_podman_compose import test_path
from tests.integration.test_utils import RunSubprocessMixin


def compose_yaml_path(scenario):
return os.path.join(
os.path.join(test_path(), "default_net_behavior"), f"docker-compose_{scenario}.yaml"
)


class TestComposeDefaultNetBehavior(unittest.TestCase, RunSubprocessMixin):
@parameterized.expand([
('no_nets', 'default_net_behavior_default'),
('one_net', 'default_net_behavior_net0'),
('two_nets', 'podman'),
('with_default', 'default_net_behavior_default'),
('no_nets_compat', 'default_net_behavior_default'),
('one_net_compat', 'default_net_behavior_default'),
('two_nets_compat', 'default_net_behavior_default'),
('with_default_compat', 'default_net_behavior_default'),
])
def test_nethost(self, scenario, default_net):
try:
self.run_subprocess_assert_returncode(
[podman_compose_path(), "-f", compose_yaml_path(scenario), "up", "-d"],
)

container_id, _ = self.run_subprocess_assert_returncode(
[
podman_compose_path(),
"-f",
compose_yaml_path(scenario),
"ps",
"--format",
'{{.ID}}',
],
)
container_id = container_id.decode('utf-8').split('\n')[0]
output, _ = self.run_subprocess_assert_returncode(
[
"podman",
"inspect",
container_id,
"--format",
"{{range $key, $value := .NetworkSettings.Networks }}{{ $key }}\n{{ end }}",
],
)
self.assertEqual(output.decode('utf-8').strip(), default_net)
finally:
self.run_subprocess_assert_returncode([
podman_compose_path(),
"-f",
compose_yaml_path(scenario),
"down",
"-t",
"0",
])

0 comments on commit d803c4c

Please sign in to comment.