Skip to content

Commit

Permalink
Merge "VMware: fix bug with booting from volumes" into stable/havana
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Oct 31, 2013
2 parents d8e6477 + 30461e8 commit 2e3da55
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 30 deletions.
2 changes: 1 addition & 1 deletion nova/tests/virt/vmwareapi/db_fakes.py
Expand Up @@ -69,7 +69,7 @@ def fake_instance_create(context, values):
'id': values['id'],
'uuid': values['uuid'],
'reservation_id': utils.generate_uid('r'),
'image_ref': values['image_ref'],
'image_ref': values.get('image_ref'),
'kernel_id': values['kernel_id'],
'ramdisk_id': values['ramdisk_id'],
'vm_state': vm_states.BUILDING,
Expand Down
27 changes: 15 additions & 12 deletions nova/tests/virt/vmwareapi/test_vmwareapi.py
Expand Up @@ -158,22 +158,23 @@ def _fake_login(_self):
self.conn = driver.VMwareAPISession()
self.assertEqual(self.attempts, 2)

def _create_instance_in_the_db(self, node=None):
def _create_instance_in_the_db(self, node=None, set_image_ref=True):
if not node:
node = self.node_name
values = {'name': 'fake_name',
'id': 1,
'uuid': "fake-uuid",
'project_id': self.project_id,
'user_id': self.user_id,
'image_ref': "fake_image_uuid",
'kernel_id': "fake_kernel_uuid",
'ramdisk_id': "fake_ramdisk_uuid",
'mac_address': "de:ad:be:ef:be:ef",
'instance_type': 'm1.large',
'node': node,
'root_gb': 80,
}
if set_image_ref:
values['image_ref'] = "fake_image_uuid"
self.instance_node = node
self.instance = db.instance_create(None, values)

Expand Down Expand Up @@ -323,14 +324,11 @@ def test_spawn_disk_invalid_disk_size(self):
self.assertRaises(exception.InstanceUnacceptable,
self._create_vm)

