cloud-init-dev team mailing list archive
-
cloud-init-dev team
-
Mailing list archive
-
Message #04349
[Merge] ~chad.smith/cloud-init:bug/util-subp-accepts-string-cmd into cloud-init:master
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.
Follow ups