Merge "Rollback instance.image_ref on failed rebuild" into stable/pike

This commit is contained in:
Zuul 2018-02-20 20:25:51 +00:00 committed by Gerrit Code Review
commit d536bec9fc
2 changed files with 26 additions and 6 deletions

View File

@ -888,6 +888,11 @@ class ComputeTaskManager(base.Base):
if migration:
migration.status = 'error'
migration.save()
# Rollback the image_ref if a new one was provided (this
# only happens in the rebuild case, not evacuate).
if orig_image_ref and orig_image_ref != image_ref:
instance.image_ref = orig_image_ref
instance.save()
request_spec = request_spec.to_legacy_request_spec_dict()
with excutils.save_and_reraise_exception():
self._set_vm_state_and_notify(context, instance.uuid,
@ -902,6 +907,11 @@ class ComputeTaskManager(base.Base):
if migration:
migration.status = 'error'
migration.save()
# Rollback the image_ref if a new one was provided (this
# only happens in the rebuild case, not evacuate).
if orig_image_ref and orig_image_ref != image_ref:
instance.image_ref = orig_image_ref
instance.save()
request_spec = request_spec.to_legacy_request_spec_dict()
with excutils.save_and_reraise_exception():
self._set_vm_state_and_notify(context, instance.uuid,

View File

@ -21,6 +21,7 @@ import mock
from oslo_log import log as logging
from oslo_serialization import base64
from oslo_utils import timeutils
import six
from nova.compute import api as compute_api
from nova.compute import instance_actions
@ -1093,11 +1094,12 @@ class ServerRebuildTestCase(integrated_helpers._IntegratedTestBase,
self.flags(host='host2')
self.compute2 = self.start_service('compute', host='host2')
# We hard-code from a fake image since we can't get images
# via the compute /images proxy API with microversion > 2.35.
original_image_ref = '155d900f-4e14-4e4c-a73d-069cbf4541e6'
server_req_body = {
'server': {
# We hard-code from a fake image since we can't get images
# via the compute /images proxy API with microversion > 2.35.
'imageRef': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
'imageRef': original_image_ref,
'flavorRef': '1', # m1.tiny from DefaultFlavorsFixture,
'name': 'test_rebuild_with_image_novalidhost',
# We don't care about networking for this test. This requires
@ -1140,15 +1142,23 @@ class ServerRebuildTestCase(integrated_helpers._IntegratedTestBase,
# Before microversion 2.51 events are only returned for instance
# actions if you're an admin.
self.api_fixture.admin_api)
# Unfortunately the server's image_ref is updated to be the new image
# even though the rebuild should not work.
# Assert the server image_ref was rolled back on failure.
server = self.api.get_server(server['id'])
self.assertEqual(rebuild_image_ref, server['image']['id'])
self.assertEqual(original_image_ref, server['image']['id'])
# The server should be in ERROR state
self.assertEqual('ERROR', server['status'])
self.assertIn('No valid host', server['fault']['message'])
# Rebuild it again with the same bad image to make sure it's rejected
# again. Since we're using CastAsCall here, there is no 202 from the
# API, and the exception from conductor gets passed back through the
# API.
ex = self.assertRaises(
client.OpenStackApiException, self.api.api_post,
'/servers/%s/action' % server['id'], rebuild_req_body)
self.assertIn('NoValidHost', six.text_type(ex))
def test_rebuild_with_new_image(self):
"""Rebuilds a server with a different image which will run it through
the scheduler to validate the image is still OK with the compute host