cloud-init-dev team mailing list archive
-
cloud-init-dev team
-
Mailing list archive
-
Message #01212
[Merge] ~smoser/cloud-init:feature/subp_add_update_env into cloud-init:master
Scott Moser has proposed merging ~smoser/cloud-init:feature/subp_add_update_env into cloud-init:master.
Requested reviews:
cloud init development team (cloud-init-dev)
For more details, see:
https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/306391
--
Your team cloud init development team is requested to review the proposed merge of ~smoser/cloud-init:feature/subp_add_update_env into cloud-init:master.
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 6c5cf74..05cb587 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -1762,7 +1762,7 @@ def delete_dir_contents(dirname):
def subp(args, data=None, rcs=None, env=None, capture=True, shell=False,
- logstring=False, decode="replace", target=None):
+ logstring=False, decode="replace", target=None, update_env=None):
# not supported in cloud-init (yet), for now kept in the call signature
# to ease maintaining code shared between cloud-init and curtin
@@ -1773,6 +1773,13 @@ def subp(args, data=None, rcs=None, env=None, capture=True, shell=False,
rcs = [0]
devnull_fp = None
+
+ if update_env:
+ if env is None:
+ env = os.environ
+ env = env.copy()
+ env.update(update_env)
+
try:
if target_path(target) != "/":
args = ['chroot', target] + list(args)
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index d2031f5..81a13e2 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -516,6 +516,7 @@ class TestSubp(helpers.TestCase):
utf8_invalid = b'ab\xaadef'
utf8_valid = b'start \xc3\xa9 end'
utf8_valid_2 = b'd\xc3\xa9j\xc8\xa7'
+ printenv = ['bash', '-c', 'for n in "$@"; do echo "$n=${!n}"; done', '--']
def printf_cmd(self, *args):
# bash's printf supports \xaa. So does /usr/bin/printf
@@ -566,6 +567,29 @@ class TestSubp(helpers.TestCase):
self.assertEqual(err, data)
self.assertEqual(out, b'')
+ def test_subp_reads_env(self):
+ with mock.patch.dict("os.environ", values={'FOO': 'BAR'}):
+ out, err = util.subp(self.printenv + ['FOO'], capture=True)
+ self.assertEqual('FOO=BAR', out.splitlines()[0])
+
+ def test_subp_env_and_update_env(self):
+ out, err = util.subp(
+ self.printenv + ['FOO', 'HOME', 'K1', 'K2'], capture=True,
+ env={'FOO': 'BAR'},
+ update_env={'HOME': '/myhome', 'K2': 'V2'})
+ self.assertEqual(
+ ['FOO=BAR', 'HOME=/myhome', 'K1=', 'K2=V2'], out.splitlines())
+
+ def test_subp_update_env(self):
+ extra = {'FOO': 'BAR', 'HOME': '/root', 'K1': 'V1'}
+ with mock.patch.dict("os.environ", values=extra) as env:
+ out, err = util.subp(
+ self.printenv + ['FOO', 'HOME', 'K1', 'K2'], capture=True,
+ update_env={'HOME': '/myhome', 'K2': 'V2'})
+
+ self.assertEqual(
+ ['FOO=BAR', 'HOME=/myhome', 'K1=V1', 'K2=V2'], out.splitlines())
+
def test_returns_none_if_no_capture(self):
(out, err) = util.subp(self.stdin2out, data=b'', capture=False)
self.assertEqual(err, None)
Follow ups