From e140f0319e63aad68ae1146a181fe693be4b130f Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Mon, 26 Mar 2018 15:41:28 -0400 Subject: [PATCH] Chef: Fix encoding and Python 3 support Allow the Chef hook to run under Python 3, and gracefully handle invalid UTF-8 sequences in the output from the command in the same manner we have in other hooks since 25cd394bbe5c371dd60328643f2e18b7bfb3d1a2. Change-Id: I087cd93a78c48f01bdebbd1e630cb8701dc9477a Closes-Bug: #1709026 --- heat-config-chef/install.d/hook-chef.py | 15 ++++++++------- tests/test_hook_chef.py | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/heat-config-chef/install.d/hook-chef.py b/heat-config-chef/install.d/hook-chef.py index 61743a8..41ef4e7 100755 --- a/heat-config-chef/install.d/hook-chef.py +++ b/heat-config-chef/install.d/hook-chef.py @@ -101,20 +101,21 @@ def main(argv=sys.argv): log.error("Error cloning kitchen from %s into %s: %s", kitchen, kitchen_path, err) json.dump({'deploy_status_code': ret, - 'deploy_stdout': out, - 'deploy_stderr': err}, + 'deploy_stdout': out.decode('utf-8', 'replace'), + 'deploy_stderr': err.decode('utf-8', 'replace')}, sys.stdout) return 0 # write the json attributes ret, out, err = run_subproc(['hostname', '-f']) if ret == 0: - fqdn = out.strip() + fqdn = out.decode('utf-8').strip() else: err = "Could not determine hostname with hostname -f" json.dump({'deploy_status_code': ret, 'deploy_stdout': "", - 'deploy_stderr': err}, sys.stdout) + 'deploy_stderr': err.decode('utf-8', 'replace')}, + sys.stdout) return 0 node_config = {} for input in c['inputs']: @@ -142,10 +143,10 @@ def main(argv=sys.argv): cmd = ['chef-client', '-z', '--config', config_path, "-j", node_file] ret, out, err = run_subproc(cmd, heat_outputs_path=heat_outputs_path) resp = {'deploy_status_code': ret, - 'deploy_stdout': out, - 'deploy_stderr': err} + 'deploy_stdout': out.decode('utf-8', 'replace'), + 'deploy_stderr': err.decode('utf-8', 'replace')} log.debug("Chef output: %s", out) - if err: + if ret != 0: log.error("Chef return code %s:\n%s", ret, err) for output in c.get('outputs', []): output_name = output['name'] diff --git a/tests/test_hook_chef.py b/tests/test_hook_chef.py index 2fd9c87..9ac79d1 100644 --- a/tests/test_hook_chef.py +++ b/tests/test_hook_chef.py @@ -86,7 +86,7 @@ class HookChefTest(common.RunScriptTest): sys.stdin.seek(0) mock_subproc = mock.Mock() mock_popen.return_value = mock_subproc - mock_subproc.communicate.return_value = ("out", "err") + mock_subproc.communicate.return_value = (b"out", b"err") mock_subproc.returncode = 0 with mock.patch("os.fdopen", mock.mock_open()) as mfdopen: with mock.patch("os.open", mock.mock_open()): @@ -138,7 +138,7 @@ class HookChefTest(common.RunScriptTest): sys.stdin.seek(0) mock_subproc = mock.Mock() mock_popen.return_value = mock_subproc - mock_subproc.communicate.return_value = ("out", "err") + mock_subproc.communicate.return_value = (b"out", b"err") mock_subproc.returncode = 0 with mock.patch("os.fdopen", mock.mock_open()) as mfdopen: with mock.patch("os.open", mock.mock_open()): @@ -183,7 +183,7 @@ class HookChefTest(common.RunScriptTest): sys.stdin.seek(0) mock_subproc = mock.Mock() mock_popen.return_value = mock_subproc - mock_subproc.communicate.return_value = ("out", "err") + mock_subproc.communicate.return_value = (b"out", b"err") mock_subproc.returncode = 0 with mock.patch("os.fdopen", mock.mock_open()) as mfdopen: with mock.patch("os.open", mock.mock_open()):