From b202a09501fd71f45e1aded1261d0d10f24ffb26 Mon Sep 17 00:00:00 2001 From: Alexandre Germain Date: Fri, 3 May 2024 15:31:23 +0200 Subject: [PATCH] Add support for `env_file` as objects Fixes: https://github.com/containers/podman-compose/issues/897 Signed-off-by: Alexandre Germain --- podman_compose.py | 12 ++- pytests/test_container_to_args.py | 91 +++++++++++++++++++ tests/env-file-tests/README.md | 12 +++ .../container-compose.env-file-flat.yaml | 9 ++ ...ntainer-compose.env-file-obj-optional.yaml | 11 +++ .../container-compose.env-file-obj.yaml | 9 ++ 6 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 tests/env-file-tests/project/container-compose.env-file-flat.yaml create mode 100644 tests/env-file-tests/project/container-compose.env-file-obj-optional.yaml create mode 100644 tests/env-file-tests/project/container-compose.env-file-obj.yaml diff --git a/podman_compose.py b/podman_compose.py index 61709d3..daba7fb 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -993,10 +993,18 @@ async def container_to_args(compose, cnt, detached=True): for item in norm_as_list(cnt.get("dns_search", None)): podman_args.extend(["--dns-search", item]) env_file = cnt.get("env_file", []) - if is_str(env_file): + if is_str(env_file) or is_dict(env_file): env_file = [env_file] for i in env_file: - i = os.path.realpath(os.path.join(dirname, i)) + if is_str(i): + i = {"path": i} + path = i["path"] + required = i.get("required", True) + i = os.path.realpath(os.path.join(dirname, path)) + if not os.path.exists(i): + if not required: + continue + raise ValueError("Env file at {} does not exist".format(i)) podman_args.extend(["--env-file", i]) env = norm_as_list(cnt.get("environment", {})) for e in env: diff --git a/pytests/test_container_to_args.py b/pytests/test_container_to_args.py index a4718f0..883b48a 100644 --- a/pytests/test_container_to_args.py +++ b/pytests/test_container_to_args.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 import unittest +from os import path from unittest import mock from podman_compose import container_to_args @@ -234,3 +235,93 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase): "/path/to/rootfs", ], ) + + async def test_env_file_str(self): + c = create_compose_mock() + + cnt = get_minimal_container() + env_file = path.realpath('tests/env-file-tests/env-files/project-1.env') + cnt['env_file'] = env_file + + args = await container_to_args(c, cnt) + self.assertEqual( + args, + [ + "--name=project_name_service_name1", + "-d", + "--env-file", + env_file, + "--network=bridge", + "--network-alias=service_name", + "busybox", + ], + ) + + async def test_env_file_str_not_exists(self): + c = create_compose_mock() + + cnt = get_minimal_container() + cnt['env_file'] = 'notexists' + + with self.assertRaises(ValueError): + await container_to_args(c, cnt) + + async def test_env_file_str_arr(self): + c = create_compose_mock() + + cnt = get_minimal_container() + env_file = path.realpath('tests/env-file-tests/env-files/project-1.env') + cnt['env_file'] = [env_file] + + args = await container_to_args(c, cnt) + self.assertEqual( + args, + [ + "--name=project_name_service_name1", + "-d", + "--env-file", + env_file, + "--network=bridge", + "--network-alias=service_name", + "busybox", + ], + ) + + async def test_env_file_obj_required(self): + c = create_compose_mock() + + cnt = get_minimal_container() + env_file = path.realpath('tests/env-file-tests/env-files/project-1.env') + cnt['env_file'] = {'path': env_file, 'required': True} + + args = await container_to_args(c, cnt) + self.assertEqual( + args, + [ + "--name=project_name_service_name1", + "-d", + "--env-file", + env_file, + "--network=bridge", + "--network-alias=service_name", + "busybox", + ], + ) + + async def test_env_file_obj_optional(self): + c = create_compose_mock() + + cnt = get_minimal_container() + cnt['env_file'] = {'path': 'not-exists', 'required': False} + + args = await container_to_args(c, cnt) + self.assertEqual( + args, + [ + "--name=project_name_service_name1", + "-d", + "--network=bridge", + "--network-alias=service_name", + "busybox", + ], + ) diff --git a/tests/env-file-tests/README.md b/tests/env-file-tests/README.md index 0e4614e..b5f4fa9 100644 --- a/tests/env-file-tests/README.md +++ b/tests/env-file-tests/README.md @@ -7,3 +7,15 @@ podman-compose -f project/container-compose.yaml --env-file env-files/project-1. ``` podman-compose -f $(pwd)/project/container-compose.yaml --env-file $(pwd)/env-files/project-1.env up ``` + +``` +podman-compose -f $(pwd)/project/container-compose.env-file-flat.yaml up +``` + +``` +podman-compose -f $(pwd)/project/container-compose.env-file-obj.yaml up +``` + +``` +podman-compose -f $(pwd)/project/container-compose.env-file-obj-optional.yaml up +``` diff --git a/tests/env-file-tests/project/container-compose.env-file-flat.yaml b/tests/env-file-tests/project/container-compose.env-file-flat.yaml new file mode 100644 index 0000000..4e010ac --- /dev/null +++ b/tests/env-file-tests/project/container-compose.env-file-flat.yaml @@ -0,0 +1,9 @@ +services: + app: + image: busybox + command: ["/bin/busybox", "sh", "-c", "env | grep ZZ"] + tmpfs: + - /run + - /tmp + env_file: + - ../env-files/project-1.env diff --git a/tests/env-file-tests/project/container-compose.env-file-obj-optional.yaml b/tests/env-file-tests/project/container-compose.env-file-obj-optional.yaml new file mode 100644 index 0000000..cfcdb64 --- /dev/null +++ b/tests/env-file-tests/project/container-compose.env-file-obj-optional.yaml @@ -0,0 +1,11 @@ +services: + app: + image: busybox + command: ["/bin/busybox", "sh", "-c", "env | grep ZZ"] + tmpfs: + - /run + - /tmp + env_file: + - path: ../env-files/project-1.env + - path: ../env-files/project-2.env + required: false diff --git a/tests/env-file-tests/project/container-compose.env-file-obj.yaml b/tests/env-file-tests/project/container-compose.env-file-obj.yaml new file mode 100644 index 0000000..a7e35a3 --- /dev/null +++ b/tests/env-file-tests/project/container-compose.env-file-obj.yaml @@ -0,0 +1,9 @@ +services: + app: + image: busybox + command: ["/bin/busybox", "sh", "-c", "env | grep ZZ"] + tmpfs: + - /run + - /tmp + env_file: + - path: ../env-files/project-1.env