diff --git a/podman/domain/containers_create.py b/podman/domain/containers_create.py index 80d7f7c8..da6c92df 100644 --- a/podman/domain/containers_create.py +++ b/podman/domain/containers_create.py @@ -383,6 +383,30 @@ def create( return self.get(container_id) + @staticmethod + def _convert_env_list_to_dict(env_list): + """Convert a list of environment variables to a dictionary. + + Args: + env_list (List[str]): List of environment variables in the format ["KEY=value"] + + Returns: + Dict[str, str]: Dictionary of environment variables + + Raises: + ValueError: If any environment variable is not in the correct format + """ + env_dict = {} + for env_var in env_list: + if '=' not in env_var: + raise ValueError( + f"Environment variable '{env_var}' is not in the correct format. " + "Expected format: 'KEY=value'" + ) + key, value = env_var.split('=', 1) # Split on first '=' only + env_dict[key] = value + return env_dict + # pylint: disable=too-many-locals,too-many-statements,too-many-branches @staticmethod def _render_payload(kwargs: MutableMapping[str, Any]) -> dict[str, Any]: @@ -410,6 +434,23 @@ def _render_payload(kwargs: MutableMapping[str, Any]) -> dict[str, Any]: with suppress(KeyError): del args[key] + # Handle environment variables + environment = args.pop("environment", None) + if environment is not None: + if isinstance(environment, list): + try: + environment = CreateMixin._convert_env_list_to_dict(environment) + except ValueError as e: + raise ValueError( + "Failed to convert environment variables list to dictionary. " + f"Error: {str(e)}" + ) from e + elif not isinstance(environment, dict): + raise TypeError( + "Environment variables must be provided as either a dictionary " + "or a list of strings in the format ['KEY=value']" + ) + # These keywords are not supported for various reasons. unsupported_keys = set(args.keys()).intersection( ( @@ -490,7 +531,7 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]: "dns_search": pop("dns_search"), "dns_server": pop("dns"), "entrypoint": pop("entrypoint"), - "env": pop("environment"), + "env": environment, "env_host": pop("env_host"), # TODO document, podman only "expose": {}, "groups": pop("group_add"), diff --git a/podman/tests/integration/test_container_create.py b/podman/tests/integration/test_container_create.py index 2c4b56d9..a530b98d 100644 --- a/podman/tests/integration/test_container_create.py +++ b/podman/tests/integration/test_container_create.py @@ -102,6 +102,44 @@ def test_container_extra_hosts(self): for hosts_entry in formatted_hosts: self.assertIn(hosts_entry, logs) + def test_container_environment_variables(self): + """Test environment variables passed to the container.""" + with self.subTest("Check environment variables as dictionary"): + env_dict = {"MY_VAR": "123", "ANOTHER_VAR": "456"} + container = self.client.containers.create( + self.alpine_image, command=["env"], environment=env_dict + ) + self.containers.append(container) + + container_env = container.attrs.get('Config', {}).get('Env', []) + for key, value in env_dict.items(): + self.assertIn(f"{key}={value}", container_env) + + container.start() + container.wait() + logs = b"\n".join(container.logs()).decode() + + for key, value in env_dict.items(): + self.assertIn(f"{key}={value}", logs) + + with self.subTest("Check environment variables as list"): + env_list = ["MY_VAR=123", "ANOTHER_VAR=456"] + container = self.client.containers.create( + self.alpine_image, command=["env"], environment=env_list + ) + self.containers.append(container) + + container_env = container.attrs.get('Config', {}).get('Env', []) + for env in env_list: + self.assertIn(env, container_env) + + container.start() + container.wait() + logs = b"\n".join(container.logs()).decode() + + for env in env_list: + self.assertIn(env, logs) + def _test_memory_limit(self, parameter_name, host_config_name, set_mem_limit=False): """Base for tests which checks memory limits""" memory_limit_tests = [