Add missing image to instance booted from volume
When booting an instance from a volume, the image_ref for the instance will be None. And the API do not get the image information for the instance also. So when we calling the related API, we get "" for instance.image. Change-Id: I3c35ab1d7c8bcec551fb5d67d0b44418266b32a4 Closes-bug: 1317880
This commit is contained in:
@@ -34,6 +34,7 @@ from nova import compute
|
||||
from nova.compute import flavors
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova.objects import instance as instance_obj
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import strutils
|
||||
@@ -599,6 +600,8 @@ class Controller(wsgi.Controller):
|
||||
limit=limit,
|
||||
marker=marker,
|
||||
want_objects=True)
|
||||
for instance in instance_list:
|
||||
instance_obj.add_image_ref(context, instance)
|
||||
except exception.MarkerNotFound:
|
||||
msg = _('marker [%s] not found') % marker
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
@@ -766,7 +769,8 @@ class Controller(wsgi.Controller):
|
||||
context = req.environ['nova.context']
|
||||
instance = self.compute_api.get(context, id,
|
||||
want_objects=True)
|
||||
req.cache_db_instance(instance)
|
||||
req.cache_db_instance(instance_obj.add_image_ref(context,
|
||||
instance))
|
||||
return self._view_builder.show(req, instance)
|
||||
except exception.NotFound:
|
||||
msg = _("Instance could not be found")
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
from nova.cells import opts as cells_opts
|
||||
from nova.cells import rpcapi as cells_rpcapi
|
||||
from nova import compute
|
||||
from nova.compute import flavors
|
||||
from nova import db
|
||||
from nova import exception
|
||||
@@ -567,6 +568,20 @@ class Instance(base.NovaPersistentObject, base.NovaObject):
|
||||
self.obj_reset_changes(['metadata'])
|
||||
|
||||
|
||||
def add_image_ref(context, instance):
|
||||
"""Helper method to add image_ref to instance object."""
|
||||
if not instance['image_ref']:
|
||||
compute_api = compute.API()
|
||||
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
|
||||
context, instance['uuid'])
|
||||
if compute_api.is_volume_backed_instance(context, instance, bdms):
|
||||
props = bdms.root_metadata(
|
||||
context, compute_api.image_api,
|
||||
compute_api.volume_api)
|
||||
instance['image_ref'] = props['image_id']
|
||||
return instance
|
||||
|
||||
|
||||
def _make_instance_list(context, inst_list, db_inst_list, expected_attrs):
|
||||
get_fault = expected_attrs and 'fault' in expected_attrs
|
||||
inst_faults = {}
|
||||
|
||||
@@ -196,6 +196,8 @@ class ServersControllerTest(ControllerTest):
|
||||
|
||||
def setUp(self):
|
||||
super(ServersControllerTest, self).setUp()
|
||||
self.compute_api = self.controller.compute_api
|
||||
self.context = context.RequestContext('fake', 'fake')
|
||||
|
||||
def test_can_check_loaded_extensions(self):
|
||||
self.ext_mgr.extensions = {'os-fake': None}
|
||||
@@ -259,6 +261,25 @@ class ServersControllerTest(ControllerTest):
|
||||
res_dict = self.controller.show(req, FAKE_UUID)
|
||||
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
|
||||
|
||||
def test_get_server_no_image(self):
|
||||
|
||||
def return_instance(self, *args, **kwargs):
|
||||
return fakes.stub_instance(id=1, uuid=FAKE_UUID,
|
||||
project_id=str(uuid.uuid4()),
|
||||
image_ref='')
|
||||
|
||||
def fake_add_image_ref(context, instance):
|
||||
instance['image_ref'] = 'fake_image'
|
||||
return instance
|
||||
|
||||
self.stubs.Set(db, 'instance_get_by_uuid', return_instance)
|
||||
self.stubs.Set(instance_obj, 'add_image_ref', fake_add_image_ref)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/fake/servers/%s' % FAKE_UUID)
|
||||
server = self.controller.show(req, FAKE_UUID)
|
||||
|
||||
self.assertEqual('fake_image', server['server']['image']['id'])
|
||||
|
||||
def test_unique_host_id(self):
|
||||
"""Create two servers with the same host and different
|
||||
project_ids and check that the hostId's are unique.
|
||||
@@ -517,6 +538,29 @@ class ServersControllerTest(ControllerTest):
|
||||
|
||||
self.assertEqual(s['links'], expected_links)
|
||||
|
||||
def test_get_servers_no_image(self):
|
||||
|
||||
def fake_get_all(compute_self, context, search_opts=None,
|
||||
sort_key=None, sort_dir='desc',
|
||||
limit=None, marker=None, want_objects=False):
|
||||
db_list = [fakes.stub_instance(100,
|
||||
uuid=FAKE_UUID,
|
||||
image_ref='')]
|
||||
return instance_obj._make_instance_list(
|
||||
context, objects.InstanceList(), db_list, FIELDS)
|
||||
|
||||
def fake_add_image_ref(context, instance):
|
||||
instance['image_ref'] = 'fake_image'
|
||||
return instance
|
||||
|
||||
self.stubs.Set(instance_obj, 'add_image_ref', fake_add_image_ref)
|
||||
self.stubs.Set(compute_api.API, 'get_all', fake_get_all)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/fake/servers/detail')
|
||||
res_dict = self.controller.detail(req)
|
||||
for s in res_dict['servers']:
|
||||
self.assertEqual('fake_image', s['image']['id'])
|
||||
|
||||
def test_get_servers_with_limit(self):
|
||||
req = fakes.HTTPRequest.blank('/fake/servers?limit=3')
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
@@ -21,6 +21,7 @@ import netaddr
|
||||
|
||||
from nova.cells import rpcapi as cells_rpcapi
|
||||
from nova.compute import flavors
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.network import model as network_model
|
||||
@@ -1088,3 +1089,14 @@ class TestInstanceObjectMisc(test.NoDBTestCase):
|
||||
self.stubs.Set(instance, '_INSTANCE_OPTIONAL_JOINED_FIELDS', ['bar'])
|
||||
self.assertEqual(['bar'], instance._expected_cols(['foo', 'bar']))
|
||||
self.assertIsNone(instance._expected_cols(None))
|
||||
|
||||
|
||||
class TestAddImageRef(test.TestCase):
|
||||
@mock.patch('nova.objects.BlockDeviceMappingList.root_metadata')
|
||||
def test_add_image_ref(self, mock_root_metadata):
|
||||
mock_root_metadata.return_value = {'image_id': 'fake_image'}
|
||||
fake_instance = fakes.stub_instance(id=1, uuid=fakes.FAKE_UUID,
|
||||
image_ref='')
|
||||
ctx = context.RequestContext('fake-user', 'fake-project')
|
||||
new_instance = instance.add_image_ref(ctx, fake_instance)
|
||||
self.assertEqual('fake_image', new_instance['image_ref'])
|
||||
|
||||
Reference in New Issue
Block a user