Handle SetAdminPasswdNotSupported raised by libvirt driver

When admin-password operation is not supported by libvirt qemu/kvm
SetAdminPasswdNotSupported exception is raised, compute manager doesn't
handle it, which cause instance state to be set to error.

Closes-bug: #1522338

Change-Id: Ic63e8f723ff19dfa63199e77ea76680bff5a123b
This commit is contained in:
Timofey Durakov
2015-12-03 12:48:23 +03:00
parent 11e23346b5
commit c6ffec0003
5 changed files with 59 additions and 3 deletions

View File

@@ -51,7 +51,9 @@ class AdminPasswordController(wsgi.Controller):
self.compute_api.set_admin_password(context, instance, password)
except exception.InstanceUnknownCell as e:
raise exc.HTTPNotFound(explanation=e.format_message())
except exception.InstancePasswordSetFailed as e:
except (exception.InstancePasswordSetFailed,
exception.SetAdminPasswdNotSupported,
exception.InstanceAgentNotEnabled) as e:
raise exc.HTTPConflict(explanation=e.format_message())
except exception.InstanceInvalidState as e:
raise common.raise_http_conflict_for_instance_invalid_state(

View File

@@ -3126,6 +3126,21 @@ class ComputeManager(manager.Manager):
instance.task_state = None
instance.save(
expected_task_state=task_states.UPDATING_PASSWORD)
except exception.InstanceAgentNotEnabled:
with excutils.save_and_reraise_exception():
LOG.debug('Guest agent is not enabled for the instance.',
instance=instance)
instance.task_state = None
instance.save(
expected_task_state=task_states.UPDATING_PASSWORD)
except exception.SetAdminPasswdNotSupported:
with excutils.save_and_reraise_exception():
LOG.info(_LI('set_admin_password is not supported '
'by this driver or guest instance.'),
instance=instance)
instance.task_state = None
instance.save(
expected_task_state=task_states.UPDATING_PASSWORD)
except NotImplementedError:
LOG.warning(_LW('set_admin_password is not implemented '
'by this driver or guest instance.'),

View File

@@ -1998,12 +1998,18 @@ class InstanceQuiesceNotSupported(Invalid):
msg_fmt = _('Quiescing is not supported in instance %(instance_id)s')
class QemuGuestAgentNotEnabled(Invalid):
class InstanceAgentNotEnabled(Invalid):
msg_fmt = _('Guest agent is not enabled for the instance')
safe = True
class QemuGuestAgentNotEnabled(InstanceAgentNotEnabled):
msg_fmt = _('QEMU guest agent is not enabled')
class SetAdminPasswdNotSupported(Invalid):
msg_fmt = _('Set admin password is not supported')
safe = True
class MemoryPageSizeInvalid(Invalid):

View File

@@ -87,6 +87,25 @@ class AdminPasswordTestV21(test.NoDBTestCase):
self._get_action(),
self.fake_req, '1', body=body)
@mock.patch('nova.compute.api.API.set_admin_password',
side_effect=exception.SetAdminPasswdNotSupported(instance="1",
reason=''))
def test_change_password_not_supported(self, mock_set_admin_password):
body = {'changePassword': {'adminPass': 'test'}}
self.assertRaises(webob.exc.HTTPConflict,
self._get_action(),
self.fake_req, '1', body=body)
@mock.patch('nova.compute.api.API.set_admin_password',
side_effect=exception.InstanceAgentNotEnabled(instance="1",
reason=''))
def test_change_password_guest_agent_disabled(self,
mock_set_admin_password):
body = {'changePassword': {'adminPass': 'test'}}
self.assertRaises(webob.exc.HTTPConflict,
self._get_action(),
self.fake_req, '1', body=body)
def test_change_password_without_admin_password(self):
body = {'changPassword': {}}
self.assertRaises(self.validiation_error,

View File

@@ -2626,7 +2626,9 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
instance=instance,
new_pass=None)
if expected_exception == NotImplementedError:
if (expected_exception == exception.SetAdminPasswdNotSupported or
expected_exception == exception.InstanceAgentNotEnabled or
expected_exception == NotImplementedError):
instance_save_mock.assert_called_once_with(
expected_task_state=task_states.UPDATING_PASSWORD)
else:
@@ -2659,6 +2661,18 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
self._do_test_set_admin_password_driver_error(
exc, vm_states.ACTIVE, None, expected_exception)
def test_set_admin_password_driver_not_supported(self):
exc = exception.SetAdminPasswdNotSupported()
expected_exception = exception.SetAdminPasswdNotSupported
self._do_test_set_admin_password_driver_error(
exc, vm_states.ACTIVE, None, expected_exception)
def test_set_admin_password_guest_agent_no_enabled(self):
exc = exception.QemuGuestAgentNotEnabled()
expected_exception = exception.InstanceAgentNotEnabled
self._do_test_set_admin_password_driver_error(
exc, vm_states.ACTIVE, None, expected_exception)
def test_destroy_evacuated_instances(self):
our_host = self.compute.host
instance_1 = objects.Instance(self.context)