diff --git a/nova/api/openstack/compute/admin_password.py b/nova/api/openstack/compute/admin_password.py index c83a329ff2..fa10bdec02 100644 --- a/nova/api/openstack/compute/admin_password.py +++ b/nova/api/openstack/compute/admin_password.py @@ -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( diff --git a/nova/compute/manager.py b/nova/compute/manager.py index d5c7d9e9f7..a4aa11f592 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -3128,6 +3128,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.'), diff --git a/nova/exception.py b/nova/exception.py index e5135253e6..13929fcaff 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -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): diff --git a/nova/tests/unit/api/openstack/compute/test_admin_password.py b/nova/tests/unit/api/openstack/compute/test_admin_password.py index 7c30f2edf1..0e0140ddb6 100644 --- a/nova/tests/unit/api/openstack/compute/test_admin_password.py +++ b/nova/tests/unit/api/openstack/compute/test_admin_password.py @@ -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, diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index ec94f16f3f..106fd1fe94 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -2609,7 +2609,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: @@ -2642,6 +2644,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)