Skip to content

Commit

Permalink
Merge pull request #1004 from lisongmin/substitution-with-service-env…
Browse files Browse the repository at this point in the history
…ironment

Substitution with service environment
  • Loading branch information
p12tic committed Jul 26, 2024
2 parents 3aa6d4d + 34f5268 commit 585d344
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add ability to substitute variables with the environment of the service.
15 changes: 15 additions & 0 deletions podman_compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,16 @@ def rec_subs(value, subs_dict):
do bash-like substitution in value and if list of dictionary do that recursively
"""
if is_dict(value):
if 'environment' in value and is_dict(value['environment']):
# Load service's environment variables
subs_dict = subs_dict.copy()
svc_envs = {k: v for k, v in value['environment'].items() if k not in subs_dict}
# we need to add `svc_envs` to the `subs_dict` so that it can evaluate the
# service environment that reference to another service environment.
subs_dict.update(svc_envs)
svc_envs = rec_subs(svc_envs, subs_dict)
subs_dict.update(svc_envs)

value = {k: rec_subs(v, subs_dict) for k, v in value.items()}
elif is_str(value):

Expand Down Expand Up @@ -1823,6 +1833,11 @@ def _parse_compose_file(self):
"COMPOSE_FILE": pathsep.join(relative_files),
"COMPOSE_PATH_SEPARATOR": pathsep,
})

if args and 'env' in args and args.env:
env_vars = norm_as_dict(args.env)
self.environ.update(env_vars)

compose = {}
# Iterate over files primitively to allow appending to files in-loop
files_iter = iter(files)
Expand Down
7 changes: 4 additions & 3 deletions tests/integration/env-tests/container-compose.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
version: '3'
version: "3"

services:
env-test:
image: busybox
command: sh -c "export | grep ZZ"
environment:
- ZZVAR1=myval1

ZZVAR1: myval1
ZZVAR2: 2-$ZZVAR1
ZZVAR3: 3-$ZZVAR2
62 changes: 62 additions & 0 deletions tests/unit/test_rec_subs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# SPDX-License-Identifier: GPL-2.0
# pylint: disable=protected-access

import unittest

from parameterized import parameterized

from podman_compose import rec_subs


class TestRecSubs(unittest.TestCase):
substitutions = [
# dict with environment variables
(
"service's environment is low priority",
{"environment": {"v1": "low priority", "actual-v1": "$v1"}},
{"environment": {"v1": "low priority", "actual-v1": "high priority"}},
),
(
"service's environment can be used in other values",
{"environment": {"v100": "v1.0.0", "image": "abc:$v100"}},
{"environment": {"v100": "v1.0.0", "image": "abc:v1.0.0"}},
),
(
"Non-variable should not be substituted",
{"environment": {"non_var": "$$v1", "vx": "$non_var"}, "image": "abc:$non_var"},
{"environment": {"non_var": "$v1", "vx": "$v1"}, "image": "abc:$v1"},
),
# list
(
"Values in list are substituted",
["$v1", "low priority"],
["high priority", "low priority"],
),
# str
(
"Value with ${VARIABLE} format",
"${v1}",
"high priority",
),
(
"Value with ${VARIABLE:-default} format",
["${v1:-default}", "${empty:-default}", "${not_exits:-default}"],
["high priority", "default", "default"],
),
(
"Value with ${VARIABLE-default} format",
["${v1-default}", "${empty-default}", "${not_exits-default}"],
["high priority", "", "default"],
),
(
"Value $$ means $",
"$$v1",
"$v1",
),
]

@parameterized.expand(substitutions)
def test_rec_subs(self, desc, input, expected):
sub_dict = {"v1": "high priority", "empty": ""}
result = rec_subs(input, sub_dict)
self.assertEqual(result, expected, msg=desc)

0 comments on commit 585d344

Please sign in to comment.