xenapi/agent: Change openssl error handling

Prior to this patch, if the openssl command returned a zero exit code
and wrote details to stderr, nova would raise a RuntimeError exception.
This patch changes the behavior to only raise a RuntimeError exception
when openssl returns a non-zero exit code. Regardless of the exit code
a warning will always be logged with stderr details if stderr is not
None. Note that processutils.execute will now raise a
processutils.ProcessExecutionError exception for any non-zero exit code
since we are passing check_exit_code=True, which we convert to a
Runtime error.

Thanks to Dimitri John Ledkov <xnox@ubuntu.com> and Eric Fried
<openstack@fried.cc> for helping with this patch.

Change-Id: I212ac2b5ccd93e00adb7b9fe102fcb70857c6073
Partial-Bug: #1771506
(cherry picked from commit 1da71fa4ab)
This commit is contained in:
Corey Bryant 2019-02-07 10:12:54 -05:00
parent 870e5bcfb6
commit 64793cf6f7
2 changed files with 26 additions and 5 deletions

View File

@ -19,6 +19,7 @@ import time
import mock
from os_xenapi.client import host_agent
from os_xenapi.client import XenAPI
from oslo_concurrency import processutils
from oslo_utils import uuidutils
from nova import exception
@ -311,6 +312,19 @@ class SetAdminPasswordTestCase(AgentTestCaseBase):
mock_add_fault.assert_called_once_with(error, mock.ANY)
@mock.patch('oslo_concurrency.processutils.execute')
def test_run_ssl_successful(self, mock_execute):
mock_execute.return_value = ('0',
'*** WARNING : deprecated key derivation used.'
'Using -iter or -pbkdf2 would be better.')
agent.SimpleDH()._run_ssl('foo')
@mock.patch('oslo_concurrency.processutils.execute',
side_effect=processutils.ProcessExecutionError(
exit_code=1, stderr=('ERROR: Something bad happened')))
def test_run_ssl_failure(self, mock_execute):
self.assertRaises(RuntimeError, agent.SimpleDH()._run_ssl, 'foo')
class UpgradeRequiredTestCase(test.NoDBTestCase):
def test_less_than(self):

View File

@ -422,11 +422,18 @@ class SimpleDH(object):
'pass:%s' % self._shared, '-nosalt']
if decrypt:
cmd.append('-d')
out, err = processutils.execute(
*cmd, process_input=encodeutils.safe_encode(text))
if err:
raise RuntimeError(_('OpenSSL error: %s') % err)
return out
try:
out, err = processutils.execute(
*cmd,
process_input=encodeutils.safe_encode(text),
check_exit_code=True)
if err:
LOG.warning("OpenSSL stderr: %s", err)
return out
except processutils.ProcessExecutionError as e:
raise RuntimeError(
_('OpenSSL errored with exit code %(exit_code)d: %(stderr)s') %
{'exit_code': e.exit_code, 'stderr': e.stderr})
def encrypt(self, text):
return self._run_ssl(text).strip('\n')