mirror of
https://github.com/containers/podman-compose.git
synced 2025-06-30 20:50:14 +02:00
Implement short syntax for env variables in compose.yml "environment:"
This commit allows compose file to directly use environment variable values in "environment:" section when variables were set in `.env` file. This functionality was missing, as docker-compose supports both: short and variable interpolation syntax forms: environment: - FOO and environment: - FOO=${FOO} Relevant docker-compose documentation: https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/ podman-compose is more compatible with docker-compose after this change. Signed-off-by: Monika Kairaityte <monika@kibit.lt>
This commit is contained in:
1
newsfragments/fix-short-syntax-env-variables.bugfix
Normal file
1
newsfragments/fix-short-syntax-env-variables.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Implemented short syntax for environment variables set in `.env` for compose.yml "environment:" section.
|
@ -1159,7 +1159,14 @@ async def container_to_args(
|
|||||||
podman_args.extend(["-e", e])
|
podman_args.extend(["-e", e])
|
||||||
env = norm_as_list(cnt.get("environment", {}))
|
env = norm_as_list(cnt.get("environment", {}))
|
||||||
for e in env:
|
for e in env:
|
||||||
podman_args.extend(["-e", e])
|
# new environment variable is set
|
||||||
|
if "=" in e:
|
||||||
|
podman_args.extend(["-e", e])
|
||||||
|
else:
|
||||||
|
# environment variable already exists in environment so pass its value
|
||||||
|
if e in compose.environ.keys():
|
||||||
|
podman_args.extend(["-e", f"{e}={compose.environ[e]}"])
|
||||||
|
|
||||||
tmpfs_ls = cnt.get("tmpfs", [])
|
tmpfs_ls = cnt.get("tmpfs", [])
|
||||||
if isinstance(tmpfs_ls, str):
|
if isinstance(tmpfs_ls, str):
|
||||||
tmpfs_ls = [tmpfs_ls]
|
tmpfs_ls = [tmpfs_ls]
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
ZZVAR1='This value is loaded but should be overwritten'
|
ZZVAR1='This value is loaded but should be overwritten'
|
||||||
ZZVAR2='This value is loaded from .env in project/ directory'
|
ZZVAR2='This value is loaded from .env in project/ directory'
|
||||||
|
ZZVAR3=TEST
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: nopush/podman-compose-test
|
||||||
|
command: ["/bin/busybox", "sh", "-c", "env | grep ZZVAR3"]
|
||||||
|
# 'env_file:' section is not used, so .env file is searched in the same directory as compose.yml
|
||||||
|
# file
|
||||||
|
environment:
|
||||||
|
# this is short syntax: podman-compose takes only this variable value from '.env' file and
|
||||||
|
# sends it to container environment
|
||||||
|
- ZZVAR3
|
@ -233,7 +233,7 @@ class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
|
|||||||
[
|
[
|
||||||
'ZZVAR1=This value is loaded but should be overwritten\r',
|
'ZZVAR1=This value is loaded but should be overwritten\r',
|
||||||
'ZZVAR2=This value is loaded from .env in project/ directory\r',
|
'ZZVAR2=This value is loaded from .env in project/ directory\r',
|
||||||
'ZZVAR3=\r',
|
'ZZVAR3=TEST\r',
|
||||||
'',
|
'',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -244,3 +244,36 @@ class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
|
|||||||
path_compose_file,
|
path_compose_file,
|
||||||
"down",
|
"down",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_env_var_value_accessed_in_compose_file_short_syntax(self) -> None:
|
||||||
|
# Test that compose file can access the environment variable set in .env file using
|
||||||
|
# short syntax, that is: only the name of environment variable is used in "environment:" in
|
||||||
|
# compose.yml file and its value is picked up directly from .env file
|
||||||
|
# long syntax of environment variables interpolation is tested in
|
||||||
|
# tests/integration/interpolation
|
||||||
|
|
||||||
|
base_path = compose_base_path()
|
||||||
|
compose_file_path = os.path.join(base_path, "project/container-compose.short_syntax.yaml")
|
||||||
|
try:
|
||||||
|
self.run_subprocess_assert_returncode([
|
||||||
|
podman_compose_path(),
|
||||||
|
"-f",
|
||||||
|
compose_file_path,
|
||||||
|
"up",
|
||||||
|
"-d",
|
||||||
|
])
|
||||||
|
output, _ = self.run_subprocess_assert_returncode([
|
||||||
|
podman_compose_path(),
|
||||||
|
"-f",
|
||||||
|
compose_file_path,
|
||||||
|
"logs",
|
||||||
|
])
|
||||||
|
# ZZVAR3 was set in .env file
|
||||||
|
self.assertEqual(output, b"ZZVAR3=TEST\n")
|
||||||
|
finally:
|
||||||
|
self.run_subprocess_assert_returncode([
|
||||||
|
podman_compose_path(),
|
||||||
|
"-f",
|
||||||
|
compose_file_path,
|
||||||
|
"down",
|
||||||
|
])
|
||||||
|
@ -262,6 +262,42 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@parameterized.expand([
|
||||||
|
# short syntax: only take this specific environment variable value from .env file
|
||||||
|
("use_env_var_from_default_env_file_short_syntax", ["ZZVAR1"], "ZZVAR1=TEST1"),
|
||||||
|
# long syntax: environment variable value from .env file is taken through variable
|
||||||
|
# interpolation
|
||||||
|
# only the value required in 'environment:' compose file is sent to containers
|
||||||
|
# environment
|
||||||
|
("use_env_var_from_default_env_file_long_syntax", ["ZZVAR1=TEST1"], "ZZVAR1=TEST1"),
|
||||||
|
# "environment:" section in compose file overrides environment variable value from .env file
|
||||||
|
(
|
||||||
|
"use_env_var_from_default_env_file_override_value",
|
||||||
|
["ZZVAR1=NEW_TEST1"],
|
||||||
|
"ZZVAR1=NEW_TEST1",
|
||||||
|
),
|
||||||
|
])
|
||||||
|
async def test_env_file(self, test_name: str, cnt_env: list, expected_var: str) -> None:
|
||||||
|
c = create_compose_mock()
|
||||||
|
# environment variables were set in .env file
|
||||||
|
c.environ = {"ZZVAR1": "TEST1", "ZZVAR2": "TEST2"}
|
||||||
|
|
||||||
|
cnt = get_minimal_container()
|
||||||
|
cnt["environment"] = cnt_env
|
||||||
|
|
||||||
|
args = await container_to_args(c, cnt)
|
||||||
|
self.assertEqual(
|
||||||
|
args,
|
||||||
|
[
|
||||||
|
"--name=project_name_service_name1",
|
||||||
|
"-d",
|
||||||
|
"-e",
|
||||||
|
f"{expected_var}",
|
||||||
|
"--network=bridge:alias=service_name",
|
||||||
|
"busybox",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
async def test_env_file_str(self) -> None:
|
async def test_env_file_str(self) -> None:
|
||||||
c = create_compose_mock()
|
c = create_compose_mock()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user