diff options
| -rw-r--r-- | cloudinit/util.py | 9 | ||||
| -rw-r--r-- | tests/unittests/test_handler/test_handler_growpart.py | 4 | ||||
| -rw-r--r-- | tests/unittests/test_util.py | 30 | 
3 files changed, 39 insertions, 4 deletions
| diff --git a/cloudinit/util.py b/cloudinit/util.py index 6c5cf741..05cb587c 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_handler/test_handler_growpart.py b/tests/unittests/test_handler/test_handler_growpart.py index e653488a..e28067de 100644 --- a/tests/unittests/test_handler/test_handler_growpart.py +++ b/tests/unittests/test_handler/test_handler_growpart.py @@ -81,11 +81,11 @@ class TestConfig(TestCase):          self.cloud = cloud.Cloud(None, self.paths, None, None, None)          self.log = logging.getLogger("TestConfig")          self.args = [] -        os.environ = {}          self.cloud_init = None          self.handle = cc_growpart.handle +    @mock.patch.dict("os.environ", clear=True)      def test_no_resizers_auto_is_fine(self):          with mock.patch.object(                  util, 'subp', @@ -98,6 +98,7 @@ class TestConfig(TestCase):              mockobj.assert_called_once_with(                  ['growpart', '--help'], env={'LANG': 'C'}) +    @mock.patch.dict("os.environ", clear=True)      def test_no_resizers_mode_growpart_is_exception(self):          with mock.patch.object(                  util, 'subp', @@ -110,6 +111,7 @@ class TestConfig(TestCase):              mockobj.assert_called_once_with(                  ['growpart', '--help'], env={'LANG': 'C'}) +    @mock.patch.dict("os.environ", clear=True)      def test_mode_auto_prefers_growpart(self):          with mock.patch.object(                  util, 'subp', diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py index d2031f59..30f603cb 100644 --- a/tests/unittests/test_util.py +++ b/tests/unittests/test_util.py @@ -223,8 +223,10 @@ class TestKeyValStrings(helpers.TestCase):  class TestGetCmdline(helpers.TestCase):      def test_cmdline_reads_debug_env(self): -        os.environ['DEBUG_PROC_CMDLINE'] = 'abcd 123' -        self.assertEqual(os.environ['DEBUG_PROC_CMDLINE'], util.get_cmdline()) +        with mock.patch.dict("os.environ", +                             values={'DEBUG_PROC_CMDLINE': 'abcd 123'}): +            ret = util.get_cmdline() +        self.assertEqual("abcd 123", ret)  class TestLoadYaml(helpers.TestCase): @@ -516,6 +518,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 +569,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): +            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) | 
