Chad Smith has proposed merging ~chad.smith/cloud-init:bug/util-subp-accepts-string-cmd into cloud-init:master.
Requested reviews: cloud-init commiters (cloud-init-dev) For more details, see: https://code.launchpad.net/~chad.smith/cloud-init/+git/cloud-init/+merge/341437 util: Fix subp regression. Allow specifying subp command as a string. The command provided to subp can either be a string or a list. This patch fixes a regression which raised CalledProcessError whenever providing a string to subp. LP: #1755965 -- Your team cloud-init commiters is requested to review the proposed merge of ~chad.smith/cloud-init:bug/util-subp-accepts-string-cmd into cloud-init:master.
diff --git a/cloudinit/util.py b/cloudinit/util.py index 083a8ef..c62b602 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -1867,8 +1867,14 @@ def subp(args, data=None, rcs=None, env=None, capture=True, shell=False, # Popen converts entries in the arguments array from non-bytes to bytes. # When locale is unset it may use ascii for that encoding which can # cause UnicodeDecodeErrors. (LP: #1751051) - bytes_args = [x if isinstance(x, six.binary_type) else x.encode("utf-8") - for x in args] + if isinstance(args, (list, tuple)): + bytes_args = [ + x if isinstance(x, six.binary_type) else x.encode("utf-8") + for x in args] + elif isinstance(args, six.binary_type): + bytes_args = args + else: + bytes_args = args.encode("utf-8") try: sp = subprocess.Popen(bytes_args, stdout=stdout, stderr=stderr, stdin=stdin, diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py index 89ae40f..499e7c9 100644 --- a/tests/unittests/test_util.py +++ b/tests/unittests/test_util.py @@ -632,6 +632,24 @@ class TestSubp(helpers.CiTestCase): # but by using bash, we remove dependency on another program. return([BASH, '-c', 'printf "$@"', 'printf'] + list(args)) + def test_subp_handles_bytestrings(self): + """subp can run a bytestring command if shell is True.""" + tmp_file = self.tmp_path('test.out') + cmd = 'echo HI MOM >> {tmp_file}'.format(tmp_file=tmp_file) + (out, _err) = util.subp(cmd.encode('utf-8'), shell=True) + self.assertEqual(u'', out) + self.assertEqual(u'', _err) + self.assertEqual('HI MOM\n', util.load_file(tmp_file)) + + def test_subp_handles_strings(self): + """subp can run a string command if shell is True.""" + tmp_file = self.tmp_path('test.out') + cmd = 'echo HI MOM >> {tmp_file}'.format(tmp_file=tmp_file) + (out, _err) = util.subp(cmd, shell=True) + self.assertEqual(u'', out) + self.assertEqual(u'', _err) + self.assertEqual('HI MOM\n', util.load_file(tmp_file)) + def test_subp_handles_utf8(self): # The given bytes contain utf-8 accented characters as seen in e.g. # the "deja dup" package in Ubuntu.
_______________________________________________ Mailing list: https://launchpad.net/~cloud-init-dev Post to : cloud-init-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~cloud-init-dev More help : https://help.launchpad.net/ListHelp