Browse Source

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 25cd394bbe.

Change-Id: I087cd93a78c48f01bdebbd1e630cb8701dc9477a
Closes-Bug: #1709026
Zane Bitter 1 year ago
parent
commit
e140f0319e
2 changed files with 11 additions and 10 deletions
  1. 8
    7
      heat-config-chef/install.d/hook-chef.py
  2. 3
    3
      tests/test_hook_chef.py

+ 8
- 7
heat-config-chef/install.d/hook-chef.py View File

@@ -101,20 +101,21 @@ def main(argv=sys.argv):
101 101
             log.error("Error cloning kitchen from %s into %s: %s", kitchen,
102 102
                       kitchen_path, err)
103 103
             json.dump({'deploy_status_code': ret,
104
-                       'deploy_stdout': out,
105
-                       'deploy_stderr': err},
104
+                       'deploy_stdout': out.decode('utf-8', 'replace'),
105
+                       'deploy_stderr': err.decode('utf-8', 'replace')},
106 106
                       sys.stdout)
107 107
             return 0
108 108
 
109 109
     # write the json attributes
110 110
     ret, out, err = run_subproc(['hostname', '-f'])
111 111
     if ret == 0:
112
-        fqdn = out.strip()
112
+        fqdn = out.decode('utf-8').strip()
113 113
     else:
114 114
         err = "Could not determine hostname with hostname -f"
115 115
         json.dump({'deploy_status_code': ret,
116 116
                    'deploy_stdout': "",
117
-                   'deploy_stderr': err}, sys.stdout)
117
+                   'deploy_stderr': err.decode('utf-8', 'replace')},
118
+                  sys.stdout)
118 119
         return 0
119 120
     node_config = {}
120 121
     for input in c['inputs']:
@@ -142,10 +143,10 @@ def main(argv=sys.argv):
142 143
     cmd = ['chef-client', '-z', '--config', config_path, "-j", node_file]
143 144
     ret, out, err = run_subproc(cmd, heat_outputs_path=heat_outputs_path)
144 145
     resp = {'deploy_status_code': ret,
145
-            'deploy_stdout': out,
146
-            'deploy_stderr': err}
146
+            'deploy_stdout': out.decode('utf-8', 'replace'),
147
+            'deploy_stderr': err.decode('utf-8', 'replace')}
147 148
     log.debug("Chef output: %s", out)
148
-    if err:
149
+    if ret != 0:
149 150
         log.error("Chef return code %s:\n%s", ret, err)
150 151
     for output in c.get('outputs', []):
151 152
         output_name = output['name']

+ 3
- 3
tests/test_hook_chef.py View File

@@ -86,7 +86,7 @@ class HookChefTest(common.RunScriptTest):
86 86
         sys.stdin.seek(0)
87 87
         mock_subproc = mock.Mock()
88 88
         mock_popen.return_value = mock_subproc
89
-        mock_subproc.communicate.return_value = ("out", "err")
89
+        mock_subproc.communicate.return_value = (b"out", b"err")
90 90
         mock_subproc.returncode = 0
91 91
         with mock.patch("os.fdopen", mock.mock_open()) as mfdopen:
92 92
             with mock.patch("os.open", mock.mock_open()):
@@ -138,7 +138,7 @@ class HookChefTest(common.RunScriptTest):
138 138
         sys.stdin.seek(0)
139 139
         mock_subproc = mock.Mock()
140 140
         mock_popen.return_value = mock_subproc
141
-        mock_subproc.communicate.return_value = ("out", "err")
141
+        mock_subproc.communicate.return_value = (b"out", b"err")
142 142
         mock_subproc.returncode = 0
143 143
         with mock.patch("os.fdopen", mock.mock_open()) as mfdopen:
144 144
             with mock.patch("os.open", mock.mock_open()):
@@ -183,7 +183,7 @@ class HookChefTest(common.RunScriptTest):
183 183
         sys.stdin.seek(0)
184 184
         mock_subproc = mock.Mock()
185 185
         mock_popen.return_value = mock_subproc
186
-        mock_subproc.communicate.return_value = ("out", "err")
186
+        mock_subproc.communicate.return_value = (b"out", b"err")
187 187
         mock_subproc.returncode = 0
188 188
         with mock.patch("os.fdopen", mock.mock_open()) as mfdopen:
189 189
             with mock.patch("os.open", mock.mock_open()):

Loading…
Cancel
Save