summaryrefslogtreecommitdiff
path: root/nova/virt/vmwareapi
diff options
context:
space:
mode:
Diffstat (limited to 'nova/virt/vmwareapi')
-rw-r--r--nova/virt/vmwareapi/constants.py3
-rw-r--r--nova/virt/vmwareapi/driver.py1
-rw-r--r--nova/virt/vmwareapi/vm_util.py67
-rw-r--r--nova/virt/vmwareapi/vmops.py4
-rw-r--r--nova/virt/vmwareapi/volumeops.py65
5 files changed, 120 insertions, 20 deletions
diff --git a/nova/virt/vmwareapi/constants.py b/nova/virt/vmwareapi/constants.py
index 6452434ce7..2a42174bf7 100644
--- a/nova/virt/vmwareapi/constants.py
+++ b/nova/virt/vmwareapi/constants.py
@@ -27,7 +27,8 @@ MIN_VC_OVS_VERSION = '5.5.0'
DISK_FORMAT_ISO = 'iso'
DISK_FORMAT_VMDK = 'vmdk'
DISK_FORMAT_ISCSI = 'iscsi'
-DISK_FORMATS_ALL = [DISK_FORMAT_ISO, DISK_FORMAT_VMDK]
+DISK_FORMAT_FCD = 'vstorageobject'
+DISK_FORMATS_ALL = [DISK_FORMAT_ISO, DISK_FORMAT_VMDK, DISK_FORMAT_FCD]
DISK_TYPE_THIN = 'thin'
CONTAINER_FORMAT_BARE = 'bare'
diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py
index df875fa8c9..66ad1df9b1 100644
--- a/nova/virt/vmwareapi/driver.py
+++ b/nova/virt/vmwareapi/driver.py
@@ -72,6 +72,7 @@ class VMwareVCDriver(driver.ComputeDriver):
"supports_trusted_certs": False,
"supports_pcpus": False,
"supports_accelerators": False,
+ "supports_remote_managed_ports": False,
# Image type support flags
"supports_image_type_aki": False,
diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py
index 01a2e18c8d..cea5195670 100644
--- a/nova/virt/vmwareapi/vm_util.py
+++ b/nova/virt/vmwareapi/vm_util.py
@@ -119,31 +119,31 @@ def vm_refs_cache_reset():
_VM_REFS_CACHE = {}
-def vm_ref_cache_delete(id):
- _VM_REFS_CACHE.pop(id, None)
+def vm_ref_cache_delete(id_):
+ _VM_REFS_CACHE.pop(id_, None)
-def vm_ref_cache_update(id, vm_ref):
- _VM_REFS_CACHE[id] = vm_ref
+def vm_ref_cache_update(id_, vm_ref):
+ _VM_REFS_CACHE[id_] = vm_ref
-def vm_ref_cache_get(id):
- return _VM_REFS_CACHE.get(id)
+def vm_ref_cache_get(id_):
+ return _VM_REFS_CACHE.get(id_)
-def _vm_ref_cache(id, func, session, data):
- vm_ref = vm_ref_cache_get(id)
+def _vm_ref_cache(id_, func, session, data):
+ vm_ref = vm_ref_cache_get(id_)
if not vm_ref:
vm_ref = func(session, data)
- vm_ref_cache_update(id, vm_ref)
+ vm_ref_cache_update(id_, vm_ref)
return vm_ref
def vm_ref_cache_from_instance(func):
@functools.wraps(func)
def wrapper(session, instance):
- id = instance.uuid
- return _vm_ref_cache(id, func, session, instance)
+ id_ = instance.uuid
+ return _vm_ref_cache(id_, func, session, instance)
return wrapper
@@ -1536,8 +1536,8 @@ def find_rescue_device(hardware_devices, instance):
raise exception.NotFound(msg)
-def get_ephemeral_name(id):
- return 'ephemeral_%d.vmdk' % id
+def get_ephemeral_name(id_):
+ return 'ephemeral_%d.vmdk' % id_
def _detach_and_delete_devices_config_spec(client_factory, devices):
@@ -1619,11 +1619,11 @@ def folder_ref_cache_get(path):
return _FOLDER_PATH_REF_MAPPING.get(path)
-def _get_vm_name(display_name, id):
+def _get_vm_name(display_name, id_):
if display_name:
- return '%s (%s)' % (display_name[:41], id[:36])
- else:
- return id[:36]
+ return '%s (%s)' % (display_name[:41], id_[:36])
+
+ return id_[:36]
def rename_vm(session, vm_ref, instance):
@@ -1631,3 +1631,36 @@ def rename_vm(session, vm_ref, instance):
rename_task = session._call_method(session.vim, "Rename_Task", vm_ref,
newName=vm_name)
session._wait_for_task(rename_task)
+
+
+def _create_fcd_id_obj(client_factory, fcd_id):
+ id_obj = client_factory.create('ns0:ID')
+ id_obj.id = fcd_id
+ return id_obj
+
+
+def attach_fcd(
+ session, vm_ref, fcd_id, ds_ref_val, controller_key, unit_number
+ ):
+ client_factory = session.vim.client.factory
+ disk_id = _create_fcd_id_obj(client_factory, fcd_id)
+ ds_ref = vutil.get_moref(ds_ref_val, 'Datastore')
+ LOG.debug("Attaching fcd (id: %(fcd_id)s, datastore: %(ds_ref_val)s) to "
+ "vm: %(vm_ref)s.",
+ {'fcd_id': fcd_id,
+ 'ds_ref_val': ds_ref_val,
+ 'vm_ref': vm_ref})
+ task = session._call_method(
+ session.vim, "AttachDisk_Task", vm_ref, diskId=disk_id,
+ datastore=ds_ref, controllerKey=controller_key, unitNumber=unit_number)
+ session._wait_for_task(task)
+
+
+def detach_fcd(session, vm_ref, fcd_id):
+ client_factory = session.vim.client.factory
+ disk_id = _create_fcd_id_obj(client_factory, fcd_id)
+ LOG.debug("Detaching fcd (id: %(fcd_id)s) from vm: %(vm_ref)s.",
+ {'fcd_id': fcd_id, 'vm_ref': vm_ref})
+ task = session._call_method(
+ session.vim, "DetachDisk_Task", vm_ref, diskId=disk_id)
+ session._wait_for_task(task)
diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py
index 1225581deb..f99290573a 100644
--- a/nova/virt/vmwareapi/vmops.py
+++ b/nova/virt/vmwareapi/vmops.py
@@ -263,11 +263,11 @@ class VMwareVMOps(object):
parent_folder = folder_ref
return folder_ref
- def _get_folder_name(self, name, id):
+ def _get_folder_name(self, name, id_):
# Maximum folder length must be less than 80 characters.
# The 'id' length is 36. The maximum prefix for name is 40.
# We cannot truncate the 'id' as this is unique across OpenStack.
- return '%s (%s)' % (name[:40], id[:36])
+ return '%s (%s)' % (name[:40], id_[:36])
def build_virtual_machine(self, instance, image_info,
dc_info, datastore, network_info, extra_specs,
diff --git a/nova/virt/vmwareapi/volumeops.py b/nova/virt/vmwareapi/volumeops.py
index 613dc671c9..a45e084454 100644
--- a/nova/virt/vmwareapi/volumeops.py
+++ b/nova/virt/vmwareapi/volumeops.py
@@ -367,6 +367,53 @@ class VMwareVolumeOps(object):
device_name=device_name)
LOG.debug("Attached ISCSI: %s", connection_info, instance=instance)
+ def _get_controller_key_and_unit(self, vm_ref, adapter_type):
+ LOG.debug("_get_controller_key_and_unit vm: %(vm_ref)s, adapter: "
+ "%(adapter)s.",
+ {'vm_ref': vm_ref, 'adapter': adapter_type})
+ client_factory = self._session.vim.client.factory
+ devices = self._session._call_method(vutil,
+ "get_object_property",
+ vm_ref,
+ "config.hardware.device")
+ return vm_util.allocate_controller_key_and_unit_number(
+ client_factory, devices, adapter_type)
+
+ def _attach_fcd(self, vm_ref, adapter_type, fcd_id, ds_ref_val):
+ (controller_key, unit_number,
+ controller_spec) = self._get_controller_key_and_unit(
+ vm_ref, adapter_type)
+
+ if controller_spec:
+ # No controller available to attach, create one first.
+ config_spec = self._session.vim.client.factory.create(
+ 'ns0:VirtualMachineConfigSpec')
+ config_spec.deviceChange = [controller_spec]
+ vm_util.reconfigure_vm(self._session, vm_ref, config_spec)
+ (controller_key, unit_number,
+ controller_spec) = self._get_controller_key_and_unit(
+ vm_ref, adapter_type)
+
+ vm_util.attach_fcd(
+ self._session, vm_ref, fcd_id, ds_ref_val, controller_key,
+ unit_number)
+
+ def _attach_volume_fcd(self, connection_info, instance):
+ """Attach fcd volume storage to VM instance."""
+ LOG.debug("_attach_volume_fcd: %s", connection_info, instance=instance)
+ vm_ref = vm_util.get_vm_ref(self._session, instance)
+ data = connection_info['data']
+ adapter_type = data['adapter_type']
+
+ if adapter_type == constants.ADAPTER_TYPE_IDE:
+ state = vm_util.get_vm_state(self._session, instance)
+ if state != power_state.SHUTDOWN:
+ raise exception.Invalid(_('%s does not support disk '
+ 'hotplug.') % adapter_type)
+
+ self._attach_fcd(vm_ref, adapter_type, data['id'], data['ds_ref_val'])
+ LOG.debug("Attached fcd: %s", connection_info, instance=instance)
+
def attach_volume(self, connection_info, instance, adapter_type=None):
"""Attach volume storage to VM instance."""
driver_type = connection_info['driver_volume_type']
@@ -376,6 +423,8 @@ class VMwareVolumeOps(object):
self._attach_volume_vmdk(connection_info, instance, adapter_type)
elif driver_type == constants.DISK_FORMAT_ISCSI:
self._attach_volume_iscsi(connection_info, instance, adapter_type)
+ elif driver_type == constants.DISK_FORMAT_FCD:
+ self._attach_volume_fcd(connection_info, instance)
else:
raise exception.VolumeDriverNotFound(driver_type=driver_type)
@@ -558,6 +607,20 @@ class VMwareVolumeOps(object):
self.detach_disk_from_vm(vm_ref, instance, device, destroy_disk=True)
LOG.debug("Detached ISCSI: %s", connection_info, instance=instance)
+ def _detach_volume_fcd(self, connection_info, instance):
+ """Detach fcd volume storage to VM instance."""
+ vm_ref = vm_util.get_vm_ref(self._session, instance)
+ data = connection_info['data']
+ adapter_type = data['adapter_type']
+
+ if adapter_type == constants.ADAPTER_TYPE_IDE:
+ state = vm_util.get_vm_state(self._session, instance)
+ if state != power_state.SHUTDOWN:
+ raise exception.Invalid(_('%s does not support disk '
+ 'hotplug.') % adapter_type)
+
+ vm_util.detach_fcd(self._session, vm_ref, data['id'])
+
def detach_volume(self, connection_info, instance):
"""Detach volume storage to VM instance."""
driver_type = connection_info['driver_volume_type']
@@ -567,6 +630,8 @@ class VMwareVolumeOps(object):
self._detach_volume_vmdk(connection_info, instance)
elif driver_type == constants.DISK_FORMAT_ISCSI:
self._detach_volume_iscsi(connection_info, instance)
+ elif driver_type == constants.DISK_FORMAT_FCD:
+ self._detach_volume_fcd(connection_info, instance)
else:
raise exception.VolumeDriverNotFound(driver_type=driver_type)