def test_spawn_attach_volume_vmdk(self):
self._create_instance_in_the_db()
def _spawn_attach_volume_vmdk(self, set_image_ref=True):
self._create_instance_in_the_db(set_image_ref=set_image_ref)
self.type_data = db.flavor_get_by_name(None, 'm1.large')
self.mox.StubOutWithMock(block_device, 'volume_in_mapping')
self.mox.StubOutWithMock(v_driver, 'block_device_info_get_mapping')
ebs_root = 'fake_root'
block_device.volume_in_mapping(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(ebs_root)
connection_info = self._test_vmdk_connection_info('vmdk')
root_disk = [{'connection_info': connection_info}]
v_driver.block_device_info_get_mapping(
Expand All @@ -349,19 +347,23 @@ def test_spawn_attach_volume_vmdk(self):
volumeops.VMwareVolumeOps.attach_volume(connection_info,
self.instance, mox.IgnoreArg())
self.mox.ReplayAll()
block_device_info = {'mount_device': 'vda'}
self.conn.spawn(self.context, self.instance, self.image,
injected_files=[], admin_password=None,
network_info=self.network_info,
block_device_info=None)
block_device_info=block_device_info)

def test_spawn_attach_volume_vmdk(self):
self._spawn_attach_volume_vmdk()

def test_spawn_attach_volume_vmdk_no_image_ref(self):
self._spawn_attach_volume_vmdk(set_image_ref=False)

def test_spawn_attach_volume_iscsi(self):
self._create_instance_in_the_db()
self.type_data = db.flavor_get_by_name(None, 'm1.large')
self.mox.StubOutWithMock(block_device, 'volume_in_mapping')
self.mox.StubOutWithMock(v_driver, 'block_device_info_get_mapping')
ebs_root = 'fake_root'
block_device.volume_in_mapping(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(ebs_root)
connection_info = self._test_vmdk_connection_info('iscsi')
root_disk = [{'connection_info': connection_info}]
v_driver.block_device_info_get_mapping(
Expand All @@ -371,10 +373,11 @@ def test_spawn_attach_volume_iscsi(self):
volumeops.VMwareVolumeOps.attach_volume(connection_info,
self.instance, mox.IgnoreArg())
self.mox.ReplayAll()
block_device_info = {'mount_device': 'vda'}
self.conn.spawn(self.context, self.instance, self.image,
injected_files=[], admin_password=None,
network_info=self.network_info,
block_device_info=None)
block_device_info=block_device_info)

def _test_snapshot(self):
expected_calls = [
Expand Down
43 changes: 26 additions & 17 deletions nova/virt/vmwareapi/vmops.py
Expand Up @@ -32,7 +32,6 @@
from oslo.config import cfg

from nova.api.metadata import base as instance_metadata
from nova import block_device
from nova import compute
from nova.compute import power_state
from nova.compute import task_states
Expand Down Expand Up @@ -165,6 +164,14 @@ def spawn(self, context, instance, image_meta, injected_files,
4. Attach the disk to the VM by reconfiguring the same.
5. Power on the VM.
"""
ebs_root = False
if block_device_info:
LOG.debug(_("Block device information present: %s")
% block_device_info, instance=instance)
block_device_mapping = driver.block_device_info_get_mapping(
block_device_info)
if block_device_mapping:
ebs_root = True

client_factory = self._session._get_vim().client.factory
service_content = self._session._get_vim().get_service_content()
Expand All @@ -177,14 +184,19 @@ def spawn(self, context, instance, image_meta, injected_files,
# The use of nested functions in this file makes for a confusing and
# hard to maintain file. At some future date, refactor this method to
# be a full-fledged method. This will also make unit testing easier.
def _get_image_properties():
def _get_image_properties(root_size):
"""
Get the Size of the flat vmdk file that is there on the storage
repository.
"""
_image_info = vmware_images.get_vmdk_size_and_properties(context,
instance['image_ref'],
instance)
image_ref = instance.get('image_ref')
if image_ref:
_image_info = vmware_images.get_vmdk_size_and_properties(
context, image_ref, instance)
else:
# The case that the image may be booted from a volume
_image_info = (root_size, {})

image_size, image_properties = _image_info
vmdk_file_size_in_kb = int(image_size) / 1024
os_type = image_properties.get("vmware_ostype", "otherGuest")
Expand All @@ -204,11 +216,12 @@ def _get_image_properties():
return (vmdk_file_size_in_kb, os_type, adapter_type, disk_type,
vif_model, image_linked_clone)

(vmdk_file_size_in_kb, os_type, adapter_type,
disk_type, vif_model, image_linked_clone) = _get_image_properties()

root_gb = instance['root_gb']
root_gb_in_kb = root_gb * 1024 * 1024

(vmdk_file_size_in_kb, os_type, adapter_type, disk_type, vif_model,
image_linked_clone) = _get_image_properties(root_gb_in_kb)

if root_gb_in_kb and vmdk_file_size_in_kb > root_gb_in_kb:
reason = _("Image disk size greater than requested disk size")
raise exception.InstanceUnacceptable(instance_id=instance['uuid'],
Expand Down Expand Up @@ -393,9 +406,6 @@ def _copy_virtual_disk(source, dest):
"data_store_name": data_store_name},
instance=instance)

ebs_root = block_device.volume_in_mapping(
self._default_root_device, block_device_info)

if not ebs_root:
# this logic allows for instances or images to decide
# for themselves which strategy is best for them.
Expand Down Expand Up @@ -521,12 +531,11 @@ def _copy_virtual_disk(source, dest):

else:
# Attach the root disk to the VM.
root_disk = driver.block_device_info_get_mapping(
block_device_info)[0]
connection_info = root_disk['connection_info']
self._volumeops.attach_root_volume(connection_info, instance,
self._default_root_device,
data_store_ref)
for root_disk in block_device_mapping:
connection_info = root_disk['connection_info']
self._volumeops.attach_root_volume(connection_info, instance,
self._default_root_device,
data_store_ref)

def _power_on_vm():
"""Power on the VM."""
Expand Down

0 comments on commit 2e3da55

Please sign in to comment.