diff --git a/docs/Extensions.md b/docs/Extensions.md index bd3c7ef..879d0b4 100644 --- a/docs/Extensions.md +++ b/docs/Extensions.md @@ -139,6 +139,24 @@ The options to the network modes are passed to the `--network` option of the `po as-is. +## Docker Compose Compatibility + +podman-compose aims to be compatible with docker-compose, but there are some differences in +behavior and features. The following sections describe how to enable compatibility with docker-compose +and how to handle some of the differences. + +Compatibility settings can either be set explicitly as described below, or by setting the `docker_compose_compat` meta +settings to `true` under the global `x-podman` key: + +```yaml +x-podman: + docker_compose_compat: true +``` + +This will enable all compatibility settings described below, and is equivalent to setting each of them to `true`. + +This setting can also be changed by setting the `PODMAN_COMPOSE_DOCKER_COMPOSE_COMPAT` environment variable. + ## Compatibility of name separators between docker-compose and podman-compose Currently, podman-compose is using underscores (`_` character) as a separator in names of diff --git a/newsfragments/docker-compose-compat.feature b/newsfragments/docker-compose-compat.feature new file mode 100644 index 0000000..0a75cfc --- /dev/null +++ b/newsfragments/docker-compose-compat.feature @@ -0,0 +1 @@ +- Add new docker_compose_compat x-podman meta setting to enable all Docker Compose compatibility settings diff --git a/podman_compose.py b/podman_compose.py index 78446b5..ab462f3 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -1957,6 +1957,7 @@ COMPOSE_DEFAULT_LS = [ class PodmanCompose: class XPodmanSettingKey(Enum): + DOCKER_COMPOSE_COMPAT = "docker_compose_compat" DEFAULT_NET_NAME_COMPAT = "default_net_name_compat" DEFAULT_NET_BEHAVIOR_COMPAT = "default_net_behavior_compat" NAME_SEPARATOR_COMPAT = "name_separator_compat" @@ -2127,6 +2128,20 @@ class PodmanCompose: ", ".join(known_keys.keys()), ) + # If Docker Compose compatibility is enabled, set compatibility settings + # that are not explicitly set already. + if self.x_podman.get(PodmanCompose.XPodmanSettingKey.DOCKER_COMPOSE_COMPAT, False): + + def set_if_not_already_set(key: PodmanCompose.XPodmanSettingKey, value: bool) -> None: + if key not in self.x_podman: + self.x_podman[key] = value + + set_if_not_already_set( + PodmanCompose.XPodmanSettingKey.DEFAULT_NET_BEHAVIOR_COMPAT, True + ) + set_if_not_already_set(PodmanCompose.XPodmanSettingKey.NAME_SEPARATOR_COMPAT, True) + set_if_not_already_set(PodmanCompose.XPodmanSettingKey.IN_POD, False) + def _parse_compose_file(self) -> None: args = self.global_args # cmd = args.command diff --git a/tests/integration/in_pod/test_podman_compose_in_pod.py b/tests/integration/in_pod/test_podman_compose_in_pod.py index 7b60886..07af8c7 100644 --- a/tests/integration/in_pod/test_podman_compose_in_pod.py +++ b/tests/integration/in_pod/test_podman_compose_in_pod.py @@ -467,6 +467,57 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): # can not actually find this pod because it was not created self.run_subprocess_assert_returncode(command_rm_pod, 1) + def test_x_podman_in_pod_not_exists_command_line_in_pod_not_exists_docker_compat(self) -> None: + """ + Test that podman-compose will not create a pod when docker compat is requested. + """ + command_up = [ + "python3", + os.path.join(base_path(), "podman_compose.py"), + "-f", + os.path.join( + base_path(), + "tests", + "integration", + "in_pod", + "custom_x-podman_not_exists", + "docker-compose.yml", + ), + "up", + "-d", + ] + + down_cmd = [ + "python3", + podman_compose_path(), + "-f", + os.path.join( + base_path(), + "tests", + "integration", + "in_pod", + "custom_x-podman_not_exists", + "docker-compose.yml", + ), + "down", + ] + + env = { + "PODMAN_COMPOSE_DOCKER_COMPOSE_COMPAT": "1", + } + + try: + self.run_subprocess_assert_returncode( + command_up, failure_exitcode_when_rootful(), env=env + ) + + finally: + self.run_subprocess_assert_returncode(down_cmd, env=env) + + command_rm_pod = ["podman", "pod", "rm", "pod_custom_x-podman_not_exists"] + # can not actually find this pod because it was not created + self.run_subprocess_assert_returncode(command_rm_pod, 1) + def test_x_podman_in_pod_not_exists_command_line_in_pod_not_exists_env_var(self) -> None: """ Test that podman-compose will not create a pod when env var is set. diff --git a/tests/integration/name_separator_compat/test_podman_compose_name_separator_compat.py b/tests/integration/name_separator_compat/test_podman_compose_name_separator_compat.py index b4ef710..76750b3 100644 --- a/tests/integration/name_separator_compat/test_podman_compose_name_separator_compat.py +++ b/tests/integration/name_separator_compat/test_podman_compose_name_separator_compat.py @@ -14,6 +14,7 @@ class TestComposeNameSeparatorCompat(unittest.TestCase, RunSubprocessMixin): @parameterized.expand([ ('default', {}, '_'), ('default', {'PODMAN_COMPOSE_NAME_SEPARATOR_COMPAT': '1'}, '-'), + ('default', {'PODMAN_COMPOSE_DOCKER_COMPOSE_COMPAT': '1'}, '-'), ('compat', {}, '-'), ('compat', {'PODMAN_COMPOSE_NAME_SEPARATOR_COMPAT': '1'}, '-'), ('compat', {'PODMAN_COMPOSE_NAME_SEPARATOR_COMPAT': '0'}, '_'),