diff options
Diffstat (limited to 'nova/virt/vmwareapi')
-rw-r--r-- | nova/virt/vmwareapi/constants.py | 3 | ||||
-rw-r--r-- | nova/virt/vmwareapi/driver.py | 1 | ||||
-rw-r--r-- | nova/virt/vmwareapi/vm_util.py | 67 | ||||
-rw-r--r-- | nova/virt/vmwareapi/vmops.py | 4 | ||||
-rw-r--r-- | nova/virt/vmwareapi/volumeops.py | 65 |
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) |