From 0b2806542bf37cda2e7cecc801aa00f3b9c48b44 Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Fri, 29 Oct 2021 10:03:12 +0200 Subject: [PATCH 1/8] Store instance.uuid as resource_uuid Currently, the code relies on passing instance to each log call as a keyword parameter. The issue there is, that it is not done necessarily 100% consistently, which causes difficulty to match the log messages with the instance at time. Also it requires at some places the caller to pass the instance purely for logging purposes. Finally, this allows olso.log to remove nova specific code to handle the instance/instance_uuid, but use the generic resource_uuid from the context. Change-Id: I3aade880d3cf5edb0d866b6b72fdeec8a0ae0679 --- nova/compute/api.py | 3 ++- nova/compute/manager.py | 6 ++++++ nova/conductor/manager.py | 8 ++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 8b763ff22fd..89add8fdbd1 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -2454,7 +2454,8 @@ def get(self, context, instance_id, expected_attrs=None): except exception.InvalidID: LOG.debug("Invalid instance id %s", instance_id) raise exception.InstanceNotFound(instance_id=instance_id) - + context.resource_id = instance.uuid + context.update_store() return instance def get_all(self, context, search_opts=None, limit=None, marker=None, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 9fda5459d14..170c925c897 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1952,6 +1952,9 @@ def build_and_run_instance(self, context, instance, image, request_spec, @utils.synchronized(instance.uuid) def _locked_do_build_and_run_instance(*args, **kwargs): + # NOTE(fwiesel): Spawned in a different thread, store the context + context.update_store() + # NOTE(danms): We grab the semaphore with the instance uuid # locked because we could wait in line to build this instance # for a while and we want to make sure that nothing else tries @@ -7929,6 +7932,9 @@ def _sync_power_states(self, context): 'num_vm_instances': num_vm_instances}) def _sync(db_instance): + context.resource_uuid = db_instance.uuid + context.update_store() + # NOTE(melwitt): This must be synchronized as we query state from # two separate sources, the driver and the database. # They are set (in stop_instance) and read, in sync. diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 9d4f6ef7fde..a3f161fb643 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -669,6 +669,8 @@ def build_instances(self, context, instances, image, filter_properties, elevated = context.elevated() for (instance, host_list) in six.moves.zip(instances, host_lists): + context.resource_uuid = instance.uuid + context.update_store() host = host_list.pop(0) if is_reschedule: # If this runs in the superconductor, the first instance will @@ -774,7 +776,7 @@ def build_instances(self, context, instances, image, filter_properties, alts = [(alt.service_host, alt.nodename) for alt in host_list] LOG.debug("Selected host: %s; Selected node: %s; Alternates: %s", - host.service_host, host.nodename, alts, instance=instance) + host.service_host, host.nodename, alts) self.compute_rpcapi.build_and_run_instance(context, instance=instance, host=host.service_host, image=image, @@ -1374,13 +1376,15 @@ def schedule_and_build_instances(self, context, build_requests, # Skip placeholders that were buried in cell0 or had their # build requests deleted by the user before instance create. continue + context.resource_uuid = instance.uuid + context.update_store() cell = cell_mapping_cache[instance.uuid] # host_list is a list of one or more Selection objects, the first # of which has been selected and its resources claimed. host = host_list.pop(0) alts = [(alt.service_host, alt.nodename) for alt in host_list] LOG.debug("Selected host: %s; Selected node: %s; Alternates: %s", - host.service_host, host.nodename, alts, instance=instance) + host.service_host, host.nodename, alts) filter_props = request_spec.to_legacy_filter_properties_dict() scheduler_utils.populate_retry(filter_props, instance.uuid) scheduler_utils.populate_filter_properties(filter_props, From 47df9c44c3f2c1ff7c26370f93bad9a9dd5860c3 Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Mon, 27 Dec 2021 09:19:09 +0100 Subject: [PATCH 2/8] Vmwareapi: Remove instance from logs The resource_id is now set automatically, so no need to set it explicitly. Change-Id: Ia2b9ed0167a6420b7441401c5f4614b2ce305962 --- nova/virt/vmwareapi/driver.py | 33 ++--- nova/virt/vmwareapi/images.py | 27 ++-- nova/virt/vmwareapi/vm_util.py | 30 ++--- nova/virt/vmwareapi/vmops.py | 218 +++++++++++++------------------ nova/virt/vmwareapi/volumeops.py | 55 +++----- 5 files changed, 150 insertions(+), 213 deletions(-) diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index d94410009f9..462f1e77e84 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -326,7 +326,7 @@ def get_console_output(self, context, instance): path = os.path.join(CONF.vmware.serial_log_dir, fname) if not os.path.exists(path): LOG.warning('The console log is missing. Check your VSPC ' - 'configuration', instance=instance) + 'configuration') return b"" read_log_data, remaining = nova.privsep.path.last_bytes( path, MAX_CONSOLE_BYTES) @@ -528,8 +528,7 @@ def detach_volume(self, context, connection_info, instance, mountpoint, """Detach volume storage to VM instance.""" if not self._vmops.is_instance_in_resource_pool(instance): LOG.debug("Not detaching %s, vm is in different cluster", - connection_info["volume_id"], - instance=instance) + connection_info["volume_id"]) return True # NOTE(claudiub): if context parameter is to be used in the future, # the _detach_instance_volumes method will have to be updated as well. @@ -572,15 +571,13 @@ def _detach_instance_volumes(self, instance, block_device_info): disk.get('device_name')) except exception.DiskNotFound: LOG.warning('The volume %s does not exist!', - disk.get('device_name'), - instance=instance) + disk.get('device_name')) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error("Failed to detach %(device_name)s. " "Exception: %(exc)s", {'device_name': disk.get('device_name'), - 'exc': e}, - instance=instance) + 'exc': e}) def destroy(self, context, instance, network_info, block_device_info=None, destroy_disks=True): @@ -604,8 +601,7 @@ def destroy(self, context, instance, network_info, block_device_info=None, except (vexc.ManagedObjectNotFoundException, exception.InstanceNotFound): LOG.warning('Instance does not exists. Proceeding to ' - 'delete instance properties on datastore', - instance=instance) + 'delete instance properties on datastore') self._vmops.destroy(context, instance, destroy_disks) def pause(self, instance): @@ -851,7 +847,7 @@ def _pre_live_migration(self, context, instance, block_device_info, if hasattr(result, 'drsFault'): LOG.error("Placement Error: %s", vim_util.serialize_object( - result.drsFault), instance=instance) + result.drsFault)) if (not hasattr(result, 'recommendations') or not result.recommendations): @@ -906,12 +902,12 @@ def live_migration(self, context, instance, dest, """Live migration of an instance to another host.""" if not migrate_data: LOG.error("live_migration() called without migration_data" - " - cannot continue operations", instance=instance) + " - cannot continue operations") recover_method(context, instance, dest, migrate_data) raise ValueError("Missing migrate_data") if migrate_data.instance_already_migrated: - LOG.info("Recovering migration", instance=instance) + LOG.info("Recovering migration") post_method(context, instance, dest, block_migration, migrate_data) return @@ -933,16 +929,15 @@ def live_migration(self, context, instance, dest, required_volume_attributes) self._set_vif_infos(migrate_data, dest_session) self._vmops.live_migration(instance, migrate_data, volumes) - LOG.info("Migration operation completed", instance=instance) + LOG.info("Migration operation completed") post_method(context, instance, dest, block_migration, migrate_data) except Exception: - LOG.exception("Failed due to an exception", instance=instance) + LOG.exception("Failed due to an exception") with excutils.save_and_reraise_exception(): # We are still in the task-state migrating, so cannot # recover the DRS settings. We rely on the sync to do that LOG.debug("Calling live migration recover_method " - "for instance: %s", instance["name"], - instance=instance) + "for instance: %s", instance["name"]) recover_method(context, instance, dest, migrate_data) def _get_volume_mappings(self, context, instance): @@ -967,7 +962,7 @@ def _get_volume_mappings(self, context, instance): message = ("Could not parse connection_info for volume {}." " Reason: {}" ).format(bdm.volume_id, e) - LOG.warning(message, instance=instance) + LOG.warning(message) # Normalize the datastore reference # As it depends on the caller, if actually need the @@ -1019,7 +1014,7 @@ def rollback_live_migration_at_destination(self, context, instance, migrate_data=None): """Clean up destination node after a failed live migration.""" LOG.info("rollback_live_migration_at_destination %s", - block_device_info, instance=instance) + block_device_info) if not migrate_data.is_same_vcenter: self._volumeops.delete_shadow_vms(block_device_info, instance) @@ -1067,7 +1062,7 @@ def post_live_migration_at_destination(self, context, instance, with self._error_out_instance_on_exception(instance, "fixup shadow vms"): volumes = self._get_volume_mappings(context, instance) - LOG.debug("Fixing shadow vms %s", volumes, instance=instance) + LOG.debug("Fixing shadow vms %s", volumes) self._volumeops.fixup_shadow_vms(instance, volumes) def ensure_filtering_rules_for_instance(self, instance, network_info): diff --git a/nova/virt/vmwareapi/images.py b/nova/virt/vmwareapi/images.py index dac18c3c5fe..df13b9b7bcc 100644 --- a/nova/virt/vmwareapi/images.py +++ b/nova/virt/vmwareapi/images.py @@ -227,8 +227,7 @@ def image_transfer(read_handle, write_handle): def upload_iso_to_datastore(iso_path, instance, **kwargs): - LOG.debug("Uploading iso %s to datastore", iso_path, - instance=instance) + LOG.debug("Uploading iso %s to datastore", iso_path) with open(iso_path, 'r') as iso_file: write_file_handle = rw_handles.FileWriteHandle( kwargs.get("host"), @@ -248,8 +247,7 @@ def upload_iso_to_datastore(iso_path, instance, **kwargs): data = iso_file.read(block_size) write_file_handle.close() - LOG.debug("Uploaded iso %s to datastore", iso_path, - instance=instance) + LOG.debug("Uploaded iso %s to datastore", iso_path) def fetch_image(context, instance, host, port, dc_name, ds_name, file_path, @@ -259,8 +257,7 @@ def fetch_image(context, instance, host, port, dc_name, ds_name, file_path, LOG.debug("Downloading image file data %(image_ref)s to the " "data store %(data_store_name)s", {'image_ref': image_ref, - 'data_store_name': ds_name}, - instance=instance) + 'data_store_name': ds_name}) metadata = IMAGE_API.get(context, image_ref) file_size = int(metadata['size']) @@ -274,8 +271,7 @@ def fetch_image(context, instance, host, port, dc_name, ds_name, file_path, "%(data_store_name)s", {'image_ref': image_ref, 'upload_name': 'n/a' if file_path is None else file_path, - 'data_store_name': 'n/a' if ds_name is None else ds_name}, - instance=instance) + 'data_store_name': 'n/a' if ds_name is None else ds_name}) def _build_shadow_vm_config_spec(session, name, size_kb, disk_type, ds_name): @@ -350,8 +346,7 @@ def fetch_image_stream_optimized(context, instance, session, vm_name, image_ref = image_id if image_id else instance.image_ref LOG.debug("Downloading image file data %(image_ref)s to the ESX " "as VM named '%(vm_name)s'", - {'image_ref': image_ref, 'vm_name': vm_name}, - instance=instance) + {'image_ref': image_ref, 'vm_name': vm_name}) metadata = IMAGE_API.get(context, image_ref) file_size = int(metadata['size']) @@ -367,7 +362,7 @@ def fetch_image_stream_optimized(context, instance, session, vm_name, file_size) LOG.info("Downloaded image file data %(image_ref)s", - {'image_ref': instance.image_ref}, instance=instance) + {'image_ref': instance.image_ref}) vmdk = vm_util.get_vmdk_info(session, imported_vm_ref, vm_name) vm_util.mark_vm_as_template(session, instance, imported_vm_ref) return vmdk.capacity_in_bytes, vmdk.path @@ -487,8 +482,7 @@ def fetch_image_ova(context, instance, session, vm_name, ds_name, image_ref = instance.image_ref LOG.debug("Downloading OVA image file %(image_ref)s to the ESX " "as VM named '%(vm_name)s'", - {'image_ref': image_ref, 'vm_name': vm_name}, - instance=instance) + {'image_ref': image_ref, 'vm_name': vm_name}) metadata = IMAGE_API.get(context, image_ref) file_size = int(metadata['size']) @@ -515,7 +509,7 @@ def fetch_image_ova(context, instance, session, vm_name, ds_name, file_size) LOG.info("Downloaded OVA image file %(image_ref)s", - {'image_ref': instance.image_ref}, instance=instance) + {'image_ref': instance.image_ref}) vmdk = vm_util.get_vmdk_info(session, imported_vm_ref, vm_name) @@ -529,7 +523,7 @@ def fetch_image_ova(context, instance, session, vm_name, ds_name, def upload_image_stream_optimized(context, image_id, instance, session, vm, vmdk_size): """Upload the snapshotted vm disk file to Glance image server.""" - LOG.debug("Uploading image %s", image_id, instance=instance) + LOG.debug("Uploading image %s", image_id) metadata = IMAGE_API.get(context, image_id) read_handle = rw_handles.VmdkReadHandle(session, @@ -560,5 +554,4 @@ def upload_image_stream_optimized(context, image_id, instance, session, updater.stop() read_handle.close() - LOG.debug("Uploaded image %s to the Glance image server", image_id, - instance=instance) + LOG.debug("Uploaded image %s to the Glance image server", image_id) diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 0a0a758f0a4..673ffe27e3b 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -1726,7 +1726,7 @@ def get_vmdk_adapter_type(adapter_type): def create_vm(session, instance, vm_folder, config_spec, res_pool_ref): """Create VM on ESX host.""" - LOG.debug("Creating VM on the ESX host", instance=instance) + LOG.debug("Creating VM on the ESX host") vm_create_task = session._call_method( session.vim, "CreateVM_Task", vm_folder, @@ -1748,7 +1748,7 @@ def create_vm(session, instance, vm_folder, config_spec, res_pool_ref): '\'%(ostype)s\'. An invalid os type may be ' 'one cause of this instance creation failure', {'ostype': config_spec.guestId}) - LOG.debug("Created VM on the ESX host", instance=instance) + LOG.debug("Created VM on the ESX host") return task_info.result @@ -1756,11 +1756,11 @@ def create_vm(session, instance, vm_folder, config_spec, res_pool_ref): def _destroy_vm(session, instance, vm_ref=None): if not vm_ref: vm_ref = get_vm_ref(session, instance) - LOG.debug("Destroying the VM", instance=instance) + LOG.debug("Destroying the VM") destroy_task = session._call_method(session.vim, "Destroy_Task", vm_ref) session._wait_for_task(destroy_task) - LOG.info("Destroyed the VM", instance=instance) + LOG.info("Destroyed the VM") def destroy_vm(session, instance, vm_ref=None): @@ -1769,13 +1769,13 @@ def destroy_vm(session, instance, vm_ref=None): return _destroy_vm(session, instance, vm_ref=vm_ref) except vexc.VimFaultException as e: with excutils.save_and_reraise_exception() as ctx: - LOG.exception(_('Destroy VM failed'), instance=instance) + LOG.exception(_('Destroy VM failed')) # we need the `InvalidArgument` fault to bubble out of this # function so it can be acted upon on higher levels if 'InvalidArgument' not in e.fault_list: ctx.reraise = False except Exception: - LOG.exception(_('Destroy VM failed'), instance=instance) + LOG.exception(_('Destroy VM failed')) def mark_vm_as_template(session, instance, vm_ref=None): @@ -1783,11 +1783,11 @@ def mark_vm_as_template(session, instance, vm_ref=None): try: if not vm_ref: vm_ref = get_vm_ref(session, instance) - LOG.debug("Marking the VM as template", instance=instance) + LOG.debug("Marking the VM as template") session._call_method(session.vim, "MarkAsTemplate", vm_ref) - LOG.info("Marked the VM as template", instance=instance) + LOG.info("Marked the VM as template") except Exception: - LOG.exception(_('Mark VM as template failed'), instance=instance) + LOG.exception(_('Mark VM as template failed')) def create_virtual_disk(session, dc_ref, adapter_type, disk_type, @@ -1866,15 +1866,15 @@ def power_on_instance(session, instance, vm_ref=None): if vm_ref is None: vm_ref = get_vm_ref(session, instance) - LOG.debug("Powering on the VM", instance=instance) + LOG.debug("Powering on the VM") try: poweron_task = session._call_method( session.vim, "PowerOnVM_Task", vm_ref) session._wait_for_task(poweron_task) - LOG.debug("Powered on the VM", instance=instance) + LOG.debug("Powered on the VM") except vexc.InvalidPowerStateException: - LOG.debug("VM already powered on", instance=instance) + LOG.debug("VM already powered on") def _get_vm_port_indices(session, vm_ref): @@ -1927,14 +1927,14 @@ def power_off_instance(session, instance, vm_ref=None): if vm_ref is None: vm_ref = get_vm_ref(session, instance) - LOG.debug("Powering off the VM", instance=instance) + LOG.debug("Powering off the VM") try: poweroff_task = session._call_method(session.vim, "PowerOffVM_Task", vm_ref) session._wait_for_task(poweroff_task) - LOG.debug("Powered off the VM", instance=instance) + LOG.debug("Powered off the VM") except vexc.InvalidPowerStateException: - LOG.debug("VM already powered off", instance=instance) + LOG.debug("VM already powered off") def find_rescue_device(hardware_devices, instance): diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index bacecd0e478..724ad74c1d0 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -49,7 +49,6 @@ from nova.console import type as ctype from nova import context as nova_context from nova import exception -from nova.i18n import _, _LI from nova import network from nova import objects from nova.objects import fields @@ -178,8 +177,7 @@ def _get_base_folder(self): def _extend_virtual_disk(self, instance, requested_size, name, dc_ref): service_content = self._session.vim.service_content - LOG.debug("Extending root virtual disk to %s", requested_size, - instance=instance) + LOG.debug("Extending root virtual disk to %s", requested_size) vmdk_extend_task = self._session._call_method( self._session.vim, "ExtendVirtualDisk_Task", @@ -193,14 +191,14 @@ def _extend_virtual_disk(self, instance, requested_size, name, dc_ref): except Exception as e: with excutils.save_and_reraise_exception(): LOG.error('Extending virtual disk failed with error: %s', - e, instance=instance) + e) # Clean up files created during the extend operation files = [name.replace(".vmdk", "-flat.vmdk"), name] for file in files: ds_path = ds_obj.DatastorePath.parse(file) self._delete_datastore_file(ds_path, dc_ref) - LOG.debug("Extended root virtual disk", instance=instance) + LOG.debug("Extended root virtual disk") def _delete_datastore_file(self, datastore_path, dc_ref): try: @@ -312,7 +310,7 @@ def _get_vm_config_spec(self, instance, image_info, utils.is_neutron(), image_info.vif_model, network_info) - LOG.debug('Instance VIF info %s', vif_infos, instance=instance) + LOG.debug('Instance VIF info %s', vif_infos) if extra_specs.storage_policy: profile_spec = vm_util.get_storage_profile_spec( @@ -441,8 +439,7 @@ def _fetch_vsphere_image(self, context, vi, image_ds_loc): "%(datastore_name)s", {'image_id': vi.ii.image_id, 'file_path': image_ds_loc, - 'datastore_name': vi.datastore.name}, - instance=vi.instance) + 'datastore_name': vi.datastore.name}) location_url = ds_obj.DatastoreURL.urlparse(location) datacenter_path = location_url.datacenter_path @@ -460,8 +457,7 @@ def _fetch_vsphere_image(self, context, vi, image_ds_loc): "%(datastore_name)s", {'image_id': vi.ii.image_id, 'file_path': image_ds_loc, - 'datastore_name': vi.datastore.name}, - instance=vi.instance) + 'datastore_name': vi.datastore.name}) def _fetch_image_as_file(self, context, vi, image_ds_loc): """Download image as an individual file to host via HTTP PUT.""" @@ -472,8 +468,7 @@ def _fetch_image_as_file(self, context, vi, image_ds_loc): "%(datastore_name)s", {'image_id': vi.ii.image_id, 'file_path': image_ds_loc, - 'datastore_name': vi.datastore.name}, - instance=vi.instance) + 'datastore_name': vi.datastore.name}) # try to get esx cookie to upload try: @@ -481,8 +476,7 @@ def _fetch_image_as_file(self, context, vi, image_ds_loc): host, cookies = self._get_esx_host_and_cookies(vi.datastore, dc_path, image_ds_loc.rel_path) except Exception as e: - LOG.warning("Get esx cookies failed: %s", e, - instance=vi.instance) + LOG.warning("Get esx cookies failed: %s", e) dc_path = vutil.get_inventory_path(session.vim, vi.dc_info.ref) host = self._session._host @@ -513,8 +507,7 @@ def _fetch_image_as_vapp(self, context, vi, image_ds_loc): "%(datastore_name)s as vApp", {'image_id': vi.ii.image_id, 'vm_name': vm_name, - 'datastore_name': vi.datastore.name}, - instance=vi.instance) + 'datastore_name': vi.datastore.name}) image_size, src_folder_ds_path = images.fetch_image_stream_optimized( context, @@ -652,18 +645,17 @@ def _unregister_template_vm(self, templ_vm_ref, instance=None): """ try: LOG.debug("Unregistering the template VM %s", - templ_vm_ref.value, - instance=instance) + templ_vm_ref.value) self._session._call_method(self._session.vim, "UnregisterVM", templ_vm_ref) - LOG.debug("Unregistered the template VM", instance=instance) + LOG.debug("Unregistered the template VM") except Exception as excep: LOG.warning("got this exception while un-registering a ", "template VM: %s", - excep, instance=instance) + excep) def _cache_vm_image_from_template(self, vi, templ_vm_ref): - LOG.debug("Caching VDMK from template VM", instance=vi.instance) + LOG.debug("Caching VDMK from template VM") vm_name = self._get_image_template_vm_name(vi.ii.image_id, vi.datastore.name) vmdk = vm_util.get_vmdk_info(self._session, templ_vm_ref, vm_name) @@ -675,11 +667,11 @@ def _cache_vm_image_from_template(self, vi, templ_vm_ref): self._cache_vm_image(vi, vmdk.path) except vexc.FileNotFoundException: LOG.warning("Could not find files for template VM %s", - templ_vm_ref.value, instance=vi.instance) + templ_vm_ref.value) self._unregister_template_vm(templ_vm_ref, vi.instance) return False - LOG.debug("Cached VDMK from template VM", instance=vi.instance) + LOG.debug("Cached VDMK from template VM") return True def _cache_stream_optimized_image(self, vi, tmp_image_ds_loc): @@ -789,7 +781,7 @@ def _fetch_image_from_other_datastores(self, vi): self._session._wait_for_task(templ_vm_clone_task) except vexc.FileNotFoundException: LOG.warning("Could not find files for template VM %s", - other_templ_vm_ref.value, instance=vi.instance) + other_templ_vm_ref.value) continue except vexc.VimFaultException as e: if 'VirtualHardwareVersionNotSupported' in e.fault_list: @@ -805,7 +797,7 @@ def _fetch_image_from_other_datastores(self, vi): def _fetch_image_if_missing(self, context, vi): image_prepare, image_fetch, image_cache = self._get_image_callbacks(vi) - LOG.debug("Processing image %s", vi.ii.image_id, instance=vi.instance) + LOG.debug("Processing image %s", vi.ii.image_id) with lockutils.lock(str(vi.cache_image_path), lock_file_prefix='nova-vmware-fetch_image'): @@ -824,7 +816,7 @@ def _fetch_image_if_missing(self, context, vi): if not image_available: # no matter if image_as_template is set, we can use the # template_vm in any case - LOG.debug("Trying to find template VM", instance=vi.instance) + LOG.debug("Trying to find template VM") templ_vm_ref = self._find_image_template_vm(vi) image_available = (templ_vm_ref is not None) if image_available and not CONF.vmware.image_as_template: @@ -834,8 +826,7 @@ def _fetch_image_if_missing(self, context, vi): if (not image_available and CONF.vmware.fetch_image_from_other_datastores): # fetching from another DS is still faster - LOG.debug("Trying to find template VM on other DS", - instance=vi.instance) + LOG.debug("Trying to find template VM on other DS") templ_vm_ref = self._fetch_image_from_other_datastores(vi) image_available = (templ_vm_ref is not None) if image_available and not CONF.vmware.image_as_template: @@ -844,15 +835,13 @@ def _fetch_image_if_missing(self, context, vi): if not image_available: # we didn't find it anywhere. upload it - LOG.debug("Preparing fetch location", instance=vi.instance) + LOG.debug("Preparing fetch location") tmp_dir_loc, tmp_image_ds_loc = image_prepare(vi) - LOG.debug("Fetch image to %s", tmp_image_ds_loc, - instance=vi.instance) + LOG.debug("Fetch image to %s", tmp_image_ds_loc) image_fetch(context, vi, tmp_image_ds_loc) - LOG.debug("Caching image", instance=vi.instance) + LOG.debug("Caching image") image_cache(vi, tmp_image_ds_loc) - LOG.debug("Cleaning up location %s", str(tmp_dir_loc), - instance=vi.instance) + LOG.debug("Cleaning up location %s", str(tmp_dir_loc)) if tmp_dir_loc: self._delete_datastore_file(str(tmp_dir_loc), vi.dc_info.ref) @@ -988,13 +977,13 @@ def _create_image_template(self, context, vi, extra_specs): reraise=is_last_attempt): LOG.error('Creating VM template for image failed' ' with error: %s', - create_templ_exc, instance=vi.instance) + create_templ_exc) try: vm_util.destroy_vm(self._session, vi.instance) except Exception as destroy_templ_exc: LOG.error('Cleaning up VM template for' ' image failed with error: %s', - destroy_templ_exc, instance=vi.instance) + destroy_templ_exc) def _build_template_vm_inventory_path(self, vi): vm_folder_name = self._session._call_method(vutil, @@ -1248,7 +1237,7 @@ def spawn(self, context, instance, image_meta, injected_files, msg = "Block device information present: %s" % block_device_info # NOTE(mriedem): block_device_info can contain an auth_password # so we have to scrub the message before logging it. - LOG.debug(strutils.mask_password(msg), instance=instance) + LOG.debug(strutils.mask_password(msg)) # Before attempting to attach any volume, make sure the # block_device_mapping (i.e. disk_bus) is valid @@ -1297,8 +1286,7 @@ def disable_drs_if_needed(self, instance): if utils.is_big_vm(int(instance.memory_mb), instance.flavor) or \ utils.is_large_vm(int(instance.memory_mb), instance.flavor): behavior = constants.DRS_BEHAVIOR_PARTIALLY_AUTOMATED - LOG.debug("Adding DRS override '%s' for big VM.", behavior, - instance=instance) + LOG.debug("Adding DRS override '%s' for big VM.", behavior) vm_ref = vm_util.get_vm_ref(self._session, instance) cluster_util.update_cluster_drs_vm_override(self._session, self._cluster, @@ -1357,7 +1345,7 @@ def _create_config_drive(self, context, instance, injected_files, CONF.config_drive_format) raise exception.InstancePowerOnFailure(reason=reason) - LOG.info('Using config drive for instance', instance=instance) + LOG.info('Using config drive for instance') extra_md = {} if admin_password: extra_md['admin_pass'] = admin_password @@ -1386,7 +1374,7 @@ def _create_config_drive(self, context, instance, injected_files, except Exception as e: with excutils.save_and_reraise_exception(): LOG.error('Creating config drive failed with error: %s', - e, instance=instance) + e) def _attach_cdrom_to_vm(self, vm_ref, instance, datastore, file_path): @@ -1405,13 +1393,13 @@ def _attach_cdrom_to_vm(self, vm_ref, instance, cdrom_attach_config_spec.deviceChange.append(controller_spec) LOG.debug("Reconfiguring VM instance to attach cdrom %s", - file_path, instance=instance) + file_path) vm_util.reconfigure_vm(self._session, vm_ref, cdrom_attach_config_spec) LOG.debug("Reconfigured VM instance to attach cdrom %s", - file_path, instance=instance) + file_path) def _create_vm_snapshot(self, instance, vm_ref, image_id=None): - LOG.debug("Creating Snapshot of the VM instance", instance=instance) + LOG.debug("Creating Snapshot of the VM instance") snapshot_task = self._session._call_method( self._session.vim, "CreateSnapshot_Task", vm_ref, @@ -1420,7 +1408,7 @@ def _create_vm_snapshot(self, instance, vm_ref, image_id=None): memory=False, quiesce=True) self._session._wait_for_task(snapshot_task) - LOG.debug("Created Snapshot of the VM instance", instance=instance) + LOG.debug("Created Snapshot of the VM instance") task_info = self._session._call_method(vutil, "get_object_property", snapshot_task, @@ -1430,13 +1418,13 @@ def _create_vm_snapshot(self, instance, vm_ref, image_id=None): @retry_if_task_in_progress def _delete_vm_snapshot(self, instance, vm_ref, snapshot): - LOG.debug("Deleting Snapshot of the VM instance", instance=instance) + LOG.debug("Deleting Snapshot of the VM instance") delete_snapshot_task = self._session._call_method( self._session.vim, "RemoveSnapshot_Task", snapshot, removeChildren=False, consolidate=True) self._session._wait_for_task(delete_snapshot_task) - LOG.debug("Deleted Snapshot of the VM instance", instance=instance) + LOG.debug("Deleted Snapshot of the VM instance") def _create_linked_clone_from_snapshot(self, instance, vm_ref, snapshot_ref, dc_info): @@ -1453,7 +1441,7 @@ def _create_linked_clone_from_snapshot(self, instance, vm_name = "%s_%s" % (constants.SNAPSHOT_VM_PREFIX, uuidutils.generate_uuid()) - LOG.debug("Creating linked-clone VM from snapshot", instance=instance) + LOG.debug("Creating linked-clone VM from snapshot") vm_clone_task = self._session._call_method( self._session.vim, "CloneVM_Task", @@ -1462,7 +1450,7 @@ def _create_linked_clone_from_snapshot(self, instance, name=vm_name, spec=clone_spec) self._session._wait_for_task(vm_clone_task) - LOG.info("Created linked-clone VM from snapshot", instance=instance) + LOG.info("Created linked-clone VM from snapshot") task_info = self._session._call_method(vutil, "get_object_property", vm_clone_task, @@ -1545,7 +1533,7 @@ def _create_vm_clone(self, instance, vm_ref, snapshot_ref, dc_info, template=True, config=config_spec) - LOG.debug("Cloning VM %s", vm_name, instance=instance) + LOG.debug("Cloning VM %s", vm_name) vm_clone_task = self._session._call_method( self._session.vim, "CloneVM_Task", @@ -1556,8 +1544,7 @@ def _create_vm_clone(self, instance, vm_ref, snapshot_ref, dc_info, name=vm_name, spec=clone_spec) self._session._wait_for_task(vm_clone_task) - LOG.info(_LI("Cloned VM %s"), vm_name, - instance=instance) + LOG.info("Cloned VM %s", vm_name) task_info = self._session._call_method(vutil, "get_object_property", vm_clone_task, @@ -1587,8 +1574,7 @@ def _get_vm_and_vmdk_attribs(): vmdk = vm_util.get_vmdk_info(self._session, vm_ref, instance.uuid) if not vmdk.path: - LOG.debug("No root disk defined. Unable to snapshot.", - instance=instance) + LOG.debug("No root disk defined. Unable to snapshot.") raise error_util.NoRootDiskDefined() lst_properties = ["datastore", "summary.config.guestId"] @@ -1672,16 +1658,16 @@ def reboot(self, instance, network_info, reboot_type="SOFT"): if (tools_status == "toolsOk" and tools_running_status == "guestToolsRunning" and reboot_type == "SOFT"): - LOG.debug("Rebooting guest OS of VM", instance=instance) + LOG.debug("Rebooting guest OS of VM") self._session._call_method(self._session.vim, "RebootGuest", vm_ref) - LOG.debug("Rebooted guest OS of VM", instance=instance) + LOG.debug("Rebooted guest OS of VM") else: - LOG.debug("Doing hard reboot of VM", instance=instance) + LOG.debug("Doing hard reboot of VM") reset_task = self._session._call_method(self._session.vim, "ResetVM_Task", vm_ref) self._session._wait_for_task(reset_task) - LOG.debug("Did hard reboot of VM", instance=instance) + LOG.debug("Did hard reboot of VM") def _destroy_instance(self, context, instance, destroy_disks=True): # Destroy a VM instance @@ -1707,14 +1693,14 @@ def _destroy_instance(self, context, instance, destroy_disks=True): # Un-register the VM try: - LOG.debug("Unregistering the VM", instance=instance) + LOG.debug("Unregistering the VM") self._session._call_method(self._session.vim, "UnregisterVM", vm_ref) - LOG.debug("Unregistered the VM", instance=instance) + LOG.debug("Unregistered the VM") except Exception as excep: LOG.warning("In vmwareapi:vmops:_destroy_instance, got " "this exception while un-registering the VM: %s", - excep, instance=instance) + excep) # Delete the folder holding the VM related content on # the datastore. @@ -1723,8 +1709,7 @@ def _destroy_instance(self, context, instance, destroy_disks=True): dir_ds_compliant_path = vm_ds_path.parent LOG.debug("Deleting contents of the VM from " "datastore %(datastore_name)s", - {'datastore_name': vm_ds_path.datastore}, - instance=instance) + {'datastore_name': vm_ds_path.datastore}) ds_ref_ret = props['datastore'] ds_ref = ds_ref_ret.ManagedObjectReference[0] dc_info = self.get_datacenter_ref_and_name(ds_ref) @@ -1733,18 +1718,16 @@ def _destroy_instance(self, context, instance, destroy_disks=True): dc_info.ref) LOG.debug("Deleted contents of the VM from " "datastore %(datastore_name)s", - {'datastore_name': vm_ds_path.datastore}, - instance=instance) + {'datastore_name': vm_ds_path.datastore}) except Exception: LOG.warning("In vmwareapi:vmops:_destroy_instance, " "exception while deleting the VM contents " "from the disk", - exc_info=True, instance=instance) + exc_info=True) except exception.InstanceNotFound: - LOG.warning('Instance does not exist on backend', - instance=instance) + LOG.warning('Instance does not exist on backend') except Exception: - LOG.exception(_('Destroy instance failed'), instance=instance) + LOG.exception(_('Destroy instance failed')) finally: vm_util.vm_ref_cache_delete(instance.uuid) @@ -1756,9 +1739,9 @@ def destroy(self, context, instance, destroy_disks=True): 2. Un-register. 3. Delete the contents of the folder holding the VM related data. """ - LOG.debug("Destroying instance", instance=instance) + LOG.debug("Destroying instance") self._destroy_instance(context, instance, destroy_disks=destroy_disks) - LOG.debug("Instance destroyed", instance=instance) + LOG.debug("Instance destroyed") def pause(self, instance): msg = _("pause not supported for vmwareapi") @@ -1777,18 +1760,18 @@ def suspend(self, instance): "runtime.powerState") # Only PoweredOn VMs can be suspended. if pwr_state == "poweredOn": - LOG.debug("Suspending the VM", instance=instance) + LOG.debug("Suspending the VM") suspend_task = self._session._call_method(self._session.vim, "SuspendVM_Task", vm_ref) self._session._wait_for_task(suspend_task) - LOG.debug("Suspended the VM", instance=instance) + LOG.debug("Suspended the VM") # Raise Exception if VM is poweredOff elif pwr_state == "poweredOff": reason = _("instance is powered off and cannot be suspended.") raise exception.InstanceSuspendFailure(reason=reason) else: LOG.debug("VM was already in suspended state. So returning " - "without doing anything", instance=instance) + "without doing anything") def resume(self, instance): """Resume the specified instance.""" @@ -1798,12 +1781,12 @@ def resume(self, instance): vm_ref, "runtime.powerState") if pwr_state.lower() == "suspended": - LOG.debug("Resuming the VM", instance=instance) + LOG.debug("Resuming the VM") suspend_task = self._session._call_method( self._session.vim, "PowerOnVM_Task", vm_ref) self._session._wait_for_task(suspend_task) - LOG.debug("Resumed the VM", instance=instance) + LOG.debug("Resumed the VM") else: reason = _("instance is not in a suspended state") raise exception.InstanceResumeFailure(reason=reason) @@ -1871,8 +1854,7 @@ def unrescue(self, instance, power_on=True): rescue_device = self._get_rescue_device(instance, vm_ref) except exception.NotFound: with excutils.save_and_reraise_exception(): - LOG.error('Unable to access the rescue disk', - instance=instance) + LOG.error('Unable to access the rescue disk') vm_util.power_off_instance(self._session, instance, vm_ref) self._volumeops.detach_disk_from_vm(vm_ref, instance, rescue_device, destroy_disk=True) @@ -1906,15 +1888,13 @@ def _clean_shutdown(self, instance, timeout, retry_interval): :return: True if the instance was shutdown within time limit, False otherwise. """ - LOG.debug("Performing Soft shutdown on instance", - instance=instance) + LOG.debug("Performing Soft shutdown on instance") vm_ref = vm_util.get_vm_ref(self._session, instance) props = self._get_instance_props(vm_ref) if props.get("runtime.powerState") != "poweredOn": - LOG.debug("Instance not in poweredOn state.", - instance=instance) + LOG.debug("Instance not in poweredOn state.") return False if ((props.get("summary.guest.toolsStatus") == "toolsOk") and @@ -1922,7 +1902,7 @@ def _clean_shutdown(self, instance, timeout, retry_interval): "guestToolsRunning")): LOG.debug("Soft shutdown instance, timeout: %d", - timeout, instance=instance) + timeout) self._session._call_method(self._session.vim, "ShutdownGuest", vm_ref) @@ -1932,17 +1912,15 @@ def _clean_shutdown(self, instance, timeout, retry_interval): props = self._get_instance_props(vm_ref) if props.get("runtime.powerState") == "poweredOff": - LOG.info("Soft shutdown succeeded.", - instance=instance) + LOG.info("Soft shutdown succeeded.") return True time.sleep(wait_time) timeout -= retry_interval - LOG.warning("Timed out while waiting for soft shutdown.", - instance=instance) + LOG.warning("Timed out while waiting for soft shutdown.") else: - LOG.debug("VMware Tools not running", instance=instance) + LOG.debug("VMware Tools not running") return False @@ -1956,7 +1934,7 @@ def is_instance_in_resource_pool(self, instance): vutil.get_moref_value(self._root_resource_pool) except (exception.InstanceNotFound, vexc.ManagedObjectNotFoundException): - LOG.debug("Failed to find instance", instance=instance) + LOG.debug("Failed to find instance") return False def _get_instance_props(self, vm_ref): @@ -1994,8 +1972,7 @@ def _update_instance_progress(self, context, instance, step, total_steps): instance_uuid = instance.uuid LOG.debug("Updating instance '%(instance_uuid)s' progress to" " %(progress)d", - {'instance_uuid': instance_uuid, 'progress': progress}, - instance=instance) + {'instance_uuid': instance_uuid, 'progress': progress}) instance.progress = progress instance.save() @@ -2023,8 +2000,7 @@ def _resize_vm(self, context, instance, vm_ref, flavor, image_meta): if not old_needs_override and new_needs_override: # Make sure we don't automatically move around "big" VMs behavior = constants.DRS_BEHAVIOR_PARTIALLY_AUTOMATED - LOG.debug("Adding DRS override '%s' for big VM.", behavior, - instance=instance) + LOG.debug("Adding DRS override '%s' for big VM.", behavior) cluster_util.update_cluster_drs_vm_override(self._session, self._cluster, vm_ref, @@ -2033,16 +2009,14 @@ def _resize_vm(self, context, instance, vm_ref, flavor, image_meta): elif old_needs_override and not new_needs_override: # remove the old override, if we had one before. make sure we don't # error out if it was already deleted another way - LOG.debug("Removing DRS override for former big VM.", - instance=instance) + LOG.debug("Removing DRS override for former big VM.") try: cluster_util.update_cluster_drs_vm_override(self._session, self._cluster, vm_ref, operation='remove') except Exception: - LOG.exception('Could not remove DRS override.', - instance=instance) + LOG.exception('Could not remove DRS override.') self._clean_up_after_special_spawning(context, flavor.memory_mb, flavor) @@ -2086,7 +2060,7 @@ def _resize_create_ephemerals_and_swap(self, vm_ref, instance, vmdk = vm_util.get_vmdk_info(self._session, vm_ref, uuid=instance.uuid) if not vmdk.device: - LOG.debug("No root disk attached!", instance=instance) + LOG.debug("No root disk attached!") return ds_ref = vmdk.device.backing.datastore datastore = ds_obj.get_datastore_by_ref(self._session, ds_ref) @@ -2203,16 +2177,13 @@ def finish_revert_migration(self, context, instance, network_info, adapter_type = vmdk.adapter_type self._detach_volumes(instance, block_device_info) - LOG.debug("Relocating VM for reverting migration", - instance=instance) + LOG.debug("Relocating VM for reverting migration") try: self._relocate_vm(vm_ref, context, instance, network_info) - LOG.debug("Relocated VM for reverting migration", - instance=instance) + LOG.debug("Relocated VM for reverting migration") except Exception as e: with excutils.save_and_reraise_exception(): - LOG.error("Relocating the VM failed: %s", e, - instance=instance) + LOG.error("Relocating the VM failed: %s", e) else: self.update_cluster_placement(context, instance) finally: @@ -2243,16 +2214,14 @@ def finish_migration(self, context, migration, instance, disk_info, self._detach_volumes(instance, block_device_info) reattach_volumes = True LOG.debug("Relocating VM for migration to %s", - migration.dest_compute, instance=instance) + migration.dest_compute) try: self._relocate_vm(vm_ref, context, instance, network_info, image_meta) - LOG.debug("Relocated VM to %s", migration.dest_compute, - instance=instance) + LOG.debug("Relocated VM to %s", migration.dest_compute) except Exception as e: with excutils.save_and_reraise_exception(): - LOG.error("Relocating the VM failed with error: %s", e, - instance=instance) + LOG.error("Relocating the VM failed with error: %s", e) self._attach_volumes(instance, block_device_info, adapter_type) @@ -2457,7 +2426,7 @@ def poll_rebooting_instances(self, timeout, instances): "older than %(timeout)d seconds", instances_info) for instance in instances: - LOG.info("Automatically hard rebooting", instance=instance) + LOG.info("Automatically hard rebooting") self.compute_api.reboot(ctxt, instance, "HARD") def get_info(self, instance): @@ -2586,11 +2555,9 @@ def _set_machine_id(self, client_factory, instance, network_info, client_factory, self._get_machine_id_str(network_info)) - LOG.debug("Reconfiguring VM instance to set the machine id", - instance=instance) + LOG.debug("Reconfiguring VM instance to set the machine id") vm_util.reconfigure_vm(self._session, vm_ref, machine_id_change_spec) - LOG.debug("Reconfigured VM instance to set the machine id", - instance=instance) + LOG.debug("Reconfigured VM instance to set the machine id") @utils.synchronized('vmware.get_and_set_vnc_port') def _get_and_set_vnc_config(self, client_factory, instance, vm_ref): @@ -2600,12 +2567,10 @@ def _get_and_set_vnc_config(self, client_factory, instance, vm_ref): client_factory, port) LOG.debug("Reconfiguring VM instance to enable vnc on " - "port - %(port)s", {'port': port}, - instance=instance) + "port - %(port)s", {'port': port}) vm_util.reconfigure_vm(self._session, vm_ref, vnc_config_spec) LOG.debug("Reconfigured VM instance to enable vnc on " - "port - %(port)s", {'port': port}, - instance=instance) + "port - %(port)s", {'port': port}) def _get_ds_browser(self, ds_ref): ds_browser = self._datastore_browser_mapping.get(ds_ref.value) @@ -2865,21 +2830,20 @@ def attach_interface(self, context, instance, image_meta, vif): attach_config_spec = vm_util.get_network_attach_config_spec( client_factory, vif_info, port_index, extra_specs.vif_limits) - LOG.debug("Reconfiguring VM to attach interface", - instance=instance) + LOG.debug("Reconfiguring VM to attach interface") try: vm_util.reconfigure_vm(self._session, vm_ref, attach_config_spec) except Exception as e: LOG.error('Attaching network adapter failed. Exception: %s', - e, instance=instance) + e) raise exception.InterfaceAttachFailed( instance_uuid=instance.uuid) self._network_api.update_instance_vnic_index( context, instance, vif, port_index) - LOG.debug("Reconfigured VM to attach interface", instance=instance) + LOG.debug("Reconfigured VM to attach interface") def detach_interface(self, context, instance, vif): """Detach an interface from the instance.""" @@ -2910,17 +2874,16 @@ def detach_interface(self, context, instance, vif): client_factory = self._session.vim.client.factory detach_config_spec = vm_util.get_network_detach_config_spec( client_factory, device, port_index) - LOG.debug("Reconfiguring VM to detach interface", - instance=instance) + LOG.debug("Reconfiguring VM to detach interface") try: vm_util.reconfigure_vm(self._session, vm_ref, detach_config_spec) except Exception as e: LOG.error('Detaching network adapter failed. Exception: %s', - e, instance=instance) + e) raise exception.InterfaceDetachFailed( instance_uuid=instance.uuid) - LOG.debug("Reconfigured VM to detach interface", instance=instance) + LOG.debug("Reconfigured VM to detach interface") def _use_disk_image_as_full_clone(self, vm_ref, vi): """Uses cached image disk by copying it into the VM directory.""" @@ -3105,8 +3068,7 @@ def get_vnc_console(self, instance): # NOTE: VM can move hosts in some situations. Debug for admins. LOG.debug("VM %(uuid)s is currently on host %(host_name)s", - {'uuid': instance.uuid, 'host_name': host_name}, - instance=instance) + {'uuid': instance.uuid, 'host_name': host_name}) return ctype.ConsoleVNC(**vnc_console) def get_mks_console(self, instance): diff --git a/nova/virt/vmwareapi/volumeops.py b/nova/virt/vmwareapi/volumeops.py index 8cd476692bb..dceb8cf7ba7 100644 --- a/nova/virt/vmwareapi/volumeops.py +++ b/nova/virt/vmwareapi/volumeops.py @@ -67,7 +67,7 @@ def attach_disk_to_vm(self, vm_ref, instance, if volume_uuid and backing_uuid: LOG.debug("Adding volume details for %s to attach config spec.", - volume_uuid, instance=instance) + volume_uuid) self._add_volume_details_to_config_spec(vmdk_attach_config_spec, volume_uuid, backing_uuid) @@ -75,15 +75,13 @@ def attach_disk_to_vm(self, vm_ref, instance, "disk %(vmdk_path)s or device %(device_name)s with type " "%(disk_type)s", {'vm_ref': vm_ref.value, 'vmdk_path': vmdk_path, - 'device_name': device_name, 'disk_type': disk_type}, - instance=instance) + 'device_name': device_name, 'disk_type': disk_type}) vm_util.reconfigure_vm(self._session, vm_ref, vmdk_attach_config_spec) LOG.debug("Reconfigured VM instance %(vm_ref)s to attach " "disk %(vmdk_path)s or device %(device_name)s with type " "%(disk_type)s", {'vm_ref': vm_ref.value, 'vmdk_path': vmdk_path, - 'device_name': device_name, 'disk_type': disk_type}, - instance=instance) + 'device_name': device_name, 'disk_type': disk_type}) def _add_volume_details_to_config_spec(self, config_spec, volume_uuid, device_uuid): @@ -118,20 +116,18 @@ def detach_disk_from_vm(self, vm_ref, instance, device, if volume_uuid is not None: LOG.debug("Adding volume details for %s to detach config spec.", - volume_uuid, instance=instance) + volume_uuid) self._add_volume_details_to_config_spec(vmdk_detach_config_spec, volume_uuid, '') disk_key = device.key LOG.debug("Reconfiguring VM instance %(vm_ref)s to detach " "disk %(disk_key)s", - {'vm_ref': vm_ref.value, 'disk_key': disk_key}, - instance=instance) + {'vm_ref': vm_ref.value, 'disk_key': disk_key}) vm_util.reconfigure_vm(self._session, vm_ref, vmdk_detach_config_spec) LOG.debug("Reconfigured VM instance %(vm_ref)s to detach " "disk %(disk_key)s", - {'vm_ref': vm_ref.value, 'disk_key': disk_key}, - instance=instance) + {'vm_ref': vm_ref.value, 'disk_key': disk_key}) def _iscsi_get_target(self, data): """Return the iSCSI Target given a volume info.""" @@ -344,8 +340,7 @@ def _attach_volume_vmdk(self, connection_info, instance, adapter_type=None): """Attach vmdk volume storage to VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) - LOG.debug("_attach_volume_vmdk: %s", connection_info, - instance=instance) + LOG.debug("_attach_volume_vmdk: %s", connection_info) data = connection_info['data'] volume_ref = self._get_volume_ref(data['volume']) @@ -369,15 +364,14 @@ def _attach_volume_vmdk(self, connection_info, instance, volume_uuid=data['volume_id'], backing_uuid=vmdk.device.backing.uuid) - LOG.debug("Attached VMDK: %s", connection_info, instance=instance) + LOG.debug("Attached VMDK: %s", connection_info) def _attach_volume_iscsi(self, connection_info, instance, adapter_type=None): """Attach iscsi volume storage to VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) # Attach Volume to VM - LOG.debug("_attach_volume_iscsi: %s", connection_info, - instance=instance) + LOG.debug("_attach_volume_iscsi: %s", connection_info) data = connection_info['data'] @@ -395,13 +389,12 @@ def _attach_volume_iscsi(self, connection_info, instance, self.attach_disk_to_vm(vm_ref, instance, adapter_type, 'rdmp', device_name=device_name) - LOG.debug("Attached ISCSI: %s", connection_info, instance=instance) + LOG.debug("Attached ISCSI: %s", connection_info) def attach_volume(self, connection_info, instance, adapter_type=None): """Attach volume storage to VM instance.""" driver_type = connection_info['driver_volume_type'] - LOG.debug("Volume attach. Driver type: %s", driver_type, - instance=instance) + LOG.debug("Volume attach. Driver type: %s", driver_type) if driver_type == constants.DISK_FORMAT_VMDK: self._attach_volume_vmdk(connection_info, instance, adapter_type) elif driver_type == constants.DISK_FORMAT_ISCSI: @@ -531,8 +524,7 @@ def _detach_volume_vmdk(self, connection_info, instance): """Detach volume storage to VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) # Detach Volume from VM - LOG.debug("_detach_volume_vmdk: %s", connection_info, - instance=instance) + LOG.debug("_detach_volume_vmdk: %s", connection_info) data = connection_info['data'] volume_ref = self._get_volume_ref(data['volume']) @@ -562,14 +554,13 @@ def _detach_volume_vmdk(self, connection_info, instance): self.detach_disk_from_vm(vm_ref, instance, device, volume_uuid=data['volume_id']) - LOG.debug("Detached VMDK: %s", connection_info, instance=instance) + LOG.debug("Detached VMDK: %s", connection_info) def _detach_volume_iscsi(self, connection_info, instance): """Detach volume storage to VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) # Detach Volume from VM - LOG.debug("_detach_volume_iscsi: %s", connection_info, - instance=instance) + LOG.debug("_detach_volume_iscsi: %s", connection_info) data = connection_info['data'] # Discover iSCSI Target @@ -584,13 +575,12 @@ def _detach_volume_iscsi(self, connection_info, instance): if device is None: raise exception.DiskNotFound(message=_("Unable to find volume")) self.detach_disk_from_vm(vm_ref, instance, device, destroy_disk=True) - LOG.debug("Detached ISCSI: %s", connection_info, instance=instance) + LOG.debug("Detached ISCSI: %s", connection_info) def detach_volume(self, connection_info, instance): """Detach volume storage to VM instance.""" driver_type = connection_info['driver_volume_type'] - LOG.debug("Volume detach. Driver type: %s", driver_type, - instance=instance) + LOG.debug("Volume detach. Driver type: %s", driver_type) if driver_type == constants.DISK_FORMAT_VMDK: self._detach_volume_vmdk(connection_info, instance) elif driver_type == constants.DISK_FORMAT_ISCSI: @@ -602,8 +592,7 @@ def attach_root_volume(self, connection_info, instance, datastore, adapter_type=None): """Attach a root volume to the VM instance.""" driver_type = connection_info['driver_volume_type'] - LOG.debug("Root volume attach. Driver type: %s", driver_type, - instance=instance) + LOG.debug("Root volume attach. Driver type: %s", driver_type) # NOTE(jkulik): Upstream moves the volume to the instance DS here. This # would violate the differentiation between ephemeral and volume DS, so # we don't do that. This comment should help us detect upstream changes @@ -662,7 +651,6 @@ def fixup_shadow_vms(self, instance, shadow_vms): LOG.warning("Shadow-vm %s already has a disk" " attached at %s replacing it with %s", volume, original_device_path, current_device_path, - instance=instance ) self.detach_disk_from_vm(self, volume_ref, instance, original_device, destroy_disk=True) @@ -676,8 +664,7 @@ def fixup_shadow_vms(self, instance, shadow_vms): ) except Exception: LOG.exception("Failed to attach volume {}. Device {}".format( - data["volume_id"], - device.key), instance=instance) + data["volume_id"], device.key)) def delete_shadow_vms(self, block_device_info, instance=None): # We need to delete the migrated shadow vms @@ -702,12 +689,12 @@ def delete_shadow_vms(self, block_device_info, instance=None): deleted.append("{volume_id} ({volume})".format(**data)) except oslo_vmw_exceptions.ManagedObjectNotFoundException: LOG.debug("Volume %s already deleted", - data.get("volume_id"), instance=instance) + data.get("volume_id")) except Exception: LOG.exception("Failed to delete volume %s", - data.get("volume_id"), instance=instance) + data.get("volume_id")) - LOG.info("Deleted %s", deleted, instance=instance) + LOG.info("Deleted %s", deleted) def map_volumes_to_devices(self, instance, disk_infos): """Maps a connection_info.data to a device of the instance by its key From 5a51c673a40647830802768bfe963de3ddc7f075 Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Mon, 25 Oct 2021 10:09:01 +0200 Subject: [PATCH 3/8] vmware: Reduce import scope Especially 'host' was fairly common name and potentially conflicting with the use of variables of the same name Change-Id: Idf3920e5e94c5aef904781bc365fc310496346cd --- nova/virt/vmwareapi/driver.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 462f1e77e84..48587a1e952 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -54,13 +54,13 @@ from nova.virt.vmwareapi import constants from nova.virt.vmwareapi import ds_util from nova.virt.vmwareapi import error_util -from nova.virt.vmwareapi import host +from nova.virt.vmwareapi.host import VCState from nova.virt.vmwareapi import special_spawning from nova.virt.vmwareapi import vif as vmwarevif from nova.virt.vmwareapi import vim_util as nova_vim_util from nova.virt.vmwareapi import vm_util -from nova.virt.vmwareapi import vmops -from nova.virt.vmwareapi import volumeops +from nova.virt.vmwareapi.vmops import VMwareVMOps +from nova.virt.vmwareapi.volumeops import VMwareVolumeOps from oslo_serialization import jsonutils LOG = logging.getLogger(__name__) @@ -137,17 +137,17 @@ def __init__(self, virtapi, scheme="https"): % self._cluster_name) self._vcenter_uuid = self._get_vcenter_uuid() self._nodename = self._create_nodename(self._cluster_ref.value) - self._volumeops = volumeops.VMwareVolumeOps(self._session, - self._cluster_ref) - self._vmops = vmops.VMwareVMOps(self._session, - virtapi, - self._volumeops, - self._cluster_ref, - datastore_regex=self._datastore_regex) - self._vc_state = host.VCState(self._session, - self._nodename, - self._cluster_ref, - self._datastore_regex) + self._volumeops = VMwareVolumeOps(self._session, + self._cluster_ref) + self._vmops = VMwareVMOps(self._session, + virtapi, + self._volumeops, + self._cluster_ref, + datastore_regex=self._datastore_regex) + self._vc_state = VCState(self._session, + self._nodename, + self._cluster_ref, + self._datastore_regex) self.capabilities['resource_scheduling'] = \ cluster_util.is_drs_enabled(self._session, self._cluster_ref) # Register the OpenStack extension From 6ad80fa75cbe055bd83dad293b22b24cc282008f Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Mon, 25 Oct 2021 13:58:01 +0200 Subject: [PATCH 4/8] Vmware: Reduce vm search scope for images When importing an image, and having a duplicate name we were going through all the VMs in the vcenter to find matching one. This can be potentially 100k ones, while it is rather likely that it is in the same location we are trying to import. We now search in the folder, and failing that in the datastore. As the name is specific for the datastore, it would should only fail, if someone uses the same naming convention and place it somewhere else. Change-Id: I9e1c55d560d36768037f4036b546b80eaa21ed32 --- nova/tests/unit/virt/vmwareapi/test_images.py | 13 +++++- nova/tests/unit/virt/vmwareapi/test_vmops.py | 4 +- nova/virt/vmwareapi/images.py | 40 +++++++++++-------- nova/virt/vmwareapi/vm_util.py | 34 +++++++--------- nova/virt/vmwareapi/vmops.py | 4 +- 5 files changed, 53 insertions(+), 42 deletions(-) diff --git a/nova/tests/unit/virt/vmwareapi/test_images.py b/nova/tests/unit/virt/vmwareapi/test_images.py index 5e2aff019f2..c2a8a68b429 100644 --- a/nova/tests/unit/virt/vmwareapi/test_images.py +++ b/nova/tests/unit/virt/vmwareapi/test_images.py @@ -20,12 +20,14 @@ import mock from oslo_utils import units +from oslo_vmware.objects import datastore as ds_obj from oslo_vmware import rw_handles from nova import exception from nova import objects from nova import test import nova.tests.unit.image.fake +from nova.tests.unit.virt.vmwareapi import fake as vmwareapi_fake from nova.tests import uuidsentinel from nova.virt.vmwareapi import constants from nova.virt.vmwareapi import images @@ -34,6 +36,13 @@ class VMwareImagesTestCase(test.NoDBTestCase): """Unit tests for Vmware API connection calls.""" + def setUp(self): + super(test.NoDBTestCase, self).setUp() + fake_ds_ref = vmwareapi_fake.ManagedObjectReference(value='fake-ds') + self._ds = ds_obj.Datastore( + ref=fake_ds_ref, name='fake_ds', + capacity=10 * units.Gi, + freespace=10 * units.Gi) def test_fetch_image(self): """Test fetching images.""" @@ -164,7 +173,7 @@ def fake_extract(name): mock_tar_open.return_value.__enter__.return_value = mock_tar images.fetch_image_ova( - context, instance, session, 'fake-vm', 'fake-datastore', + context, instance, session, 'fake-vm', self._ds, vm_folder_ref, res_pool_ref) mock_tar_open.assert_called_once_with(mode='r|', @@ -216,7 +225,7 @@ def test_fetch_image_stream_optimized(self, mock.sentinel.vm_ref images.fetch_image_stream_optimized( - context, instance, session, 'fake-vm', 'fake-datastore', + context, instance, session, 'fake-vm', self._ds, vm_folder_ref, res_pool_ref) mock_image_transfer.assert_called_once_with(mock_read_handle, diff --git a/nova/tests/unit/virt/vmwareapi/test_vmops.py b/nova/tests/unit/virt/vmwareapi/test_vmops.py index 4418496ddeb..3f8e77f3597 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vmops.py +++ b/nova/tests/unit/virt/vmwareapi/test_vmops.py @@ -2909,7 +2909,7 @@ def test_fetch_image_as_vapp(self, mock_template_vm_name, vi.instance, self._session, 'fake-name', - self._ds.name, + self._ds, vi.dc_info.vmFolder, self._vmops._root_resource_pool, image_id=self._image_id) @@ -2937,7 +2937,7 @@ def test_fetch_image_as_ova(self, mock_template_vm_name, vi.instance, self._session, 'fake-name', - self._ds.name, + self._ds, vi.dc_info.vmFolder, self._vmops._root_resource_pool) self.assertEqual(vi.ii.file_size, 123) diff --git a/nova/virt/vmwareapi/images.py b/nova/virt/vmwareapi/images.py index df13b9b7bcc..5bb23df4d33 100644 --- a/nova/virt/vmwareapi/images.py +++ b/nova/virt/vmwareapi/images.py @@ -340,7 +340,7 @@ def _build_import_spec_for_import_vapp(session, vm_name, datastore_name): def fetch_image_stream_optimized(context, instance, session, vm_name, - ds_name, vm_folder_ref, res_pool_ref, + datastore, vm_folder_ref, res_pool_ref, image_id=None): """Fetch image from Glance to ESX datastore.""" image_ref = image_id if image_id else instance.image_ref @@ -352,13 +352,14 @@ def fetch_image_stream_optimized(context, instance, session, vm_name, file_size = int(metadata['size']) vm_import_spec = _build_import_spec_for_import_vapp( - session, vm_name, ds_name) + session, vm_name, datastore.name) read_iter = IMAGE_API.download(context, image_ref) read_handle = rw_handles.ImageReadHandle(read_iter) imported_vm_ref = _import_image(session, read_handle, vm_import_spec, vm_name, vm_folder_ref, res_pool_ref, + datastore.ref, file_size) LOG.info("Downloaded image file data %(image_ref)s", @@ -369,7 +370,7 @@ def fetch_image_stream_optimized(context, instance, session, vm_name, def _import_image(session, read_handle, vm_import_spec, vm_name, vm_folder_ref, - res_pool_ref, file_size): + res_pool_ref, datastore_ref, file_size): # retry in order to handle conflicts in case of parallel execution # (multiple agents) or previously failed import of the same image max_attempts = 3 @@ -390,21 +391,26 @@ def _import_image(session, read_handle, vm_import_spec, vm_name, vm_folder_ref, except vexc.DuplicateName: LOG.debug("Handling name duplication during import of VM %s", vm_name) - vm_ref = vm_util.get_vm_ref_from_name(session, vm_name) + vm_ref = vm_util.get_vm_ref_from_name(session, vm_name, + base_obj=vm_folder_ref, path="childEntity") + if not vm_ref: + # This only happens, if the owner of the image + # has been changed, while we where importing... rather unlikely + vm_ref = vm_util.get_vm_ref_from_name(session, vm_name, + base_obj=datastore_ref, path="vm") + waited_for_ongoing_import = _wait_for_import_task(session, vm_ref) if waited_for_ongoing_import: imported_vm_ref = vm_ref break - else: - try: - destroy_task = session._call_method(session.vim, - "Destroy_Task", - vm_ref) - session._wait_for_task(destroy_task) - vm_util.vm_ref_cache_delete(vm_name) - except vexc.ManagedObjectNotFoundException: - # another agent destroyed the VM in the meantime - pass + try: + destroy_task = session._call_method(session.vim, + "Destroy_Task", + vm_ref) + session._wait_for_task(destroy_task) + except vexc.ManagedObjectNotFoundException: + # another agent destroyed the VM in the meantime + pass if not imported_vm_ref: raise vexc.VMwareDriverException("Could not import image" @@ -474,7 +480,7 @@ def get_vmdk_name_from_ovf(xmlstr): return vmdk_name -def fetch_image_ova(context, instance, session, vm_name, ds_name, +def fetch_image_ova(context, instance, session, vm_name, datastore, vm_folder_ref, res_pool_ref): """Download the OVA image from the glance image server to the Nova compute node. @@ -488,7 +494,7 @@ def fetch_image_ova(context, instance, session, vm_name, ds_name, file_size = int(metadata['size']) vm_import_spec = _build_import_spec_for_import_vapp( - session, vm_name, ds_name) + session, vm_name, datastore.name) read_iter = IMAGE_API.download(context, image_ref) read_handle = rw_handles.ImageReadHandle(read_iter) @@ -506,7 +512,7 @@ def fetch_image_ova(context, instance, session, vm_name, ds_name, imported_vm_ref = _import_image(session, extracted, vm_import_spec, vm_name, vm_folder_ref, res_pool_ref, - file_size) + datastore.ref, file_size) LOG.info("Downloaded OVA image file %(image_ref)s", {'image_ref': instance.image_ref}) diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 673ffe27e3b..cad0f544350 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -281,14 +281,6 @@ def wrapper(session, instance): return wrapper -def vm_ref_cache_from_name(func): - @six.wraps(func) - def wrapper(session, name): - id_ = name - return _vm_ref_cache(id_, func, session, name) - return wrapper - - def vm_ref_cache_heal_from_instance(func): """Decorator for a function working with a cached ManagedObject reference for an instance @@ -1336,25 +1328,29 @@ def _get_object_from_results(session, results, value, func): return func(objects, value) -def _get_vm_ref_from_name(session, vm_name): +def get_vm_ref_from_name(session, vm_name, base_obj=None, path=None): """Get reference to the VM with the name specified. This method reads all of the names of the VM's that are running on the backend, then it filters locally the matching vm_name. It is far more optimal to use _get_vm_ref_from_vm_uuid. """ - vms = session._call_method(vim_util, "get_objects", - "VirtualMachine", ["name"]) + property_list = ["name"] + if not base_obj: # Legacy: It doesn't scale + vms = session._call_method( + vim_util, "get_objects", + "VirtualMachine", property_list) + else: + if not path: + raise ValueError("Method needs base_obj and path") + vms = session._call_method( + vim_util, "get_inner_objects", base_obj, path, + "VirtualMachine", property_list) + return _get_object_from_results(session, vms, vm_name, _get_object_for_value) -@vm_ref_cache_from_name -def get_vm_ref_from_name(session, vm_name): - return (_get_vm_ref_from_vm_uuid(session, vm_name) or - _get_vm_ref_from_name(session, vm_name)) - - def _get_vm_ref_from_vm_uuid(session, instance_uuid): """Get reference to the VM. @@ -1395,7 +1391,7 @@ def get_vm_ref(session, instance): """Get reference to the VM through uuid or vm name.""" uuid = instance.uuid vm_ref = (search_vm_ref_by_identifier(session, uuid) or - _get_vm_ref_from_name(session, instance.name)) + get_vm_ref_from_name(session, instance.name)) if vm_ref is None: raise exception.InstanceNotFound(instance_id=uuid) return vm_ref @@ -1411,7 +1407,7 @@ def search_vm_ref_by_identifier(session, identifier): """ vm_ref = (_get_vm_ref_from_vm_uuid(session, identifier) or _get_vm_ref_from_extraconfig(session, identifier) or - _get_vm_ref_from_name(session, identifier)) + get_vm_ref_from_name(session, identifier)) return vm_ref diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 724ad74c1d0..9ce72c42849 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -514,7 +514,7 @@ def _fetch_image_as_vapp(self, context, vi, image_ds_loc): vi.instance, self._session, vm_name, - vi.datastore.name, + vi.datastore, self._get_project_folder(vi.dc_info, project_id=vi.ii.owner, type_='Images'), @@ -536,7 +536,7 @@ def _fetch_image_as_ova(self, context, vi, image_ds_loc): vi.instance, self._session, vm_name, - vi.datastore.name, + vi.datastore, self._get_project_folder(vi.dc_info, project_id=vi.ii.owner, type_='Images'), From f07ebdefe9a3a76635bb69d5dd7c416fec0c527f Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Tue, 2 Nov 2021 12:25:55 +0100 Subject: [PATCH 5/8] Vmware: vm_util only works with vmrefs Previously, the functions were often taking an optional vm_ref argument, and would resolve the vm_ref from the instance itself, if not. In other places, the instance was only passed for logging purposes. By only taking a vm_ref as argument and relying on the resource_id being logged, we reduce the variability in the interface. This breaks mostly vm_ref_cache_heal_from_instance functor, which is solved in a different way in a another patch. Change-Id: Ifb4b4caacbacbbc44236d942c6e08489ed41ec43 --- .../unit/virt/vmwareapi/test_configdrive.py | 10 +- .../unit/virt/vmwareapi/test_driver_api.py | 50 ++--- .../tests/unit/virt/vmwareapi/test_vm_util.py | 80 ++------ nova/tests/unit/virt/vmwareapi/test_vmops.py | 95 ++++----- .../unit/virt/vmwareapi/test_volumeops.py | 46 +++-- nova/virt/vmwareapi/driver.py | 5 +- nova/virt/vmwareapi/images.py | 4 +- nova/virt/vmwareapi/vm_util.py | 50 ++--- nova/virt/vmwareapi/vmops.py | 185 +++++++----------- nova/virt/vmwareapi/volumeops.py | 41 ++-- 10 files changed, 219 insertions(+), 347 deletions(-) diff --git a/nova/tests/unit/virt/vmwareapi/test_configdrive.py b/nova/tests/unit/virt/vmwareapi/test_configdrive.py index 6ad72801a87..4bddfeb511b 100644 --- a/nova/tests/unit/virt/vmwareapi/test_configdrive.py +++ b/nova/tests/unit/virt/vmwareapi/test_configdrive.py @@ -147,23 +147,23 @@ def _spawn_vm(self, mock_find_image_template_vm, block_device_info=block_device_info) @mock.patch.object(vmops.VMwareVMOps, '_create_config_drive', - return_value=('[ds1] fake.iso')) + return_value='fake-path/fake.iso') @mock.patch.object(vmops.VMwareVMOps, '_attach_cdrom_to_vm') def test_create_vm_with_config_drive_verify_method_invocation(self, mock_attach_cdrom, mock_create_config_drive): self.test_instance.config_drive = 'True' self._spawn_vm() - mock_create_config_drive.assert_called_once_with(mock.ANY, + mock_create_config_drive.assert_called_once_with(self.context, self.test_instance, mock.ANY, mock.ANY, mock.ANY, + 'ds1', mock.ANY, mock.ANY, - mock.ANY, - mock.ANY) + 'Fake-CookieJar') mock_attach_cdrom.assert_called_once_with(mock.ANY, mock.ANY, - mock.ANY, mock.ANY) + mock.ANY) @mock.patch.object(vmops.VMwareVMOps, '_create_config_drive', return_value=('[ds1] fake.iso')) diff --git a/nova/tests/unit/virt/vmwareapi/test_driver_api.py b/nova/tests/unit/virt/vmwareapi/test_driver_api.py index 358f41f1e29..d36e3eb651f 100644 --- a/nova/tests/unit/virt/vmwareapi/test_driver_api.py +++ b/nova/tests/unit/virt/vmwareapi/test_driver_api.py @@ -595,7 +595,7 @@ def test_iso_disk_cdrom_attach(self, self.fake_image_uuid, '%s.iso' % self.fake_image_uuid) - def fake_attach_cdrom(vm_ref, instance, data_store_ref, + def fake_attach_cdrom(vm_ref, data_store_ref, iso_uploaded_path): self.assertEqual(iso_uploaded_path, str(iso_path)) @@ -626,7 +626,7 @@ def test_iso_disk_cdrom_attach_with_config_drive(self, ds_obj.DatastorePath(self.ds, 'fake-config-drive')] self.iso_index = 0 - def fake_attach_cdrom(vm_ref, instance, data_store_ref, + def fake_attach_cdrom(vm_ref, data_store_ref, iso_uploaded_path): self.assertEqual(iso_uploaded_path, str(iso_path[self.iso_index])) self.iso_index += 1 @@ -680,7 +680,7 @@ def test_cdrom_attach_with_config_drive(self): iso_path = ds_obj.DatastorePath(self.ds, 'fake-config-drive') self.cd_attach_called = False - def fake_attach_cdrom(vm_ref, instance, data_store_ref, + def fake_attach_cdrom(vm_ref, data_store_ref, iso_uploaded_path): self.assertEqual(iso_uploaded_path, str(iso_path)) self.cd_attach_called = True @@ -860,7 +860,7 @@ def test_spawn_disk_extend(self, mock_extend, self._create_vm() info = self._get_info() self._check_vm_info(info, power_state.RUNNING) - mock_extend.assert_called_once_with(mock.ANY, requested_size, + mock_extend.assert_called_once_with(requested_size, mock.ANY, mock.ANY) @mock.patch.object(vmops.VMwareVMOps, 'update_cached_instances') @@ -869,7 +869,7 @@ def test_spawn_disk_extend_exists(self, mock_update_cached_instances): self.fake_image_uuid, '%s.80.vmdk' % self.fake_image_uuid) - def _fake_extend(instance, requested_size, name, dc_ref): + def _fake_extend(requested_size, name, dc_ref): vmwareapi_fake._add_file(str(root)) with test.nested( @@ -919,7 +919,7 @@ def test_spawn_disk_extend_sparse(self, mock_from_image, cached_image = ds_obj.DatastorePath(self.ds, 'vmware_base', iid, '%s.80.vmdk' % iid) mock_extend.assert_called_once_with( - self.instance, self.instance.flavor.root_gb * units.Mi, + self.instance.flavor.root_gb * units.Mi, str(cached_image), "fake_dc_ref") def test_spawn_disk_extend_failed_copy(self): @@ -1378,7 +1378,6 @@ def test_snapshot_delete_vm_snapshot(self, mock_attach_volume, mock_get_vmdk.return_value = self.get_fake_vmdk() self._create_vm() - fake_vm = self._get_vm_record() snapshot_ref = vmwareapi_fake.ManagedObjectReference( value="Snapshot-123", name="VirtualMachineSnapshot") @@ -1388,9 +1387,7 @@ def test_snapshot_delete_vm_snapshot(self, mock_attach_volume, self._test_snapshot() - mock_delete_vm_snapshot.assert_called_once_with(self.instance, - fake_vm.obj, - snapshot_ref) + mock_delete_vm_snapshot.assert_called_once_with(snapshot_ref) def get_fake_vmdk(self): ds_ref = vmwareapi_fake.ManagedObjectReference(value='fake-ref') @@ -1410,7 +1407,6 @@ def get_fake_vmdk(self): def _snapshot_delete_vm_snapshot_exception(self, exception, call_count=1): self._create_vm() - fake_vm = vmwareapi_fake._get_objects("VirtualMachine").objects[0].obj snapshot_ref = vmwareapi_fake.ManagedObjectReference( value="Snapshot-123", name="VirtualMachineSnapshot") @@ -1423,11 +1419,10 @@ def _snapshot_delete_vm_snapshot_exception(self, exception, call_count=1): if exception != vexc.TaskInProgress: self.assertRaises(exception, self.conn._vmops._delete_vm_snapshot, - self.instance, fake_vm, snapshot_ref) + snapshot_ref) self.assertEqual(0, _fake_sleep.call_count) else: - self.conn._vmops._delete_vm_snapshot(self.instance, fake_vm, - snapshot_ref) + self.conn._vmops._delete_vm_snapshot(snapshot_ref) self.assertEqual(call_count - 1, _fake_sleep.call_count) self.assertEqual(call_count, _fake_wait.call_count) @@ -1602,13 +1597,18 @@ def test_power_off_non_existent(self): @mock.patch.object(driver.VMwareVCDriver, 'reboot') @mock.patch.object(vm_util, 'get_vm_state', return_value=power_state.SHUTDOWN) - def test_resume_state_on_host_boot(self, mock_get_vm_state, + @mock.patch.object(vm_util, 'get_vm_ref', + return_value=mock.sentinel.vm_ref) + def test_resume_state_on_host_boot(self, mock_get_vm_ref, + mock_get_vm_state, mock_reboot): self._create_instance() self.conn.resume_state_on_host_boot(self.context, self.instance, 'network_info') - mock_get_vm_state.assert_called_once_with(self.conn._session, + mock_get_vm_ref.assert_called_once_with(self.conn._session, self.instance) + mock_get_vm_state.assert_called_once_with(self.conn._session, + mock.sentinel.vm_ref) mock_reboot.assert_called_once_with(self.context, self.instance, 'network_info', 'hard', None) @@ -1616,15 +1616,19 @@ def test_resume_state_on_host_boot_no_reboot(self): self._create_instance() for state in [power_state.RUNNING, power_state.SUSPENDED]: with test.nested( + mock.patch.object(vm_util, 'get_vm_ref', + return_value=mock.sentinel.vm_ref), mock.patch.object(driver.VMwareVCDriver, 'reboot'), mock.patch.object(vm_util, 'get_vm_state', return_value=state) - ) as (mock_reboot, mock_get_vm_state): + ) as (mock_get_vm_ref, mock_reboot, mock_get_vm_state): self.conn.resume_state_on_host_boot(self.context, self.instance, 'network_info') + mock_get_vm_ref.assert_called_once_with(self.conn._session, + self.instance) mock_get_vm_state.assert_called_once_with(self.conn._session, - self.instance) + mock.sentinel.vm_ref) self.assertFalse(mock_reboot.called) @mock.patch('nova.virt.driver.block_device_info_get_mapping') @@ -1775,9 +1779,9 @@ def fake_create_config_drive(instance, injected_files, password, self._create_vm() - def fake_power_on_instance(session, instance, vm_ref=None): + def fake_power_on_instance(session, vm_ref): self._power_on_called += 1 - return self._power_on(session, instance, vm_ref=vm_ref) + return self._power_on(session, vm_ref) info = self._get_info() self._check_vm_info(info, power_state.RUNNING) @@ -1964,7 +1968,7 @@ def test_attach_vmdk_disk_to_vm(self): connection_info['data']['volume']) self.assertTrue(get_vmdk_info.called) attach_disk_to_vm.assert_called_once_with(mock.sentinel.vm_ref, - self.instance, adapter_type, disk_type, vmdk_path='fake-path', + adapter_type, disk_type, vmdk_path='fake-path', volume_uuid=connection_info['data']['volume_id'], backing_uuid=disk_uuid) @@ -2033,7 +2037,7 @@ def test_attach_iscsi_disk_to_vm(self): self.conn.attach_volume(None, connection_info, self.instance, mount_point) - mock_attach_disk.assert_called_once_with(mock.ANY, self.instance, + mock_attach_disk.assert_called_once_with(mock.ANY, mock.ANY, 'rdmp', device_name=mock.ANY) mock_iscsi_get_target.assert_called_once_with( connection_info['data']) @@ -2093,7 +2097,7 @@ def test_detach_iscsi_disk_from_vm(self, mock_iscsi_get_target, mock_iscsi_get_target.assert_called_once_with(connection_info['data']) mock_get_rdm_disk.assert_called_once() mock_detach_disk_from_vm.assert_called_once_with(mock.ANY, - self.instance, device, destroy_disk=True) + device, destroy_disk=True) def test_connection_info_get(self): self._create_vm() diff --git a/nova/tests/unit/virt/vmwareapi/test_vm_util.py b/nova/tests/unit/virt/vmwareapi/test_vm_util.py index 25dfa98076a..ffa9f7b0f5d 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vm_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_vm_util.py @@ -1201,7 +1201,6 @@ def fake_wait_for_task(self, *args): ) as (wait_for_task, call_method): vm_ref = vm_util.create_vm( session, - self._instance, 'fake_vm_folder', 'fake_config_spec', 'fake_res_pool_ref') @@ -1236,7 +1235,7 @@ def fake_log_warn(msg, values): os_type='invalid_os_type') self.assertRaises(vexc.VMwareDriverException, - vm_util.create_vm, session, self._instance, + vm_util.create_vm, session, 'folder', config_spec, 'res-pool') self.assertTrue(found[0]) @@ -1263,24 +1262,7 @@ def test_power_on_instance_with_vm_ref(self): return_value='fake-task'), mock.patch.object(session, "_wait_for_task"), ) as (fake_call_method, fake_wait_for_task): - vm_util.power_on_instance(session, self._instance, - vm_ref='fake-vm-ref') - fake_call_method.assert_called_once_with(session.vim, - "PowerOnVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - - def test_power_on_instance_without_vm_ref(self): - session = fake.FakeSession() - with test.nested( - mock.patch.object(vm_util, "get_vm_ref", - return_value='fake-vm-ref'), - mock.patch.object(session, "_call_method", - return_value='fake-task'), - mock.patch.object(session, "_wait_for_task"), - ) as (fake_get_vm_ref, fake_call_method, fake_wait_for_task): - vm_util.power_on_instance(session, self._instance) - fake_get_vm_ref.assert_called_once_with(session, self._instance) + vm_util.power_on_instance(session, 'fake-vm-ref') fake_call_method.assert_called_once_with(session.vim, "PowerOnVM_Task", 'fake-vm-ref') @@ -1296,8 +1278,7 @@ def test_power_on_instance_with_exception(self): ) as (fake_call_method, fake_wait_for_task): self.assertRaises(exception.NovaException, vm_util.power_on_instance, - session, self._instance, - vm_ref='fake-vm-ref') + session, 'fake-vm-ref') fake_call_method.assert_called_once_with(session.vim, "PowerOnVM_Task", 'fake-vm-ref') @@ -1312,8 +1293,7 @@ def test_power_on_instance_with_power_state_exception(self): session, "_wait_for_task", side_effect=vexc.InvalidPowerStateException), ) as (fake_call_method, fake_wait_for_task): - vm_util.power_on_instance(session, self._instance, - vm_ref='fake-vm-ref') + vm_util.power_on_instance(session, 'fake-vm-ref') fake_call_method.assert_called_once_with(session.vim, "PowerOnVM_Task", 'fake-vm-ref') @@ -1667,38 +1647,20 @@ def test_get_network_detach_config_spec(self): self.assertEqual(expected, result) - @mock.patch.object(vm_util, "get_vm_ref") - def test_power_off_instance(self, fake_get_ref): - session = fake.FakeSession() - with test.nested( - mock.patch.object(session, '_call_method', - return_value='fake-task'), - mock.patch.object(session, '_wait_for_task') - ) as (fake_call_method, fake_wait_for_task): - vm_util.power_off_instance(session, self._instance, 'fake-vm-ref') - fake_call_method.assert_called_once_with(session.vim, - "PowerOffVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - self.assertFalse(fake_get_ref.called) - - @mock.patch.object(vm_util, "get_vm_ref", return_value="fake-vm-ref") - def test_power_off_instance_no_vm_ref(self, fake_get_ref): + def test_power_off_instance(self): session = fake.FakeSession() with test.nested( mock.patch.object(session, '_call_method', return_value='fake-task'), mock.patch.object(session, '_wait_for_task') ) as (fake_call_method, fake_wait_for_task): - vm_util.power_off_instance(session, self._instance) - fake_get_ref.assert_called_once_with(session, self._instance) + vm_util.power_off_instance(session, 'fake-vm-ref') fake_call_method.assert_called_once_with(session.vim, "PowerOffVM_Task", 'fake-vm-ref') fake_wait_for_task.assert_called_once_with('fake-task') - @mock.patch.object(vm_util, "get_vm_ref") - def test_power_off_instance_with_exception(self, fake_get_ref): + def test_power_off_instance_with_exception(self): session = fake.FakeSession() with test.nested( mock.patch.object(session, '_call_method', @@ -1708,15 +1670,13 @@ def test_power_off_instance_with_exception(self, fake_get_ref): ) as (fake_call_method, fake_wait_for_task): self.assertRaises(exception.NovaException, vm_util.power_off_instance, - session, self._instance, 'fake-vm-ref') + session, 'fake-vm-ref') fake_call_method.assert_called_once_with(session.vim, "PowerOffVM_Task", 'fake-vm-ref') fake_wait_for_task.assert_called_once_with('fake-task') - self.assertFalse(fake_get_ref.called) - @mock.patch.object(vm_util, "get_vm_ref") - def test_power_off_instance_power_state_exception(self, fake_get_ref): + def test_power_off_instance_power_state_exception(self): session = fake.FakeSession() with test.nested( mock.patch.object(session, '_call_method', @@ -1725,12 +1685,11 @@ def test_power_off_instance_power_state_exception(self, fake_get_ref): session, '_wait_for_task', side_effect=vexc.InvalidPowerStateException) ) as (fake_call_method, fake_wait_for_task): - vm_util.power_off_instance(session, self._instance, 'fake-vm-ref') + vm_util.power_off_instance(session, 'fake-vm-ref') fake_call_method.assert_called_once_with(session.vim, "PowerOffVM_Task", 'fake-vm-ref') fake_wait_for_task.assert_called_once_with('fake-task') - self.assertFalse(fake_get_ref.called) def test_get_vm_create_spec_updated_hw_version(self): extra_specs = vm_util.ExtraSpecs(hw_version='vmx-08') @@ -2112,22 +2071,11 @@ def setUp(self): self.host_ref = list(fake._db_content['HostSystem'].keys())[0] self.vm_ref = fake.create_vm(host_ref=self.host_ref) - @mock.patch.object(vm_util, 'get_vm_ref') - def test_get_host_ref_for_vm(self, mock_get_vm_ref): - mock_get_vm_ref.return_value = self.vm_ref - - ret = vm_util.get_host_ref_for_vm(self.session, 'fake-instance') - - mock_get_vm_ref.assert_called_once_with(self.session, 'fake-instance') + def test_get_host_ref_for_vm(self): + ret = vm_util.get_host_ref_for_vm(self.session, self.vm_ref) self.assertEqual(self.host_ref, ret) - @mock.patch.object(vm_util, 'get_vm_ref') - def test_get_host_name_for_vm(self, mock_get_vm_ref): - mock_get_vm_ref.return_value = self.vm_ref - + def test_get_host_name_for_vm(self): host = fake._get_object(self.host_ref) - - ret = vm_util.get_host_name_for_vm(self.session, 'fake-instance') - - mock_get_vm_ref.assert_called_once_with(self.session, 'fake-instance') + ret = vm_util.get_host_name_for_vm(self.session, self.vm_ref) self.assertEqual(host.name, ret) diff --git a/nova/tests/unit/virt/vmwareapi/test_vmops.py b/nova/tests/unit/virt/vmwareapi/test_vmops.py index 3f8e77f3597..33ab80ba6b0 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vmops.py +++ b/nova/tests/unit/virt/vmwareapi/test_vmops.py @@ -271,8 +271,7 @@ def fake_call_method(module, method, *args, **kwargs): mock.patch.object(self._session, '_wait_for_task'), mock.patch.object(self._session, '_call_method', fake_call_method) ) as (_wait_for_task, _call_method): - self._vmops._delete_vm_snapshot(self._instance, - "fake_vm_ref", "fake_vm_snapshot") + self._vmops._delete_vm_snapshot("fake_vm_snapshot") _wait_for_task.assert_has_calls([ mock.call('fake_remove_snapshot_task')]) @@ -306,8 +305,7 @@ def fake_call_method(module, method, *args, **kwargs): def test_update_instance_progress(self): with mock.patch.object(self._instance, 'save') as mock_save: - self._vmops._update_instance_progress(self._instance._context, - self._instance, 5, 10) + self._vmops._update_instance_progress(self._instance, 5, 10) mock_save.assert_called_once_with() self.assertEqual(50, self._instance.progress) @@ -462,7 +460,6 @@ def test_rescue(self, self._vmops.rescue( self._context, self._instance, None, self._image_meta) mock_power_off.assert_called_once_with(self._session, - self._instance, vm_ref) uuid = self._instance.image_ref @@ -473,15 +470,14 @@ def test_rescue(self, mock_disk_copy.assert_called_once_with(self._session, dc_info.ref, cache_path, rescue_path) _volumeops.attach_disk_to_vm.assert_called_once_with(vm_ref, - self._instance, mock.ANY, mock.ANY, rescue_path) + mock.ANY, mock.ANY, rescue_path) mock_get_boot_spec.assert_called_once_with(mock.ANY, 'fake-rescue-device') mock_reconfigure.assert_called_once_with(self._session, vm_ref, 'fake-boot-spec') mock_power_on.assert_called_once_with(self._session, - self._instance, - vm_ref=vm_ref) + vm_ref) def test_unrescue_power_on(self): self._test_unrescue(True) @@ -512,15 +508,14 @@ def fake_call_method(module, method, *args, **kwargs): if power_on: _power_on_instance.assert_called_once_with(self._session, - self._instance, vm_ref=vm_ref) + vm_ref) else: self.assertFalse(_power_on_instance.called) _get_vm_ref.assert_called_once_with(self._session, self._instance) - _power_off.assert_called_once_with(self._session, self._instance, - vm_ref) + _power_off.assert_called_once_with(self._session, vm_ref) _volumeops.detach_disk_from_vm.assert_called_once_with( - vm_ref, self._instance, mock.ANY, destroy_disk=True) + vm_ref, mock.ANY, destroy_disk=True) @mock.patch.object(time, 'sleep') @mock.patch.object(vmops.VMwareVMOps, 'update_cached_instances') @@ -699,8 +694,7 @@ def _test_finish_migration(self, power_on=True, 'fake-ref') if power_on: fake_power_on.assert_called_once_with(self._session, - self._instance, - vm_ref='fake-ref') + 'fake-ref') else: self.assertFalse(fake_power_on.called) @@ -716,7 +710,7 @@ def _test_finish_migration(self, power_on=True, vmdk, self._instance.flavor) - calls = [mock.call(self._context, self._instance, step=i, + calls = [mock.call(self._instance, step=i, total_steps=vmops.RESIZE_TOTAL_STEPS) for i in range(2, 7)] fake_update_instance_progress.assert_has_calls(calls) @@ -874,7 +868,6 @@ def _test_finish_revert_migration(self, fake_list_instances, vm_ref_calls = [mock.call(self._session, self._instance)] fake_power_off.assert_called_once_with(self._session, - self._instance, 'fake-ref') # Validate VM reconfiguration metadata = ('name:fake_display_name\n' @@ -909,7 +902,6 @@ def _test_finish_revert_migration(self, fake_list_instances, 'original.vmdk') mock_detach_disk.assert_called_once_with('fake-ref', - self._instance, device) fake_disk_delete.assert_called_once_with( self._session, dc_info.ref, '[fake] uuid/root.vmdk') @@ -918,7 +910,7 @@ def _test_finish_revert_migration(self, fake_list_instances, '[fake] uuid/original.vmdk', '[fake] uuid/root.vmdk') mock_attach_disk.assert_called_once_with( - 'fake-ref', self._instance, vmdk.adapter_type, 'fake-disk', + 'fake-ref', vmdk.adapter_type, 'fake-disk', '[fake] uuid/root.vmdk') fake_remove_ephemerals_and_swap.assert_called_once_with('fake-ref') fake_resize_create_ephemerals_and_swap.assert_called_once_with( @@ -940,7 +932,7 @@ def _test_finish_revert_migration(self, fake_list_instances, fake_get_vm_ref.assert_has_calls(vm_ref_calls) if power_on and not relocate_fails: fake_power_on.assert_called_once_with(self._session, - self._instance) + 'fake-ref') else: self.assertFalse(fake_power_on.called) @@ -1134,10 +1126,9 @@ def test_resize_disk(self, fake_disk_copy, fake_disk_move, self._session, dc_info.ref, '[fake] uuid/root.vmdk', '[fake] uuid/resized.vmdk') mock_detach_disk.assert_called_once_with('fake-ref', - instance, device) fake_extend.assert_called_once_with( - instance, flavor['root_gb'] * units.Mi, + flavor['root_gb'] * units.Mi, '[fake] uuid/resized.vmdk', dc_info.ref) calls = [ mock.call(self._session, dc_info.ref, @@ -1149,7 +1140,7 @@ def test_resize_disk(self, fake_disk_copy, fake_disk_move, fake_disk_move.assert_has_calls(calls) mock_attach_disk.assert_called_once_with( - 'fake-ref', instance, 'fake-adapter', 'fake-disk', + 'fake-ref', 'fake-adapter', 'fake-disk', '[fake] uuid/root.vmdk') @mock.patch.object(vm_util, 'detach_devices_from_vm') @@ -1247,9 +1238,8 @@ def _test_migrate_disk_and_power_off(self, fake_get_vm_ref, fake_progress, self._instance) fake_power_off.assert_called_once_with(self._session, - self._instance, 'fake-ref') - calls = [mock.call(self._context, self._instance, step=i, + calls = [mock.call(self._instance, step=i, total_steps=vmops.RESIZE_TOTAL_STEPS) for i in range(2)] fake_progress.assert_has_calls(calls) @@ -1330,15 +1320,14 @@ def test_finish_migration_root_block_device(self, fake_get_vm_ref, fake_resize_create_eph_swap.assert_called_once_with( 'fake-ref', self._instance, None) fake_remove_eph_and_swap.assert_called_once_with('fake-ref') - fake_power_on.assert_called_once_with(self._session, self._instance, - vm_ref='fake-ref') + fake_power_on.assert_called_once_with(self._session, 'fake-ref') fake_resize_vm.assert_called_once_with(self._context, self._instance, 'fake-ref', self._instance.flavor, self._image_meta) fake_get_vmdk_info.assert_not_called() fake_resize_disk.assert_not_called() - calls = [mock.call(self._context, self._instance, step=i, + calls = [mock.call(self._instance, step=i, total_steps=vmops.RESIZE_TOTAL_STEPS) for i in range(2, 7)] fake_progress.assert_has_calls(calls) @@ -1445,7 +1434,6 @@ def test_manage_image_cache_templates(self, mock_get_avlbl_ds, mock.patch.object(self._session, '_wait_for_task')): self._vmops.manage_image_cache(self._context, fake_instances) mock_destroy_vm.assert_called_once_with(self._session, - None, expired_templ_vm_ref) @mock.patch.object(vutil, 'WithRetrieval') @@ -1519,7 +1507,7 @@ def test_configure_config_drive(self, network_info, self._ds.name, 'fake_path', self._instance.uuid, "Fake-CookieJar") mock_attach_cdrom_to_vm.assert_called_once_with( - vm_ref, self._instance, self._ds.ref, str(upload_iso_path)) + vm_ref, self._ds.ref, str(upload_iso_path)) @mock.patch('nova.image.api.API.get') @mock.patch.object(vmops.LOG, 'debug') @@ -1667,7 +1655,7 @@ def test_spawn_non_root_block_device(self, from_image, get_vm_config_info.assert_called_once_with(self._instance, image_info, extra_specs) build_virtual_machine.assert_called_once_with( - self._instance, self._context, image_info, vi.datastore, [], + self._instance, image_info, vi.datastore, [], extra_specs, self._get_metadata(), 'fake_vm_folder') enlist_image.assert_called_once_with(image_info.image_id, vi.datastore, vi.dc_info.ref) @@ -1733,7 +1721,7 @@ def test_spawn_with_no_image_and_block_devices(self, from_image, get_vm_config_info.assert_called_once_with(self._instance, image_info, extra_specs) build_virtual_machine.assert_called_once_with( - self._instance, self._context, image_info, vi.datastore, [], + self._instance, image_info, vi.datastore, [], extra_specs, self._get_metadata(is_image_used=False), 'fake_vm_folder') volumeops.attach_root_volume.assert_called_once_with( @@ -1790,7 +1778,7 @@ def test_spawn_unsupported_hardware(self, from_image, get_vm_config_info.assert_called_once_with( self._instance, image_info, extra_specs) build_virtual_machine.assert_called_once_with( - self._instance, self._context, image_info, vi.datastore, [], + self._instance, image_info, vi.datastore, [], extra_specs, self._get_metadata(is_image_used=False), 'fake_vm_folder') @@ -1847,11 +1835,11 @@ def _test_use_disk_image_as_linked_clone(self, str(sized_cached_image_ds_loc)) mock_extend_if_required.assert_called_once_with( self._dc_info, - vi.ii, - vi.instance, str(sized_cached_image_ds_loc)) + vi.instance, + str(sized_cached_image_ds_loc)) mock_attach_disk_to_vm.assert_called_once_with( - "fake_vm_ref", self._instance, vi.ii.adapter_type, + "fake_vm_ref", vi.ii.adapter_type, vi.ii.disk_type, str(sized_cached_image_ds_loc), vi.root_gb * units.Mi, False, @@ -1899,11 +1887,11 @@ def _test_use_disk_image_as_full_clone(self, mock_extend_if_required.assert_called_once_with( self._dc_info, - vi.ii, - vi.instance, fake_path) + vi.instance, + fake_path) mock_attach_disk_to_vm.assert_called_once_with( - "fake_vm_ref", self._instance, vi.ii.adapter_type, + "fake_vm_ref", vi.ii.adapter_type, vi.ii.disk_type, fake_path, vi.root_gb * units.Mi, False, disk_io_limits=vi._extra_specs.disk_io_limits) @@ -1939,7 +1927,7 @@ def _test_use_iso_image(self, self._vmops._use_iso_image("fake_vm_ref", vi) mock_attach_cdrom.assert_called_once_with( - "fake_vm_ref", self._instance, self._ds.ref, + "fake_vm_ref", self._ds.ref, str(vi.cache_image_path)) fake_path = '[fake_ds] %(uuid)s/%(uuid)s.vmdk' % {'uuid': self._uuid} @@ -1951,7 +1939,7 @@ def _test_use_iso_image(self, vi.root_gb * units.Mi) linked_clone = False mock_attach_disk_to_vm.assert_called_once_with( - "fake_vm_ref", self._instance, + "fake_vm_ref", vi.ii.adapter_type, vi.ii.disk_type, fake_path, vi.root_gb * units.Mi, linked_clone, @@ -2109,7 +2097,6 @@ def _test_spawn(self, metadata='fake-metadata') mock_create_vm.assert_called_once_with( self._session, - self._instance, 'fake_vm_folder', 'fake_create_spec', self._cluster.resourcePool) @@ -2123,7 +2110,7 @@ def _test_spawn(self, network_info, vm_ref='fake_vm_ref') mock_power_on_instance.assert_called_once_with( - self._session, self._instance, vm_ref='fake_vm_ref') + self._session, 'fake_vm_ref') if (block_device_info and 'block_device_mapping' in block_device_info): @@ -2341,7 +2328,6 @@ def test_spawn_with_ephemerals_and_swap(self, from_image, get_vm_config_info.assert_called_once_with(self._instance, image_info, extra_specs) build_virtual_machine.assert_called_once_with(self._instance, - self._context, image_info, vi.datastore, [], extra_specs, metadata, 'fake-folder') enlist_image.assert_called_once_with(image_info.image_id, vi.datastore, vi.dc_info.ref) @@ -2360,20 +2346,19 @@ def test_spawn_with_ephemerals_and_swap(self, from_image, self._uuid, 'swap.vmdk')) create_and_attach_thin_disk.assert_has_calls([ - mock.call(self._instance, 'fake-vm-ref', vi.dc_info, + mock.call('fake-vm-ref', vi.dc_info, ephemerals[0]['size'] * units.Mi, vi.ii.adapter_type, eph0_path), - mock.call(self._instance, 'fake-vm-ref', vi.dc_info, + mock.call('fake-vm-ref', vi.dc_info, ephemerals[1]['size'] * units.Mi, vi.ii.adapter_type, eph1_path), - mock.call(self._instance, 'fake-vm-ref', vi.dc_info, + mock.call('fake-vm-ref', vi.dc_info, swap['swap_size'] * units.Ki, vi.ii.adapter_type, swap_path) ]) power_on_instance.assert_called_once_with(self._session, - self._instance, - vm_ref='fake-vm-ref') + 'fake-vm-ref') def _get_fake_vi(self): image_info = images.VMwareImage( @@ -2393,8 +2378,7 @@ def test_create_and_attach_thin_disk(self, mock_create): path = str(ds_obj.DatastorePath(vi.datastore.name, self._uuid, 'fake-filename')) - self._vmops._create_and_attach_thin_disk(self._instance, - 'fake-vm-ref', + self._vmops._create_and_attach_thin_disk('fake-vm-ref', vi.dc_info, 1, 'fake-adapter-type', path) @@ -2402,7 +2386,7 @@ def test_create_and_attach_thin_disk(self, mock_create): self._session, self._dc_info.ref, 'fake-adapter-type', 'thin', path, 1) mock_attach_disk_to_vm.assert_called_once_with( - 'fake-vm-ref', self._instance, 'fake-adapter-type', + 'fake-vm-ref', 'fake-adapter-type', 'thin', path, 1, False) def test_create_ephemeral_with_bdi(self): @@ -2421,7 +2405,7 @@ def test_create_ephemeral_with_bdi(self): self._uuid, vi.ii.adapter_type) mock_caa.assert_called_once_with( - self._instance, 'fake-vm-ref', + 'fake-vm-ref', vi.dc_info, 1 * units.Mi, 'virtio', '[fake_ds] %s/ephemeral_0.vmdk' % self._uuid) @@ -2436,7 +2420,7 @@ def _test_create_ephemeral_from_instance(self, bdi): self._uuid, vi.ii.adapter_type) mock_caa.assert_called_once_with( - self._instance, 'fake-vm-ref', + 'fake-vm-ref', vi.dc_info, 1 * units.Mi, constants.DEFAULT_ADAPTER_TYPE, '[fake_ds] %s/ephemeral_0.vmdk' % self._uuid) @@ -2466,8 +2450,8 @@ def _test_create_swap_from_instance(self, bdi): size = swap.get('swap_size', 0) * units.Ki path = str(ds_obj.DatastorePath(vi.datastore.name, self._uuid, 'swap.vmdk')) - create_and_attach.assert_called_once_with(self._instance, - 'fake-vm-ref', vi.dc_info, size, 'lsiLogic', path) + create_and_attach.assert_called_once_with('fake-vm-ref', + vi.dc_info, size, 'lsiLogic', path) def test_create_swap_with_bdi(self): block_device_info = {'swap': {'disk_bus': None, @@ -2489,7 +2473,6 @@ def test_build_virtual_machine(self, mock_create_folder, extra_specs = vm_util.ExtraSpecs() vm_ref = self._vmops.build_virtual_machine(self._instance, - self._context, image, self._ds, self.network_info, diff --git a/nova/tests/unit/virt/vmwareapi/test_volumeops.py b/nova/tests/unit/virt/vmwareapi/test_volumeops.py index bdaa6beaaa8..e2b4180c64c 100644 --- a/nova/tests/unit/virt/vmwareapi/test_volumeops.py +++ b/nova/tests/unit/virt/vmwareapi/test_volumeops.py @@ -81,8 +81,8 @@ def fake_call_method(module, method, *args, **kwargs): fake_device.backing.fileName = 'fake_path' fake_device.key = 'fake_key' fake_vm_ref = vmwareapi_fake.ManagedObjectReference() - self._volumeops.detach_disk_from_vm(fake_vm_ref, self._instance, - fake_device, destroy_disk) + self._volumeops.detach_disk_from_vm(fake_vm_ref, fake_device, + destroy_disk) _wait_for_task.assert_has_calls([ mock.call('fake_configure_task')]) @@ -129,7 +129,8 @@ def test_attach_volume_vmdk_invalid(self): constants.DISK_TYPE_PREALLOCATED, 1024, 'fake-device') with test.nested( - mock.patch.object(vm_util, 'get_vm_ref'), + mock.patch.object(vm_util, 'get_vm_ref', + return_value=mock.sentinel.vm_ref), mock.patch.object(self._volumeops, '_get_volume_ref'), mock.patch.object(vm_util, 'get_vmdk_info', return_value=vmdk_info), @@ -147,7 +148,7 @@ def test_attach_volume_vmdk_invalid(self): connection_info['data']['volume']) self.assertTrue(get_vmdk_info.called) get_vm_state.assert_called_once_with(self._volumeops._session, - instance) + mock.sentinel.vm_ref) @mock.patch.object(vm_util, 'create_extra_config', return_value=mock.sentinel.extra_config) @@ -271,11 +272,11 @@ def test_detach_volume_vmdk(self): adapter_type = vm_util.CONTROLLER_TO_ADAPTER_TYPE.get( virtual_controller.__class__.__name__) consolidate_vmdk_volume.assert_called_once_with( - instance, mock.sentinel.vm_ref, virtual_disk, + mock.sentinel.vm_ref, virtual_disk, mock.sentinel.volume_ref, adapter_type=adapter_type, disk_type='fake-disk-type') detach_disk_from_vm.assert_called_once_with( - mock.sentinel.vm_ref, instance, virtual_disk, + mock.sentinel.vm_ref, virtual_disk, volume_uuid=connection_info['data']['volume_id']) def test_detach_volume_vmdk_invalid(self): @@ -317,7 +318,7 @@ def test_detach_volume_vmdk_invalid(self): get_vmdk_backed_disk_device.assert_called_once_with( mock.sentinel.vm_ref, connection_info['data']) get_vm_state.assert_called_once_with(self._volumeops._session, - instance) + mock.sentinel.vm_ref) @mock.patch.object(vm_util, 'get_vm_ref') @mock.patch.object(vm_util, 'get_rdm_disk') @@ -350,7 +351,7 @@ def test_detach_volume_iscsi(self, detach_disk_from_vm, iscsi_get_target, vutil, "get_object_property", vm_ref, "config.hardware.device") get_rdm_disk.assert_called_once_with(hardware_devices, disk_uuid) detach_disk_from_vm.assert_called_once_with( - vm_ref, instance, device, destroy_disk=True) + vm_ref, device, destroy_disk=True) @mock.patch.object(vm_util, 'get_vm_ref') @mock.patch.object(volumeops.VMwareVolumeOps, '_iscsi_get_target') @@ -444,13 +445,13 @@ def _test_attach_volume_vmdk(self, adapter_type=None): connection_info['data']['volume']) self.assertTrue(get_vmdk_info.called) attach_disk_to_vm.assert_called_once_with( - vm_ref, self._instance, adapter_type, + vm_ref, adapter_type, constants.DISK_TYPE_PREALLOCATED, vmdk_path='fake-path', volume_uuid=connection_info['data']['volume_id'], backing_uuid=disk_uuid) if adapter_type == constants.ADAPTER_TYPE_IDE: get_vm_state.assert_called_once_with(self._volumeops._session, - self._instance) + vm_ref) else: self.assertFalse(get_vm_state.called) @@ -483,7 +484,7 @@ def _test_attach_volume_iscsi(self, adapter_type=None): if adapter_type is None: self.assertTrue(get_scsi_adapter_type.called) attach_disk_to_vm.assert_called_once_with(vm_ref, - self._instance, adapter_type, 'rdmp', + adapter_type, 'rdmp', device_name=mock.sentinel.device_name) def test_attach_volume_vmdk(self): @@ -516,7 +517,7 @@ def test_consolidate_vmdk_volume_with_no_relocate( volume_ref = mock.sentinel.volume_ref vm_ref = mock.sentinel.vm_ref - self._volumeops._consolidate_vmdk_volume(self._instance, vm_ref, + self._volumeops._consolidate_vmdk_volume(vm_ref, device, volume_ref) get_vmdk_base_volume_device.assert_called_once_with(volume_ref) @@ -549,13 +550,12 @@ def test_consolidate_vmdk_volume_with_relocate( detach_disk_from_vm.side_effect = [ oslo_vmw_exceptions.FileNotFoundException] - instance = self._instance volume_ref = vmwareapi_fake.ManagedObjectReference() vm_ref = vmwareapi_fake.ManagedObjectReference() adapter_type = constants.ADAPTER_TYPE_BUSLOGIC disk_type = constants.DISK_TYPE_EAGER_ZEROED_THICK - self._volumeops._consolidate_vmdk_volume(instance, vm_ref, device, + self._volumeops._consolidate_vmdk_volume(vm_ref, device, volume_ref, adapter_type, disk_type) @@ -563,9 +563,9 @@ def test_consolidate_vmdk_volume_with_relocate( relocate_vm.assert_called_once_with(self._session, volume_ref, rp, datastore, host) detach_disk_from_vm.assert_called_once_with( - volume_ref, instance, original_device, destroy_disk=True) + volume_ref, original_device, destroy_disk=True) attach_disk_to_vm.assert_called_once_with( - volume_ref, instance, adapter_type, disk_type, + volume_ref, adapter_type, disk_type, vmdk_path=new_file_name) @mock.patch.object(volumeops.VMwareVolumeOps, @@ -596,13 +596,12 @@ def test_consolidate_vmdk_volume_with_missing_vmdk( relocate_vm.side_effect = [ oslo_vmw_exceptions.FileNotFoundException, None] - instance = mock.sentinel.instance volume_ref = vmwareapi_fake.ManagedObjectReference() vm_ref = vmwareapi_fake.ManagedObjectReference() adapter_type = constants.ADAPTER_TYPE_BUSLOGIC disk_type = constants.DISK_TYPE_EAGER_ZEROED_THICK - self._volumeops._consolidate_vmdk_volume(instance, vm_ref, device, + self._volumeops._consolidate_vmdk_volume(vm_ref, device, volume_ref, adapter_type, disk_type) @@ -614,9 +613,9 @@ def test_consolidate_vmdk_volume_with_missing_vmdk( host)] self.assertEqual(relocate_calls, relocate_vm.call_args_list) detach_disk_from_vm.assert_called_once_with( - volume_ref, instance, original_device) + volume_ref, original_device) attach_disk_to_vm.assert_called_once_with( - volume_ref, instance, adapter_type, disk_type, + volume_ref, adapter_type, disk_type, vmdk_path=new_file_name) def test_iscsi_get_host_iqn(self): @@ -658,10 +657,9 @@ def test_iscsi_get_host_iqn_instance_not_found(self): ) as (fake_get_host_ref_for_vm, fake_get_host_ref, fake_call_method): - result = self._volumeops._iscsi_get_host_iqn(self._instance) + result = self._volumeops._iscsi_get_host_iqn(None) - fake_get_host_ref_for_vm.assert_called_once_with( - self._volumeops._session, self._instance) + fake_get_host_ref_for_vm.assert_not_called() fake_get_host_ref.assert_called_once_with( self._volumeops._session, self._volumeops._cluster) fake_call_method.assert_called_once_with(vutil, @@ -687,7 +685,7 @@ def test_get_volume_connector(self): fake_get_vm_ref.assert_called_once_with(self._volumeops._session, self._instance) - fake_iscsi_get_host_iqn.assert_called_once_with(self._instance) + fake_iscsi_get_host_iqn.assert_called_once_with(vm_ref) self.assertEqual(host_ip, connector['ip']) self.assertEqual(host_ip, connector['host']) diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 48587a1e952..40aa53ce94e 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -241,7 +241,8 @@ def resume_state_on_host_boot(self, context, instance, network_info, """resume guest state when a host is booted.""" # Check if the instance is running already and avoid doing # anything if it is. - state = vm_util.get_vm_state(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, instance) + state = vm_util.get_vm_state(self._session, vm_ref) ignored_states = [power_state.RUNNING, power_state.SUSPENDED] if state in ignored_states: return @@ -1016,7 +1017,7 @@ def rollback_live_migration_at_destination(self, context, instance, LOG.info("rollback_live_migration_at_destination %s", block_device_info) if not migrate_data.is_same_vcenter: - self._volumeops.delete_shadow_vms(block_device_info, instance) + self._volumeops.delete_shadow_vms(block_device_info) @contextlib.contextmanager def _error_out_instance_on_exception(self, instance, message): diff --git a/nova/virt/vmwareapi/images.py b/nova/virt/vmwareapi/images.py index 5bb23df4d33..06b06161dd6 100644 --- a/nova/virt/vmwareapi/images.py +++ b/nova/virt/vmwareapi/images.py @@ -365,7 +365,7 @@ def fetch_image_stream_optimized(context, instance, session, vm_name, LOG.info("Downloaded image file data %(image_ref)s", {'image_ref': instance.image_ref}) vmdk = vm_util.get_vmdk_info(session, imported_vm_ref, vm_name) - vm_util.mark_vm_as_template(session, instance, imported_vm_ref) + vm_util.mark_vm_as_template(session, imported_vm_ref) return vmdk.capacity_in_bytes, vmdk.path @@ -519,7 +519,7 @@ def fetch_image_ova(context, instance, session, vm_name, datastore, vmdk = vm_util.get_vmdk_info(session, imported_vm_ref, vm_name) - vm_util.mark_vm_as_template(session, instance, imported_vm_ref) + vm_util.mark_vm_as_template(session, imported_vm_ref) return vmdk.capacity_in_bytes, vmdk.path raise exception.ImageUnacceptable( reason=_("Extracting vmdk from OVA failed."), diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index cad0f544350..1a4f41a6e85 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -1411,26 +1411,22 @@ def search_vm_ref_by_identifier(session, identifier): return vm_ref -@vm_ref_cache_heal_from_instance -def get_host_ref_for_vm(session, instance): +def get_host_ref_for_vm(session, vm_ref): """Get a MoRef to the ESXi host currently running an instance.""" - vm_ref = get_vm_ref(session, instance) return session._call_method(vutil, "get_object_property", vm_ref, "runtime.host") -def get_host_name_for_vm(session, instance): +def get_host_name_for_vm(session, vm_ref): """Get the hostname of the ESXi host currently running an instance.""" - host_ref = get_host_ref_for_vm(session, instance) + host_ref = get_host_ref_for_vm(session, vm_ref) return session._call_method(vutil, "get_object_property", host_ref, "name") -@vm_ref_cache_heal_from_instance -def get_vm_state(session, instance): - vm_ref = get_vm_ref(session, instance) +def get_vm_state(session, vm_ref): vm_state = session._call_method(vutil, "get_object_property", vm_ref, "runtime.powerState") return constants.POWER_STATES[vm_state] @@ -1720,7 +1716,7 @@ def get_vmdk_adapter_type(adapter_type): return vmdk_adapter_type -def create_vm(session, instance, vm_folder, config_spec, res_pool_ref): +def create_vm(session, vm_folder, config_spec, res_pool_ref): """Create VM on ESX host.""" LOG.debug("Creating VM on the ESX host") vm_create_task = session._call_method( @@ -1748,21 +1744,14 @@ def create_vm(session, instance, vm_folder, config_spec, res_pool_ref): return task_info.result -@vm_ref_cache_heal_from_instance -def _destroy_vm(session, instance, vm_ref=None): - if not vm_ref: - vm_ref = get_vm_ref(session, instance) - LOG.debug("Destroying the VM") - destroy_task = session._call_method(session.vim, "Destroy_Task", - vm_ref) - session._wait_for_task(destroy_task) - LOG.info("Destroyed the VM") - - -def destroy_vm(session, instance, vm_ref=None): +def destroy_vm(session, vm_ref): """Destroy a VM instance. Assumes VM is powered off.""" try: - return _destroy_vm(session, instance, vm_ref=vm_ref) + LOG.debug("Destroying the VM") + destroy_task = session._call_method(session.vim, "Destroy_Task", + vm_ref) + session._wait_for_task(destroy_task) + LOG.info("Destroyed the VM") except vexc.VimFaultException as e: with excutils.save_and_reraise_exception() as ctx: LOG.exception(_('Destroy VM failed')) @@ -1774,11 +1763,9 @@ def destroy_vm(session, instance, vm_ref=None): LOG.exception(_('Destroy VM failed')) -def mark_vm_as_template(session, instance, vm_ref=None): +def mark_vm_as_template(session, vm_ref): """Mark a VM instance as template. Assumes VM is powered off.""" try: - if not vm_ref: - vm_ref = get_vm_ref(session, instance) LOG.debug("Marking the VM as template") session._call_method(session.vim, "MarkAsTemplate", vm_ref) LOG.info("Marked the VM as template") @@ -1855,13 +1842,8 @@ def reconfigure_vm(session, vm_ref, config_spec): session._wait_for_task(reconfig_task) -@vm_ref_cache_heal_from_instance -def power_on_instance(session, instance, vm_ref=None): +def power_on_instance(session, vm_ref): """Power on the specified instance.""" - - if vm_ref is None: - vm_ref = get_vm_ref(session, instance) - LOG.debug("Powering on the VM") try: poweron_task = session._call_method( @@ -1916,13 +1898,9 @@ def get_vm_detach_port_index(session, vm_ref, iface_id): return int(option.key.split('.')[2]) -@vm_ref_cache_heal_from_instance -def power_off_instance(session, instance, vm_ref=None): +def power_off_instance(session, vm_ref): """Power off the specified instance.""" - if vm_ref is None: - vm_ref = get_vm_ref(session, instance) - LOG.debug("Powering off the VM") try: poweroff_task = session._call_method(session.vim, diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 9ce72c42849..337ea06b972 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -49,6 +49,7 @@ from nova.console import type as ctype from nova import context as nova_context from nova import exception +from nova.i18n import _ from nova import network from nova import objects from nova.objects import fields @@ -175,7 +176,7 @@ def _get_base_folder(self): base_folder = CONF.image_cache_subdirectory_name return base_folder - def _extend_virtual_disk(self, instance, requested_size, name, dc_ref): + def _extend_virtual_disk(self, requested_size, name, dc_ref): service_content = self._session.vim.service_content LOG.debug("Extending root virtual disk to %s", requested_size) vmdk_extend_task = self._session._call_method( @@ -212,8 +213,7 @@ def _delete_datastore_file(self, datastore_path, dc_ref): {'ds': datastore_path}, exc_info=True) - def _extend_if_required(self, dc_info, image_info, instance, - root_vmdk_path): + def _extend_if_required(self, dc_info, instance, root_vmdk_path): root_vmdk = ds_obj.DatastorePath.parse(root_vmdk_path.replace( ".vmdk", "-flat.vmdk")) @@ -228,7 +228,7 @@ def _extend_if_required(self, dc_info, image_info, instance, root_vmdk.basename) if instance.flavor.root_gb * units.Gi > actual_file_size: size_in_kb = instance.flavor.root_gb * units.Mi - self._extend_virtual_disk(instance, size_in_kb, + self._extend_virtual_disk(size_in_kb, root_vmdk_path, dc_info.ref) def _configure_config_drive(self, context, instance, vm_ref, dc_info, @@ -247,10 +247,8 @@ def _configure_config_drive(self, context, instance, vm_ref, dc_info, instance.uuid, cookies) uploaded_iso_path = datastore.build_path(uploaded_iso_path) - self._attach_cdrom_to_vm( - vm_ref, instance, - datastore.ref, - str(uploaded_iso_path)) + self._attach_cdrom_to_vm(vm_ref, datastore.ref, + str(uploaded_iso_path)) def _get_instance_metadata(self, context, instance, flavor=None): if not flavor: @@ -331,7 +329,7 @@ def _get_vm_config_spec(self, instance, image_info, return config_spec - def build_virtual_machine(self, instance, context, image_info, datastore, + def build_virtual_machine(self, instance, image_info, datastore, network_info, extra_specs, metadata, vm_folder, vm_name=None): config_spec = self._get_vm_config_spec(instance, @@ -343,7 +341,7 @@ def build_virtual_machine(self, instance, context, image_info, datastore, vm_name=vm_name) # Create the VM - vm_ref = vm_util.create_vm(self._session, instance, vm_folder, + vm_ref = vm_util.create_vm(self._session, vm_folder, config_spec, self._root_resource_pool) return vm_ref @@ -637,7 +635,7 @@ def _cache_vm_image(self, vi, tmp_image_ds_loc): except vexc.FileAlreadyExistsException: pass - def _unregister_template_vm(self, templ_vm_ref, instance=None): + def _unregister_template_vm(self, templ_vm_ref): """Unregister a template VM We need to Unregister instead of Destroy, if the datastore path does @@ -668,7 +666,7 @@ def _cache_vm_image_from_template(self, vi, templ_vm_ref): except vexc.FileNotFoundException: LOG.warning("Could not find files for template VM %s", templ_vm_ref.value) - self._unregister_template_vm(templ_vm_ref, vi.instance) + self._unregister_template_vm(templ_vm_ref) return False LOG.debug("Cached VDMK from template VM") @@ -851,7 +849,7 @@ def _fetch_image_if_missing(self, context, vi): if vi.ii.disk_type == constants.DISK_TYPE_SPARSE: self._update_image_size(vi) - def _create_and_attach_thin_disk(self, instance, vm_ref, dc_info, size, + def _create_and_attach_thin_disk(self, vm_ref, dc_info, size, adapter_type, path): disk_type = constants.DISK_TYPE_THIN vm_util.create_virtual_disk( @@ -862,7 +860,7 @@ def _create_and_attach_thin_disk(self, instance, vm_ref, dc_info, size, size) self._volumeops.attach_disk_to_vm( - vm_ref, instance, + vm_ref, adapter_type, disk_type, path, size, False) @@ -877,7 +875,7 @@ def _create_ephemeral(self, bdi, instance, vm_ref, dc_info, filename = vm_util.get_ephemeral_name(idx) path = str(ds_obj.DatastorePath(datastore.name, folder, filename)) - self._create_and_attach_thin_disk(instance, vm_ref, dc_info, + self._create_and_attach_thin_disk(vm_ref, dc_info, size, at, path) # There may be block devices defined but no ephemerals. In this case @@ -887,7 +885,7 @@ def _create_ephemeral(self, bdi, instance, vm_ref, dc_info, filename = vm_util.get_ephemeral_name(0) path = str(ds_obj.DatastorePath(datastore.name, folder, filename)) - self._create_and_attach_thin_disk(instance, vm_ref, dc_info, size, + self._create_and_attach_thin_disk(vm_ref, dc_info, size, adapter_type, path) def _create_swap(self, bdi, instance, vm_ref, dc_info, datastore, @@ -899,7 +897,7 @@ def _create_swap(self, bdi, instance, vm_ref, dc_info, datastore, swap = driver.block_device_info_get_swap(bdi) if driver.swap_is_usable(swap): size = swap['swap_size'] * units.Ki - self._create_and_attach_thin_disk(instance, vm_ref, dc_info, + self._create_and_attach_thin_disk(vm_ref, dc_info, size, adapter_type, path) else: # driver.block_device_info_get_swap returns @@ -911,7 +909,7 @@ def _create_swap(self, bdi, instance, vm_ref, dc_info, datastore, size = instance.flavor.swap * units.Ki if not swap and size > 0: - self._create_and_attach_thin_disk(instance, vm_ref, dc_info, size, + self._create_and_attach_thin_disk(vm_ref, dc_info, size, adapter_type, path) def _update_vnic_index(self, context, instance, network_info): @@ -939,13 +937,13 @@ def _create_image_template(self, context, vi, extra_specs): max_attempts = 2 for i in six.moves.range(max_attempts): + templ_vm_ref = None try: vm_folder = self._get_project_folder(vi.dc_info, project_id=vi.ii.owner, type_='Images') templ_vm_ref = self.build_virtual_machine(vi.instance, - context, vi.ii, vi.datastore, None, @@ -966,9 +964,7 @@ def _create_image_template(self, context, vi, extra_specs): else: self._use_disk_image_as_full_clone(templ_vm_ref, vi) - vm_util.mark_vm_as_template(self._session, - vi.instance, - templ_vm_ref) + vm_util.mark_vm_as_template(self._session, templ_vm_ref) return templ_vm_ref except Exception as create_templ_exc: @@ -979,7 +975,8 @@ def _create_image_template(self, context, vi, extra_specs): ' with error: %s', create_templ_exc) try: - vm_util.destroy_vm(self._session, vi.instance) + if templ_vm_ref: + vm_util.destroy_vm(self._session, templ_vm_ref) except Exception as destroy_templ_exc: LOG.error('Cleaning up VM template for' ' image failed with error: %s', @@ -1072,7 +1069,6 @@ def _create_instance_from_image_template(self, context, vm_ref, uuid=vi.instance.uuid) self._extend_if_required(vi.dc_info, - vi.ii, vi.instance, root_vmdk_info.path) @@ -1187,7 +1183,6 @@ def spawn(self, context, instance, image_meta, injected_files, vm_folder = self._get_project_folder( vi.dc_info, project_id=instance.project_id, type_='Instances') vm_ref = self.build_virtual_machine(instance, - context, image_info, vi.datastore, network_info, @@ -1277,7 +1272,7 @@ def spawn(self, context, instance, image_meta, injected_files, # Make sure we don't automatically move around "big" VMs self.disable_drs_if_needed(instance) - vm_util.power_on_instance(self._session, instance, vm_ref=vm_ref) + vm_util.power_on_instance(self._session, vm_ref) self._clean_up_after_special_spawning(context, instance.memory_mb, instance.flavor) @@ -1376,8 +1371,7 @@ def _create_config_drive(self, context, instance, injected_files, LOG.error('Creating config drive failed with error: %s', e) - def _attach_cdrom_to_vm(self, vm_ref, instance, - datastore, file_path): + def _attach_cdrom_to_vm(self, vm_ref, datastore, file_path): """Attach cdrom to VM by reconfiguration.""" client_factory = self._session.vim.client.factory devices = vm_util.get_hardware_devices(self._session, vm_ref) @@ -1417,7 +1411,7 @@ def _create_vm_snapshot(self, instance, vm_ref, image_id=None): return snapshot @retry_if_task_in_progress - def _delete_vm_snapshot(self, instance, vm_ref, snapshot): + def _delete_vm_snapshot(self, snapshot): LOG.debug("Deleting Snapshot of the VM instance") delete_snapshot_task = self._session._call_method( self._session.vim, @@ -1426,37 +1420,6 @@ def _delete_vm_snapshot(self, instance, vm_ref, snapshot): self._session._wait_for_task(delete_snapshot_task) LOG.debug("Deleted Snapshot of the VM instance") - def _create_linked_clone_from_snapshot(self, instance, - vm_ref, snapshot_ref, dc_info): - """Create linked clone VM to be deployed to same ds as source VM - """ - client_factory = self._session.vim.client.factory - rel_spec = vm_util.relocate_vm_spec( - client_factory, - datastore=None, - host=None, - disk_move_type="createNewChildDiskBacking") - clone_spec = vm_util.clone_vm_spec(client_factory, rel_spec, - power_on=False, snapshot=snapshot_ref, template=True) - vm_name = "%s_%s" % (constants.SNAPSHOT_VM_PREFIX, - uuidutils.generate_uuid()) - - LOG.debug("Creating linked-clone VM from snapshot") - vm_clone_task = self._session._call_method( - self._session.vim, - "CloneVM_Task", - vm_ref, - folder=dc_info.vmFolder, - name=vm_name, - spec=clone_spec) - self._session._wait_for_task(vm_clone_task) - LOG.info("Created linked-clone VM from snapshot") - task_info = self._session._call_method(vutil, - "get_object_property", - vm_clone_task, - "info") - return task_info.result - def _create_vm_clone(self, instance, vm_ref, snapshot_ref, dc_info, disk_move_type=None, image_id=None, disks=None, volume_mapping=None): @@ -1628,8 +1591,7 @@ def _get_vm_and_vmdk_attribs(): finally: if snapshot_vm_ref: try: - vm_util.destroy_vm(self._session, instance, - snapshot_vm_ref) + vm_util.destroy_vm(self._session, snapshot_vm_ref) except Exception: # exception is logged inside the function. we can continue. pass @@ -1637,7 +1599,7 @@ def _get_vm_and_vmdk_attribs(): # based on it allows the instance vm's disks to be consolidated. # TODO(vui) Add handling for when vmdk volume is attached. if snapshot_ref: - self._delete_vm_snapshot(instance, vm_ref, snapshot_ref) + self._delete_vm_snapshot(snapshot_ref) def reboot(self, instance, network_info, reboot_type="SOFT"): """Reboot a VM instance.""" @@ -1650,7 +1612,7 @@ def reboot(self, instance, network_info, reboot_type="SOFT"): # Raise an exception if the VM is not powered On. if pwr_state not in ["poweredOn"]: - reason = _("instance is not powered on") + reason = "instance is not powered on" raise exception.InstanceRebootFailure(reason=reason) # If latest vmware tools are installed in the VM, and that the tools @@ -1669,7 +1631,7 @@ def reboot(self, instance, network_info, reboot_type="SOFT"): self._session._wait_for_task(reset_task) LOG.debug("Did hard reboot of VM") - def _destroy_instance(self, context, instance, destroy_disks=True): + def _destroy_instance(self, instance, destroy_disks=True): # Destroy a VM instance try: vm_ref = vm_util.get_vm_ref(self._session, instance) @@ -1689,7 +1651,7 @@ def _destroy_instance(self, context, instance, destroy_disks=True): # Power off the VM if it is in PoweredOn state. if pwr_state == "poweredOn": - vm_util.power_off_instance(self._session, instance, vm_ref) + vm_util.power_off_instance(self._session, vm_ref) # Un-register the VM try: @@ -1727,7 +1689,7 @@ def _destroy_instance(self, context, instance, destroy_disks=True): except exception.InstanceNotFound: LOG.warning('Instance does not exist on backend') except Exception: - LOG.exception(_('Destroy instance failed')) + LOG.exception('Destroy instance failed') finally: vm_util.vm_ref_cache_delete(instance.uuid) @@ -1740,15 +1702,15 @@ def destroy(self, context, instance, destroy_disks=True): 3. Delete the contents of the folder holding the VM related data. """ LOG.debug("Destroying instance") - self._destroy_instance(context, instance, destroy_disks=destroy_disks) + self._destroy_instance(instance, destroy_disks=destroy_disks) LOG.debug("Instance destroyed") def pause(self, instance): - msg = _("pause not supported for vmwareapi") + msg = "pause not supported for vmwareapi" raise NotImplementedError(msg) def unpause(self, instance): - msg = _("unpause not supported for vmwareapi") + msg = "unpause not supported for vmwareapi" raise NotImplementedError(msg) def suspend(self, instance): @@ -1767,7 +1729,7 @@ def suspend(self, instance): LOG.debug("Suspended the VM") # Raise Exception if VM is poweredOff elif pwr_state == "poweredOff": - reason = _("instance is powered off and cannot be suspended.") + reason = "instance is powered off and cannot be suspended." raise exception.InstanceSuspendFailure(reason=reason) else: LOG.debug("VM was already in suspended state. So returning " @@ -1819,7 +1781,7 @@ def rescue(self, context, instance, network_info, image_meta): datastore, dc_info, self._imagecache) - vm_util.power_off_instance(self._session, instance, vm_ref) + vm_util.power_off_instance(self._session, vm_ref) # Fetch the image if it does not exist in the cache self._fetch_image_if_missing(context, vi) @@ -1834,7 +1796,7 @@ def rescue(self, context, instance, network_info, image_meta): ds_util.disk_copy(self._session, dc_info.ref, vi.cache_image_path, rescue_disk_path) # Attach the rescue disk to the instance - self._volumeops.attach_disk_to_vm(vm_ref, instance, vmdk.adapter_type, + self._volumeops.attach_disk_to_vm(vm_ref, vmdk.adapter_type, vmdk.disk_type, rescue_disk_path) # Get the rescue device and configure the boot order to # boot from this device @@ -1843,7 +1805,7 @@ def rescue(self, context, instance, network_info, image_meta): boot_spec = vm_util.get_vm_boot_spec(factory, rescue_device) # Update the VM with the new boot order and power on vm_util.reconfigure_vm(self._session, vm_ref, boot_spec) - vm_util.power_on_instance(self._session, instance, vm_ref=vm_ref) + vm_util.power_on_instance(self._session, vm_ref) def unrescue(self, instance, power_on=True): """Unrescue the specified instance.""" @@ -1855,11 +1817,11 @@ def unrescue(self, instance, power_on=True): except exception.NotFound: with excutils.save_and_reraise_exception(): LOG.error('Unable to access the rescue disk') - vm_util.power_off_instance(self._session, instance, vm_ref) - self._volumeops.detach_disk_from_vm(vm_ref, instance, rescue_device, + vm_util.power_off_instance(self._session, vm_ref) + self._volumeops.detach_disk_from_vm(vm_ref, rescue_device, destroy_disk=True) if power_on: - vm_util.power_on_instance(self._session, instance, vm_ref=vm_ref) + vm_util.power_on_instance(self._session, vm_ref) def power_off(self, instance, timeout=0, retry_interval=0): """Power off the specified instance. @@ -1875,7 +1837,8 @@ def power_off(self, instance, timeout=0, retry_interval=0): retry_interval): return - vm_util.power_off_instance(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_util.power_off_instance(self._session, vm_ref) self.update_cached_instances() def _clean_shutdown(self, instance, timeout, retry_interval): @@ -1955,10 +1918,11 @@ def _get_instance_props(self, vm_ref): vm_ref, lst_properties) def power_on(self, instance): - vm_util.power_on_instance(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_util.power_on_instance(self._session, vm_ref) self.update_cached_instances() - def _update_instance_progress(self, context, instance, step, total_steps): + def _update_instance_progress(self, instance, step, total_steps): """Update instance progress percent to reflect current step number """ # Divide the action's workflow into discrete steps and "bump" the @@ -2033,16 +1997,16 @@ def _resize_disk(self, instance, vm_ref, vmdk, flavor): 'resized.vmdk')) ds_util.disk_copy(self._session, dc_info.ref, vmdk.path, str(resized_disk)) - self._extend_virtual_disk(instance, root_disk_in_kb, resized_disk, + self._extend_virtual_disk(root_disk_in_kb, resized_disk, dc_info.ref) - self._volumeops.detach_disk_from_vm(vm_ref, instance, vmdk.device) + self._volumeops.detach_disk_from_vm(vm_ref, vmdk.device) original_disk = str(ds_obj.DatastorePath(datastore, folder, 'original.vmdk')) ds_util.disk_move(self._session, dc_info.ref, vmdk.path, original_disk) ds_util.disk_move(self._session, dc_info.ref, resized_disk, vmdk.path) - self._volumeops.attach_disk_to_vm(vm_ref, instance, + self._volumeops.attach_disk_to_vm(vm_ref, vmdk.adapter_type, vmdk.disk_type, vmdk.path) @@ -2092,13 +2056,13 @@ def migrate_disk_and_power_off(self, context, instance, dest, flavor): exception.ResizeError(reason=reason)) # 0. Zero out the progress to begin - self._update_instance_progress(context, instance, + self._update_instance_progress(instance, step=0, total_steps=RESIZE_TOTAL_STEPS) # 1. Power off the instance - vm_util.power_off_instance(self._session, instance, vm_ref) - self._update_instance_progress(context, instance, + vm_util.power_off_instance(self._session, vm_ref) + self._update_instance_progress(instance, step=1, total_steps=RESIZE_TOTAL_STEPS) @@ -2134,12 +2098,11 @@ def _revert_migration_update_disks(self, vm_ref, instance, vmdk, if ds_util.file_exists(self._session, ds_browser, original_disk.parent, original_disk.basename): - self._volumeops.detach_disk_from_vm(vm_ref, instance, - vmdk.device) + self._volumeops.detach_disk_from_vm(vm_ref, vmdk.device) ds_util.disk_delete(self._session, dc_info.ref, vmdk.path) ds_util.disk_move(self._session, dc_info.ref, str(original_disk), vmdk.path) - self._volumeops.attach_disk_to_vm(vm_ref, instance, + self._volumeops.attach_disk_to_vm(vm_ref, vmdk.adapter_type, vmdk.disk_type, vmdk.path) # Reconfigure ephemerals @@ -2152,7 +2115,7 @@ def finish_revert_migration(self, context, instance, network_info, """Finish reverting a resize.""" vm_ref = vm_util.get_vm_ref(self._session, instance) # Ensure that the VM is off - vm_util.power_off_instance(self._session, instance, vm_ref) + vm_util.power_off_instance(self._session, vm_ref) client_factory = self._session.vim.client.factory # Reconfigure the VM properties extra_specs = self._get_extra_specs(instance.flavor, @@ -2190,7 +2153,7 @@ def finish_revert_migration(self, context, instance, network_info, self._attach_volumes(instance, block_device_info, adapter_type) if power_on: - vm_util.power_on_instance(self._session, instance) + vm_util.power_on_instance(self._session, vm_ref) def finish_migration(self, context, migration, instance, disk_info, network_info, image_meta, resize_instance=False, @@ -2228,7 +2191,7 @@ def finish_migration(self, context, migration, instance, disk_info, self.update_cluster_placement(context, instance) self.disable_drs_if_needed(instance) - self._update_instance_progress(context, instance, + self._update_instance_progress(instance, step=2, total_steps=RESIZE_TOTAL_STEPS) # 3.Reconfigure the VM and disk @@ -2237,32 +2200,32 @@ def finish_migration(self, context, migration, instance, disk_info, vmdk = vm_util.get_vmdk_info(self._session, vm_ref, uuid=instance.uuid) self._resize_disk(instance, vm_ref, vmdk, flavor) - self._update_instance_progress(context, instance, + self._update_instance_progress(instance, step=3, total_steps=RESIZE_TOTAL_STEPS) # 4. Purge ephemeral and swap disks self._remove_ephemerals_and_swap(vm_ref) - self._update_instance_progress(context, instance, + self._update_instance_progress(instance, step=4, total_steps=RESIZE_TOTAL_STEPS) # 5. Update ephemerals self._resize_create_ephemerals_and_swap(vm_ref, instance, block_device_info) - self._update_instance_progress(context, instance, + self._update_instance_progress(instance, step=5, total_steps=RESIZE_TOTAL_STEPS) # 6. Attach the volumes (if necessary) if reattach_volumes: self._attach_volumes(instance, block_device_info, adapter_type) - self._update_instance_progress(context, instance, + self._update_instance_progress(instance, step=6, total_steps=RESIZE_TOTAL_STEPS) # 7. Start VM if power_on: - vm_util.power_on_instance(self._session, instance, vm_ref=vm_ref) - self._update_instance_progress(context, instance, + vm_util.power_on_instance(self._session, vm_ref) + self._update_instance_progress(instance, step=7, total_steps=RESIZE_TOTAL_STEPS) @@ -2748,7 +2711,7 @@ def _destroy_expired_image_templates(self, templ_vm_folder_ref): msg = "Destroying expired image-template VM {}" LOG.debug(msg.format(templ_vm_name)) try: - vm_util.destroy_vm(self._session, None, templ_vm_ref) + vm_util.destroy_vm(self._session, templ_vm_ref) except vexc.VimFaultException as e: with excutils.save_and_reraise_exception() as ctx: if 'InvalidArgument' in e.fault_list \ @@ -2899,11 +2862,12 @@ def _use_disk_image_as_full_clone(self, vm_ref, vi): str(vi.cache_image_path), str(root_disk_ds_loc)) - self._extend_if_required( - vi.dc_info, vi.ii, vi.instance, str(root_disk_ds_loc)) + self._extend_if_required(vi.dc_info, + vi.instance, + str(root_disk_ds_loc)) self._volumeops.attach_disk_to_vm( - vm_ref, vi.instance, + vm_ref, vi.ii.adapter_type, vi.ii.disk_type, str(root_disk_ds_loc), vi.root_gb * units.Mi, False, @@ -2971,12 +2935,12 @@ def _use_disk_image_as_linked_clone(self, vm_ref, vi): # for cleanup up here, as _extend_virtual_disk # already does it self._extend_if_required( - vi.dc_info, vi.ii, vi.instance, str(sized_disk_ds_loc)) + vi.dc_info, vi.instance, str(sized_disk_ds_loc)) # Associate the sized image disk to the VM by attaching to the VM a # COW child of said disk. self._volumeops.attach_disk_to_vm( - vm_ref, vi.instance, + vm_ref, vi.ii.adapter_type, vi.ii.disk_type, str(sized_disk_ds_loc), vi.root_gb * units.Mi, vi.ii.linked_clone, @@ -2985,9 +2949,8 @@ def _use_disk_image_as_linked_clone(self, vm_ref, vi): def _use_iso_image(self, vm_ref, vi): """Uses cached image as a bootable virtual cdrom.""" - self._attach_cdrom_to_vm( - vm_ref, vi.instance, vi.datastore.ref, - str(vi.cache_image_path)) + self._attach_cdrom_to_vm(vm_ref, vi.datastore.ref, + str(vi.cache_image_path)) # Optionally create and attach blank disk if vi.root_gb > 0: @@ -3007,7 +2970,7 @@ def _use_iso_image(self, vm_ref, vi): vi.root_gb * units.Mi) self._volumeops.attach_disk_to_vm( - vm_ref, vi.instance, + vm_ref, vi.ii.adapter_type, vi.ii.disk_type, str(root_disk_ds_loc), vi.root_gb * units.Mi, linked_clone, @@ -3059,11 +3022,9 @@ def get_vnc_console(self, instance): # a VNC proxy. Instead, you need to tell OpenStack to talk # directly to the ESX host running the VM you are attempting # to connect to via VNC. - + vm_ref = vm_util.get_vm_ref(self._session, instance) vnc_console = self._get_vnc_console_connection(instance) - host_name = vm_util.get_host_name_for_vm( - self._session, - instance) + host_name = vm_util.get_host_name_for_vm(self._session, vm_ref) vnc_console['host'] = host_name # NOTE: VM can move hosts in some situations. Debug for admins. diff --git a/nova/virt/vmwareapi/volumeops.py b/nova/virt/vmwareapi/volumeops.py index dceb8cf7ba7..63e28117b5f 100644 --- a/nova/virt/vmwareapi/volumeops.py +++ b/nova/virt/vmwareapi/volumeops.py @@ -40,7 +40,7 @@ def __init__(self, session, cluster=None): self._session = session self._cluster = cluster - def attach_disk_to_vm(self, vm_ref, instance, + def attach_disk_to_vm(self, vm_ref, adapter_type, disk_type, vmdk_path=None, disk_size=None, linked_clone=False, device_name=None, disk_io_limits=None, @@ -102,7 +102,7 @@ def _get_volume_uuid(self, vm_ref, volume_uuid): if opt_val is not None: return opt_val.value - def detach_disk_from_vm(self, vm_ref, instance, device, + def detach_disk_from_vm(self, vm_ref, device, destroy_disk=False, volume_uuid=None): """Detach disk from VM by reconfiguration. @@ -281,11 +281,11 @@ def _iscsi_discover_target(self, data): 'target_portal': target_portal}) return (device_name, uuid) - def _iscsi_get_host_iqn(self, instance): + def _iscsi_get_host_iqn(self, vm_ref): """Return the host iSCSI IQN.""" - try: - host_mor = vm_util.get_host_ref_for_vm(self._session, instance) - except exception.InstanceNotFound: + if vm_ref: + host_mor = vm_util.get_host_ref_for_vm(self._session, vm_ref) + else: host_mor = vm_util.get_host_ref(self._session, self._cluster) hbas_ret = self._session._call_method( @@ -314,7 +314,7 @@ def get_volume_connector(self, instance): vm_ref = vm_util.get_vm_ref(self._session, instance) except exception.InstanceNotFound: vm_ref = None - iqn = self._iscsi_get_host_iqn(instance) + iqn = self._iscsi_get_host_iqn(vm_ref) connector = {'ip': CONF.vmware.host_ip, 'initiator': iqn, 'host': CONF.vmware.host_ip} @@ -353,13 +353,13 @@ def _attach_volume_vmdk(self, connection_info, instance, # IDE does not support disk hotplug if adapter_type == constants.ADAPTER_TYPE_IDE: - state = vm_util.get_vm_state(self._session, instance) + state = vm_util.get_vm_state(self._session, vm_ref) if state != power_state.SHUTDOWN: raise exception.Invalid(_('%s does not support disk ' 'hotplug.') % adapter_type) # Attach the disk to virtual machine instance - self.attach_disk_to_vm(vm_ref, instance, adapter_type, vmdk.disk_type, + self.attach_disk_to_vm(vm_ref, adapter_type, vmdk.disk_type, vmdk_path=vmdk.path, volume_uuid=data['volume_id'], backing_uuid=vmdk.device.backing.uuid) @@ -386,7 +386,7 @@ def _attach_volume_iscsi(self, connection_info, instance, vm_ref) adapter_type = vm_util.get_scsi_adapter_type(hardware_devices) - self.attach_disk_to_vm(vm_ref, instance, + self.attach_disk_to_vm(vm_ref, adapter_type, 'rdmp', device_name=device_name) LOG.debug("Attached ISCSI: %s", connection_info) @@ -427,7 +427,7 @@ def _get_res_pool_of_vm(self, vm_ref): # Get the resource pool of host's cluster. return self._get_res_pool_of_host(host) - def _consolidate_vmdk_volume(self, instance, vm_ref, device, volume_ref, + def _consolidate_vmdk_volume(self, vm_ref, device, volume_ref, adapter_type=None, disk_type=None): """Consolidate volume backing VMDK files if needed. @@ -487,7 +487,7 @@ def _consolidate_vmdk_volume(self, instance, vm_ref, device, volume_ref, original_device_path, exc_info=True) LOG.debug("Removing disk device of volume's backing and " "reattempting relocate.") - self.detach_disk_from_vm(volume_ref, instance, original_device) + self.detach_disk_from_vm(volume_ref, original_device) detached = True vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore, host) @@ -496,14 +496,14 @@ def _consolidate_vmdk_volume(self, instance, vm_ref, device, volume_ref, # already. if not detached: try: - self.detach_disk_from_vm(volume_ref, instance, + self.detach_disk_from_vm(volume_ref, original_device, destroy_disk=True) except oslo_vmw_exceptions.FileNotFoundException: LOG.debug("Original volume backing %s is missing, no need " "to detach it", original_device.backing.fileName) # Attach the current volume to the volume_ref - self.attach_disk_to_vm(volume_ref, instance, + self.attach_disk_to_vm(volume_ref, adapter_type, disk_type, vmdk_path=current_device_path) @@ -540,18 +540,18 @@ def _detach_volume_vmdk(self, connection_info, instance): # IDE does not support disk hotplug if adapter_type == constants.ADAPTER_TYPE_IDE: - state = vm_util.get_vm_state(self._session, instance) + state = vm_util.get_vm_state(self._session, vm_ref) if state != power_state.SHUTDOWN: raise exception.Invalid(_('%s does not support disk ' 'hotplug.') % adapter_type) disk_type = vm_util._get_device_disk_type(device) - self._consolidate_vmdk_volume(instance, vm_ref, device, volume_ref, + self._consolidate_vmdk_volume(vm_ref, device, volume_ref, adapter_type=adapter_type, disk_type=disk_type) - self.detach_disk_from_vm(vm_ref, instance, device, + self.detach_disk_from_vm(vm_ref, device, volume_uuid=data['volume_id']) LOG.debug("Detached VMDK: %s", connection_info) @@ -574,7 +574,7 @@ def _detach_volume_iscsi(self, connection_info, instance): device = vm_util.get_rdm_disk(hardware_devices, uuid) if device is None: raise exception.DiskNotFound(message=_("Unable to find volume")) - self.detach_disk_from_vm(vm_ref, instance, device, destroy_disk=True) + self.detach_disk_from_vm(vm_ref, device, destroy_disk=True) LOG.debug("Detached ISCSI: %s", connection_info) def detach_volume(self, connection_info, instance): @@ -652,12 +652,11 @@ def fixup_shadow_vms(self, instance, shadow_vms): " attached at %s replacing it with %s", volume, original_device_path, current_device_path, ) - self.detach_disk_from_vm(self, volume_ref, instance, + self.detach_disk_from_vm(vm_ref, volume_ref, original_device, destroy_disk=True) disk_type = vm_util._get_device_disk_type(device) self.attach_disk_to_vm(volume_ref, - instance, constants.DEFAULT_ADAPTER_TYPE, disk_type, current_device_path @@ -666,7 +665,7 @@ def fixup_shadow_vms(self, instance, shadow_vms): LOG.exception("Failed to attach volume {}. Device {}".format( data["volume_id"], device.key)) - def delete_shadow_vms(self, block_device_info, instance=None): + def delete_shadow_vms(self, block_device_info): # We need to delete the migrated shadow vms # (until we implement it in cinder) block_device_mapping = driver.block_device_info_get_mapping( From 7fc389b673c9b28e415c7b38932db7b6a5a87173 Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Tue, 2 Nov 2021 12:59:52 +0100 Subject: [PATCH 6/8] VMware: Split out VMwareAPISession The object is not only used by the driver, but in practically all modules of vmwareapi. It reduces a bit the scope of the driver module itself Change-Id: I76e446945c312e5b4fea54d04335d7d20ef3829d --- nova/tests/unit/virt/vmwareapi/stubs.py | 7 +- .../unit/virt/vmwareapi/test_driver_api.py | 21 +++--- .../unit/virt/vmwareapi/test_network_util.py | 8 +-- .../tests/unit/virt/vmwareapi/test_vm_util.py | 10 +-- nova/tests/unit/virt/vmwareapi/test_vmops.py | 4 +- .../unit/virt/vmwareapi/test_volumeops.py | 4 +- nova/virt/vmwareapi/driver.py | 49 +------------ nova/virt/vmwareapi/session.py | 70 +++++++++++++++++++ 8 files changed, 99 insertions(+), 74 deletions(-) create mode 100644 nova/virt/vmwareapi/session.py diff --git a/nova/tests/unit/virt/vmwareapi/stubs.py b/nova/tests/unit/virt/vmwareapi/stubs.py index 41d5e38794e..e1b4a7957cf 100644 --- a/nova/tests/unit/virt/vmwareapi/stubs.py +++ b/nova/tests/unit/virt/vmwareapi/stubs.py @@ -36,7 +36,7 @@ def fake_vim_prop(arg): return fake.get_fake_vim_object(arg) -def fake_is_vim_object(arg, module): +def fake_is_vim_object(module): """Stubs out the VMwareAPISession's is_vim_object method.""" return isinstance(module, fake.FakeVim) @@ -74,9 +74,10 @@ def set_stubs(test): fake.fake_upload_image) test.stub_out('nova.virt.vmwareapi.images.fetch_image', fake.fake_fetch_image) - test.stub_out('nova.virt.vmwareapi.driver.VMwareAPISession.vim', + test.stub_out('nova.virt.vmwareapi.session.VMwareAPISession.vim', fake_vim_prop) - test.stub_out('nova.virt.vmwareapi.driver.VMwareAPISession._is_vim_object', + test.stub_out('nova.virt.vmwareapi.session.VMwareAPISession.' + '_is_vim_object', fake_is_vim_object) if CONF.use_neutron: test.stub_out( diff --git a/nova/tests/unit/virt/vmwareapi/test_driver_api.py b/nova/tests/unit/virt/vmwareapi/test_driver_api.py index d36e3eb651f..565e529632e 100644 --- a/nova/tests/unit/virt/vmwareapi/test_driver_api.py +++ b/nova/tests/unit/virt/vmwareapi/test_driver_api.py @@ -65,6 +65,7 @@ from nova.virt.vmwareapi import error_util from nova.virt.vmwareapi import imagecache from nova.virt.vmwareapi import images +from nova.virt.vmwareapi.session import VMwareAPISession from nova.virt.vmwareapi import vif from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi import vm_util @@ -125,7 +126,7 @@ class VMwareDriverStartupTestCase(test.NoDBTestCase): def _start_driver_with_flags(self, expected_exception_type, startup_flags): self.flags(**startup_flags) with mock.patch( - 'nova.virt.vmwareapi.driver.VMwareAPISession.__init__'): + 'nova.virt.vmwareapi.session.VMwareAPISession.__init__'): e = self.assertRaises( Exception, driver.VMwareVCDriver, None) # noqa self.assertIs(type(e), expected_exception_type) @@ -160,29 +161,29 @@ def test_start_driver_with_user_host_password(self): class VMwareSessionTestCase(test.NoDBTestCase): - @mock.patch.object(driver.VMwareAPISession, '_is_vim_object', + @mock.patch.object(VMwareAPISession, '_is_vim_object', return_value=False) def test_call_method(self, mock_is_vim): with test.nested( - mock.patch.object(driver.VMwareAPISession, '_create_session', + mock.patch.object(VMwareAPISession, '_create_session', _fake_create_session), - mock.patch.object(driver.VMwareAPISession, 'invoke_api'), + mock.patch.object(VMwareAPISession, 'invoke_api'), ) as (fake_create, fake_invoke): - session = driver.VMwareAPISession() + session = VMwareAPISession() session._vim = mock.Mock() module = mock.Mock() session._call_method(module, 'fira') fake_invoke.assert_called_once_with(module, 'fira', session._vim) - @mock.patch.object(driver.VMwareAPISession, '_is_vim_object', + @mock.patch.object(VMwareAPISession, '_is_vim_object', return_value=True) def test_call_method_vim(self, mock_is_vim): with test.nested( - mock.patch.object(driver.VMwareAPISession, '_create_session', + mock.patch.object(VMwareAPISession, '_create_session', _fake_create_session), - mock.patch.object(driver.VMwareAPISession, 'invoke_api'), + mock.patch.object(VMwareAPISession, 'invoke_api'), ) as (fake_create, fake_invoke): - session = driver.VMwareAPISession() + session = VMwareAPISession() module = mock.Mock() session._call_method(module, 'fira') fake_invoke.assert_called_once_with(module, 'fira') @@ -349,7 +350,7 @@ def _fake_check_session(_self): _fake_check_session) with mock.patch.object(greenthread, 'sleep'): - self.conn = driver.VMwareAPISession() + self.conn = VMwareAPISession() self.assertEqual(2, self.attempts) def _get_instance_type_by_name(self, type): diff --git a/nova/tests/unit/virt/vmwareapi/test_network_util.py b/nova/tests/unit/virt/vmwareapi/test_network_util.py index 9d6533ebfb0..e766ba00be0 100644 --- a/nova/tests/unit/virt/vmwareapi/test_network_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_network_util.py @@ -23,8 +23,8 @@ from nova import test from nova.tests.unit.virt.vmwareapi import fake from nova.tests.unit.virt.vmwareapi import stubs -from nova.virt.vmwareapi import driver from nova.virt.vmwareapi import network_util +from nova.virt.vmwareapi.session import VMwareAPISession from nova.virt.vmwareapi import vm_util @@ -38,12 +38,12 @@ class GetNetworkWithTheNameTestCase(test.NoDBTestCase): def setUp(self): super(GetNetworkWithTheNameTestCase, self).setUp() fake.reset() - self.stub_out('nova.virt.vmwareapi.driver.VMwareAPISession.vim', + self.stub_out('nova.virt.vmwareapi.session.VMwareAPISession.vim', stubs.fake_vim_prop) - self.stub_out('nova.virt.vmwareapi.driver.' + self.stub_out('nova.virt.vmwareapi.session.' 'VMwareAPISession.is_vim_object', stubs.fake_is_vim_object) - self._session = driver.VMwareAPISession() + self._session = VMwareAPISession() def _build_cluster_networks(self, networks): """Returns a set of results for a cluster network lookup. diff --git a/nova/tests/unit/virt/vmwareapi/test_vm_util.py b/nova/tests/unit/virt/vmwareapi/test_vm_util.py index ffa9f7b0f5d..b2edaddc559 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vm_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_vm_util.py @@ -33,7 +33,7 @@ from nova.tests.unit.virt.vmwareapi import fake from nova.tests.unit.virt.vmwareapi import stubs from nova.virt.vmwareapi import constants -from nova.virt.vmwareapi import driver +from nova.virt.vmwareapi.session import VMwareAPISession from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi import vm_util @@ -1226,7 +1226,7 @@ def fake_log_warn(msg, values): found[0] = True mock_log_warn.side_effect = fake_log_warn - session = driver.VMwareAPISession() + session = VMwareAPISession() config_spec = vm_util.get_vm_create_spec( session.vim.client.factory, @@ -2053,19 +2053,19 @@ def test_rename_vm(self, mock_get_name): self._instance.uuid) -@mock.patch.object(driver.VMwareAPISession, 'vim', stubs.fake_vim_prop) +@mock.patch.object(VMwareAPISession, 'vim', stubs.fake_vim_prop) class VMwareVMUtilGetHostRefTestCase(test.NoDBTestCase): # N.B. Mocking on the class only mocks test_*(), but we need # VMwareAPISession.vim to be mocked in both setUp and tests. Not mocking in # setUp causes object initialisation to fail. Not mocking in tests results # in vim calls not using FakeVim. - @mock.patch.object(driver.VMwareAPISession, 'vim', stubs.fake_vim_prop) + @mock.patch.object(VMwareAPISession, 'vim', stubs.fake_vim_prop) def setUp(self): super(VMwareVMUtilGetHostRefTestCase, self).setUp() fake.reset() vm_util.vm_refs_cache_reset() - self.session = driver.VMwareAPISession() + self.session = VMwareAPISession() # Create a fake VirtualMachine running on a known host self.host_ref = list(fake._db_content['HostSystem'].keys())[0] diff --git a/nova/tests/unit/virt/vmwareapi/test_vmops.py b/nova/tests/unit/virt/vmwareapi/test_vmops.py index 33ab80ba6b0..8a5421ab919 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vmops.py +++ b/nova/tests/unit/virt/vmwareapi/test_vmops.py @@ -44,9 +44,9 @@ from nova.virt import hardware from nova.virt.vmwareapi import cluster_util from nova.virt.vmwareapi import constants -from nova.virt.vmwareapi import driver from nova.virt.vmwareapi import ds_util from nova.virt.vmwareapi import images +from nova.virt.vmwareapi.session import VMwareAPISession from nova.virt.vmwareapi import vif from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi import vm_util @@ -75,7 +75,7 @@ def setUp(self): my_ip='', flat_injected=True) self._context = context.RequestContext('fake_user', 'fake_project') - self._session = driver.VMwareAPISession() + self._session = VMwareAPISession() self._virtapi = mock.Mock() self._image_id = nova.tests.unit.image.fake.get_valid_image_id() diff --git a/nova/tests/unit/virt/vmwareapi/test_volumeops.py b/nova/tests/unit/virt/vmwareapi/test_volumeops.py index e2b4180c64c..b665f134152 100644 --- a/nova/tests/unit/virt/vmwareapi/test_volumeops.py +++ b/nova/tests/unit/virt/vmwareapi/test_volumeops.py @@ -27,7 +27,7 @@ from nova.tests.unit.virt.vmwareapi import stubs from nova.tests import uuidsentinel from nova.virt.vmwareapi import constants -from nova.virt.vmwareapi import driver +from nova.virt.vmwareapi.session import VMwareAPISession from nova.virt.vmwareapi import vm_util from nova.virt.vmwareapi import volumeops @@ -39,7 +39,7 @@ def setUp(self): super(VMwareVolumeOpsTestCase, self).setUp() vmwareapi_fake.reset() stubs.set_stubs(self) - self._session = driver.VMwareAPISession() + self._session = VMwareAPISession() self._context = context.RequestContext('fake_user', 'fake_project') self._volumeops = volumeops.VMwareVolumeOps(self._session) diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 40aa53ce94e..1d592ecf6ab 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -31,10 +31,8 @@ from oslo_utils import excutils from oslo_utils import units from oslo_utils import versionutils as v_utils -from oslo_vmware import api from oslo_vmware import exceptions as vexc from oslo_vmware import pbm -from oslo_vmware import vim from oslo_vmware import vim_util from nova.compute import power_state @@ -55,6 +53,7 @@ from nova.virt.vmwareapi import ds_util from nova.virt.vmwareapi import error_util from nova.virt.vmwareapi.host import VCState +from nova.virt.vmwareapi.session import VMwareAPISession from nova.virt.vmwareapi import special_spawning from nova.virt.vmwareapi import vif as vmwarevif from nova.virt.vmwareapi import vim_util as nova_vim_util @@ -1071,49 +1070,3 @@ def ensure_filtering_rules_for_instance(self, instance, network_info): def unfilter_instance(self, instance, network_info): pass - - -class VMwareAPISession(api.VMwareAPISession): - """Sets up a session with the VC/ESX host and handles all - the calls made to the host. - """ - def __init__(self, host_ip=CONF.vmware.host_ip, - host_port=CONF.vmware.host_port, - username=CONF.vmware.host_username, - password=CONF.vmware.host_password, - retry_count=CONF.vmware.api_retry_count, - scheme="https", - cacert=CONF.vmware.ca_file, - insecure=CONF.vmware.insecure, - pool_size=CONF.vmware.connection_pool_size): - super(VMwareAPISession, self).__init__( - host=host_ip, - port=host_port, - server_username=username, - server_password=password, - api_retry_count=retry_count, - task_poll_interval=CONF.vmware.task_poll_interval, - scheme=scheme, - create_session=True, - cacert=cacert, - insecure=insecure, - pool_size=pool_size) - - def _is_vim_object(self, module): - """Check if the module is a VIM Object instance.""" - return isinstance(module, vim.Vim) - - def _call_method(self, module, method, *args, **kwargs): - """Calls a method within the module specified with - args provided. - """ - if not self._is_vim_object(module): - return self.invoke_api(module, method, self.vim, *args, **kwargs) - - return self.invoke_api(module, method, *args, **kwargs) - - def _wait_for_task(self, task_ref): - """Return a Deferred that will give the result of the given task. - The task is polled until it completes. - """ - return self.wait_for_task(task_ref) diff --git a/nova/virt/vmwareapi/session.py b/nova/virt/vmwareapi/session.py new file mode 100644 index 00000000000..f98493427de --- /dev/null +++ b/nova/virt/vmwareapi/session.py @@ -0,0 +1,70 @@ +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. +# Copyright (c) 2012 VMware, Inc. +# Copyright (c) 2011 Citrix Systems, Inc. +# Copyright 2011 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_vmware import api +from oslo_vmware import vim + +import nova.conf + +CONF = nova.conf.CONF + + +class VMwareAPISession(api.VMwareAPISession): + """Sets up a session with the VC/ESX host and handles all + the calls made to the host. + """ + def __init__(self, host_ip=CONF.vmware.host_ip, + host_port=CONF.vmware.host_port, + username=CONF.vmware.host_username, + password=CONF.vmware.host_password, + retry_count=CONF.vmware.api_retry_count, + scheme="https", + cacert=CONF.vmware.ca_file, + insecure=CONF.vmware.insecure, + pool_size=CONF.vmware.connection_pool_size): + super(VMwareAPISession, self).__init__( + host=host_ip, + port=host_port, + server_username=username, + server_password=password, + api_retry_count=retry_count, + task_poll_interval=CONF.vmware.task_poll_interval, + scheme=scheme, + create_session=True, + cacert=cacert, + insecure=insecure, + pool_size=pool_size) + + @staticmethod + def _is_vim_object(module): + """Check if the module is a VIM Object instance.""" + return isinstance(module, vim.Vim) + + def _call_method(self, module, method, *args, **kwargs): + """Calls a method within the module specified with + args provided. + """ + if not self._is_vim_object(module): + return self.invoke_api(module, method, self.vim, *args, **kwargs) + + return self.invoke_api(module, method, *args, **kwargs) + + def _wait_for_task(self, task_ref): + """Return a Deferred that will give the result of the given task. + The task is polled until it completes. + """ + return self.wait_for_task(task_ref) From a323fbd9ed552243d26ad2fe10144bad29b3dbef Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Tue, 2 Nov 2021 13:12:53 +0100 Subject: [PATCH 7/8] Vmwareapi: Rename public VMwareAPISession functions The _wait_for_task doesn't add over the existing wait_for_task function, and the call_method is clearly a public function used all over the place Remove the first, and rename the second accordingly Change-Id: I020fd565a4f68f2498f2bf5e6537391d81f325b9 --- nova/tests/unit/virt/vmwareapi/fake.py | 8 +- .../unit/virt/vmwareapi/test_driver_api.py | 56 +++++------ .../tests/unit/virt/vmwareapi/test_ds_util.py | 44 ++++----- nova/tests/unit/virt/vmwareapi/test_images.py | 4 +- .../unit/virt/vmwareapi/test_network_util.py | 12 +-- nova/tests/unit/virt/vmwareapi/test_vif.py | 4 +- .../tests/unit/virt/vmwareapi/test_vm_util.py | 62 ++++++------ nova/tests/unit/virt/vmwareapi/test_vmops.py | 40 ++++---- .../unit/virt/vmwareapi/test_volumeops.py | 32 +++---- nova/virt/vmwareapi/cluster_util.py | 14 +-- nova/virt/vmwareapi/driver.py | 12 +-- nova/virt/vmwareapi/ds_util.py | 54 +++++------ nova/virt/vmwareapi/host.py | 2 +- nova/virt/vmwareapi/images.py | 12 +-- nova/virt/vmwareapi/network_util.py | 18 ++-- nova/virt/vmwareapi/session.py | 8 +- nova/virt/vmwareapi/special_spawning.py | 14 +-- nova/virt/vmwareapi/vim_util.py | 2 +- nova/virt/vmwareapi/vm_util.py | 94 +++++++++---------- nova/virt/vmwareapi/vmops.py | 80 ++++++++-------- nova/virt/vmwareapi/volumeops.py | 24 ++--- 21 files changed, 295 insertions(+), 301 deletions(-) diff --git a/nova/tests/unit/virt/vmwareapi/fake.py b/nova/tests/unit/virt/vmwareapi/fake.py index fe7e0c7871c..55286d21fa7 100644 --- a/nova/tests/unit/virt/vmwareapi/fake.py +++ b/nova/tests/unit/virt/vmwareapi/fake.py @@ -1216,17 +1216,17 @@ class FakeSession(object): def __init__(self): self.vim = FakeVim() - def _call_method(self, module, method, *args, **kwargs): + def call_method(self, module, method, *args, **kwargs): raise NotImplementedError() - def _wait_for_task(self, task_ref): + def wait_for_task(self, task_ref): raise NotImplementedError() class FakeObjectRetrievalSession(FakeSession): """A session for faking object retrieval tasks. - _call_method() returns a given set of objects + call_method() returns a given set of objects sequentially, regardless of the method called. """ @@ -1235,7 +1235,7 @@ def __init__(self, *ret): self.ret = ret self.ind = 0 - def _call_method(self, module, method, *args, **kwargs): + def call_method(self, module, method, *args, **kwargs): if (method == 'continue_retrieval' or method == 'cancel_retrieval'): return diff --git a/nova/tests/unit/virt/vmwareapi/test_driver_api.py b/nova/tests/unit/virt/vmwareapi/test_driver_api.py index 565e529632e..5b5a2b94d96 100644 --- a/nova/tests/unit/virt/vmwareapi/test_driver_api.py +++ b/nova/tests/unit/virt/vmwareapi/test_driver_api.py @@ -172,7 +172,7 @@ def test_call_method(self, mock_is_vim): session = VMwareAPISession() session._vim = mock.Mock() module = mock.Mock() - session._call_method(module, 'fira') + session.call_method(module, 'fira') fake_invoke.assert_called_once_with(module, 'fira', session._vim) @mock.patch.object(VMwareAPISession, '_is_vim_object', @@ -185,7 +185,7 @@ def test_call_method_vim(self, mock_is_vim): ) as (fake_create, fake_invoke): session = VMwareAPISession() module = mock.Mock() - session._call_method(module, 'fira') + session.call_method(module, 'fira') fake_invoke.assert_called_once_with(module, 'fira') @@ -295,8 +295,8 @@ def test_init_host(self): self.fail("init_host raised: %s" % ex) def _set_exception_vars(self): - self.wait_task = self.conn._session._wait_for_task - self.call_method = self.conn._session._call_method + self.wait_task = self.conn._session.wait_for_task + self.call_method = self.conn._session.call_method self.task_ref = None self.exception = False @@ -817,7 +817,7 @@ def fake_call_method(module, method, *args, **kwargs): return task_ref with ( - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', fake_call_method) ): if fault: @@ -944,9 +944,9 @@ def fake_call_method(module, method, *args, **kwargs): return self.call_method(module, method, *args, **kwargs) with test.nested( - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', new=fake_call_method), - mock.patch.object(self.conn._session, '_wait_for_task', + mock.patch.object(self.conn._session, 'wait_for_task', new=fake_wait_for_task)): self.assertRaises(CopyError, self._create_vm) @@ -980,9 +980,9 @@ def fake_call_method(module, method, *args, **kwargs): return task_ref with test.nested( - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', new=fake_call_method), - mock.patch.object(self.conn._session, '_wait_for_task', + mock.patch.object(self.conn._session, 'wait_for_task', new=fake_wait_for_task)): self.assertRaises(CopyError, self._create_vm) vmwareapi_fake.assertPathNotExists(self, cached_image) @@ -1024,9 +1024,9 @@ def fake_call_method(module, method, *args, **kwargs): return task_ref with test.nested( - mock.patch.object(self.conn._session, '_wait_for_task', + mock.patch.object(self.conn._session, 'wait_for_task', new=fake_wait_for_task), - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', new=fake_call_method)): self.assertRaises(DeleteError, self._create_vm) vmwareapi_fake.assertPathExists(self, cached_image) @@ -1080,9 +1080,9 @@ def fake_call_method(module, method, *args, **kwargs): return task_ref with test.nested( - mock.patch.object(self.conn._session, '_wait_for_task', + mock.patch.object(self.conn._session, 'wait_for_task', fake_wait_for_task), - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', fake_call_method) ) as (mock_wait_for_task, mock_call_method): self.assertRaises(NoDiskSpace, self._create_vm) @@ -1112,9 +1112,9 @@ def fake_call_method(module, method, *args, **kwargs): return task_ref with test.nested( - mock.patch.object(self.conn._session, '_wait_for_task', + mock.patch.object(self.conn._session, 'wait_for_task', fake_wait_for_task), - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): self._create_vm() @@ -1143,9 +1143,9 @@ def fake_call_method(module, method, *args, **kwargs): return task_ref with test.nested( - mock.patch.object(self.conn._session, '_wait_for_task', + mock.patch.object(self.conn._session, 'wait_for_task', fake_wait_for_task), - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): self.assertRaises(vexc.VMwareDriverException, @@ -1153,7 +1153,7 @@ def fake_call_method(module, method, *args, **kwargs): self.assertTrue(self.exception) def test_spawn_with_move_poll_exception(self): - self.call_method = self.conn._session._call_method + self.call_method = self.conn._session.call_method def fake_call_method(module, method, *args, **kwargs): task_ref = self.call_method(module, method, *args, **kwargs) @@ -1163,7 +1163,7 @@ def fake_call_method(module, method, *args, **kwargs): return task_ref with ( - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', fake_call_method) ): self.assertRaises(vexc.VMwareDriverException, @@ -1188,7 +1188,7 @@ def fake_call_method(module, method, *args, **kwargs): return task_ref with ( - mock.patch.object(self.conn._session, '_call_method', + mock.patch.object(self.conn._session, 'call_method', fake_call_method) ): self._create_vm() @@ -1315,7 +1315,7 @@ def test_search_vm_ref_by_identifier(self, mock_update_cached_instances): def test_get_object_for_optionvalue(self): self._create_vm() - vms = self.conn._session._call_method(vim_util, "get_objects", + vms = self.conn._session.call_method(vim_util, "get_objects", "VirtualMachine", ['config.extraConfig["nvp.vm-uuid"]']) vm_ref = vm_util._get_object_for_optionvalue(vms.objects, self.instance["uuid"]) @@ -1413,7 +1413,7 @@ def _snapshot_delete_vm_snapshot_exception(self, exception, call_count=1): name="VirtualMachineSnapshot") with test.nested( - mock.patch.object(self.conn._session, '_wait_for_task', + mock.patch.object(self.conn._session, 'wait_for_task', side_effect=exception), mock.patch.object(vmops, '_time_sleep_wrapper') ) as (_fake_wait, _fake_sleep): @@ -1720,7 +1720,7 @@ def fake_vm_ref_from_name(session, vm_name): mock.patch.object(vm_util, 'get_vm_ref_from_name', fake_vm_ref_from_name), mock.patch.object(self.conn._session, - '_call_method'), + 'call_method'), mock.patch.object(self.conn._vmops, '_destroy_instance') ) as (mock_get, mock_call, mock_destroy): @@ -2233,7 +2233,7 @@ def test_public_api_signatures(self): self.assertPublicAPISignatures(v_driver.ComputeDriver(None), self.conn) def test_register_extension(self): - with mock.patch.object(self.conn._session, '_call_method', + with mock.patch.object(self.conn._session, 'call_method', return_value=None) as mock_call_method: self.conn._register_openstack_extension() mock_call_method.assert_has_calls( @@ -2244,7 +2244,7 @@ def test_register_extension(self): constants.EXTENSION_TYPE_INSTANCE)]) def test_register_extension_already_exists(self): - with mock.patch.object(self.conn._session, '_call_method', + with mock.patch.object(self.conn._session, 'call_method', return_value='fake-extension') as mock_find_ext: self.conn._register_openstack_extension() mock_find_ext.assert_called_once_with(oslo_vim_util, @@ -2260,7 +2260,7 @@ def fake_call_method(module, method, *args, **kwargs): else: raise Exception() with (mock.patch.object( - self.conn._session, '_call_method', fake_call_method)): + self.conn._session, 'call_method', fake_call_method)): self.conn._register_openstack_extension() @mock.patch.object(vmops.VMwareVMOps, 'update_cached_instances') @@ -2530,7 +2530,7 @@ def test_attach_interface_with_exception(self): self._create_vm() vif = self._create_vif() - with mock.patch.object(self.conn._session, '_wait_for_task', + with mock.patch.object(self.conn._session, 'wait_for_task', side_effect=Exception): self.assertRaises(exception.InterfaceAttachFailed, self.conn.attach_interface, @@ -2577,7 +2577,7 @@ def test_detach_interface_with_exception(self, mock_get_device): vif = self._create_vif() self._attach_interface(vif) - with mock.patch.object(self.conn._session, '_wait_for_task', + with mock.patch.object(self.conn._session, 'wait_for_task', side_effect=Exception): self.assertRaises(exception.InterfaceDetachFailed, self.conn.detach_interface, diff --git a/nova/tests/unit/virt/vmwareapi/test_ds_util.py b/nova/tests/unit/virt/vmwareapi/test_ds_util.py index 77cfc41201f..860625003bd 100644 --- a/nova/tests/unit/virt/vmwareapi/test_ds_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_ds_util.py @@ -38,7 +38,7 @@ def tearDown(self): fake.reset() def test_get_datacenter_ref(self): - with mock.patch.object(self.session, '_call_method') as call_method: + with mock.patch.object(self.session, 'call_method') as call_method: ds_util.get_datacenter_ref(self.session, "datacenter") call_method.assert_called_once_with( self.session.vim, @@ -56,8 +56,8 @@ def fake_call_method(module, method, *args, **kwargs): return 'fake_delete_task' with test.nested( - mock.patch.object(self.session, '_wait_for_task'), - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'wait_for_task'), + mock.patch.object(self.session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): ds_path = ds_obj.DatastorePath('ds', 'fake/path') @@ -80,8 +80,8 @@ def fake_call_method(module, method, *args, **kwargs): return 'fake_copy_task' with test.nested( - mock.patch.object(self.session, '_wait_for_task'), - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'wait_for_task'), + mock.patch.object(self.session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): src_ds_path = ds_obj.DatastorePath('ds', 'fake/path', 'src_file') @@ -106,8 +106,8 @@ def fake_call_method(module, method, *args, **kwargs): return 'fake_move_task' with test.nested( - mock.patch.object(self.session, '_wait_for_task'), - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'wait_for_task'), + mock.patch.object(self.session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): src_ds_path = ds_obj.DatastorePath('ds', 'tmp/src') @@ -131,8 +131,8 @@ def fake_call_method(module, method, *args, **kwargs): return 'fake_move_task' with test.nested( - mock.patch.object(self.session, '_wait_for_task'), - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'wait_for_task'), + mock.patch.object(self.session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): ds_util.disk_move(self.session, @@ -142,8 +142,8 @@ def fake_call_method(module, method, *args, **kwargs): def test_disk_copy(self): with test.nested( - mock.patch.object(self.session, '_wait_for_task'), - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'wait_for_task'), + mock.patch.object(self.session, 'call_method', return_value=mock.sentinel.cm) ) as (_wait_for_task, _call_method): ds_util.disk_copy(self.session, mock.sentinel.dc_ref, @@ -158,8 +158,8 @@ def test_disk_copy(self): def test_disk_delete(self): with test.nested( - mock.patch.object(self.session, '_wait_for_task'), - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'wait_for_task'), + mock.patch.object(self.session, 'call_method', return_value=mock.sentinel.cm) ) as (_wait_for_task, _call_method): ds_util.disk_delete(self.session, @@ -179,7 +179,7 @@ def fake_call_method(module, method, *args, **kwargs): createParentDirectories = kwargs.get('createParentDirectories') self.assertTrue(createParentDirectories) - with mock.patch.object(self.session, '_call_method', + with mock.patch.object(self.session, 'call_method', fake_call_method): ds_path = ds_obj.DatastorePath('ds', 'fake/path') ds_util.mkdir(self.session, ds_path, 'fake-dc-ref') @@ -214,9 +214,9 @@ def fake_wait_for_task(task_ref): self.fail() with test.nested( - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'call_method', fake_call_method), - mock.patch.object(self.session, '_wait_for_task', + mock.patch.object(self.session, 'wait_for_task', fake_wait_for_task)): ds_path = ds_obj.DatastorePath('ds', 'fake/path') file_exists = ds_util.file_exists(self.session, @@ -239,9 +239,9 @@ def fake_wait_for_task(task_ref): self.fail() with test.nested( - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'call_method', fake_call_method), - mock.patch.object(self.session, '_wait_for_task', + mock.patch.object(self.session, 'wait_for_task', fake_wait_for_task)): ds_path = ds_obj.DatastorePath('ds', 'fake/path') file_exists = ds_util.file_exists(self.session, @@ -285,7 +285,7 @@ def fake_call_method(module, method, *args, **kwargs): def next_datastore(*args, **kwargs): return next(datastores_i[0]) - with mock.patch.object(self.session, '_call_method', + with mock.patch.object(self.session, 'call_method', side_effect=fake_call_method), \ mock.patch('oslo_vmware.vim_util.continue_retrieval', side_effect=next_datastore), \ @@ -400,7 +400,7 @@ def test_get_datastore_no_host_in_cluster(self): def fake_call_method(module, method, *args, **kwargs): return '' - with mock.patch.object(self.session, '_call_method', + with mock.patch.object(self.session, 'call_method', fake_call_method): self.assertRaises(exception.DatastoreNotFound, ds_util.get_datastore, @@ -456,7 +456,7 @@ def test_is_datastore_valid_matching_regex(self): def test_get_connected_hosts_none(self): with mock.patch.object(self.session, - '_call_method') as _call_method: + 'call_method') as _call_method: hosts = ds_util.get_connected_hosts(self.session, 'fake_datastore') self.assertEqual([], hosts) @@ -472,7 +472,7 @@ def test_get_connected_hosts(self): host_mounts = mock.Mock(spec=object) host_mounts.DatastoreHostMount = [host_mount] - with mock.patch.object(self.session, '_call_method', + with mock.patch.object(self.session, 'call_method', return_value=host_mounts) as _call_method: hosts = ds_util.get_connected_hosts(self.session, 'fake_datastore') diff --git a/nova/tests/unit/virt/vmwareapi/test_images.py b/nova/tests/unit/virt/vmwareapi/test_images.py index c2a8a68b429..d5945e1ded9 100644 --- a/nova/tests/unit/virt/vmwareapi/test_images.py +++ b/nova/tests/unit/virt/vmwareapi/test_images.py @@ -127,7 +127,7 @@ def test_fetch_image_ova(self, mock_tar_open, mock_write_class, mock.patch.object(images.IMAGE_API, 'download'), mock.patch.object(images, 'image_transfer'), mock.patch.object(images, '_build_shadow_vm_config_spec'), - mock.patch.object(session, '_call_method'), + mock.patch.object(session, 'call_method'), mock.patch.object(vm_util, 'get_vmdk_info') ) as (mock_image_api_get, mock_image_api_download, @@ -198,7 +198,7 @@ def test_fetch_image_stream_optimized(self, mock.patch.object(images.IMAGE_API, 'download'), mock.patch.object(images, 'image_transfer'), mock.patch.object(images, '_build_shadow_vm_config_spec'), - mock.patch.object(session, '_call_method'), + mock.patch.object(session, 'call_method'), mock.patch.object(vm_util, 'get_vmdk_info') ) as (mock_image_api_get, mock_image_api_download, diff --git a/nova/tests/unit/virt/vmwareapi/test_network_util.py b/nova/tests/unit/virt/vmwareapi/test_network_util.py index e766ba00be0..6be301b0bd1 100644 --- a/nova/tests/unit/virt/vmwareapi/test_network_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_network_util.py @@ -104,7 +104,7 @@ def mock_call_method(module, method, *args, **kwargs): result.name = 'no-match' return result - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', mock_call_method): res = network_util.get_network_with_the_name(self._session, 'fake_net', @@ -126,7 +126,7 @@ def mock_call_method(module, method, *args, **kwargs): result.distributedVirtualSwitch = 'fake_dvs' return result - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', mock_call_method): res = network_util.get_network_with_the_name(self._session, 'fake_net', @@ -149,7 +149,7 @@ def mock_call_method(module, method, *args, **kwargs): if method == 'get_object_property': return 'fake_net' - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', mock_call_method): res = network_util.get_network_with_the_name(self._session, 'fake_net', @@ -162,7 +162,7 @@ class GetVlanIdAndVswitchForPortgroupTestCase(test.NoDBTestCase): @mock.patch.object(vm_util, 'get_host_ref') def test_no_port_groups(self, mock_get_host_ref): session = mock.Mock() - session._call_method.return_value = None + session.call_method.return_value = None self.assertRaises( exception.NovaException, network_util.get_vlanid_and_vswitch_for_portgroup, @@ -174,7 +174,7 @@ def test_no_port_groups(self, mock_get_host_ref): @mock.patch.object(vm_util, 'get_host_ref') def test_valid_port_group(self, mock_get_host_ref): session = mock.Mock() - session._call_method.return_value = self._fake_port_groups() + session.call_method.return_value = self._fake_port_groups() vlanid, vswitch = network_util.get_vlanid_and_vswitch_for_portgroup( session, 'port_group_name', @@ -186,7 +186,7 @@ def test_valid_port_group(self, mock_get_host_ref): @mock.patch.object(vm_util, 'get_host_ref') def test_unknown_port_group(self, mock_get_host_ref): session = mock.Mock() - session._call_method.return_value = self._fake_port_groups() + session.call_method.return_value = self._fake_port_groups() vlanid, vswitch = network_util.get_vlanid_and_vswitch_for_portgroup( session, 'unknown_port_group', diff --git a/nova/tests/unit/virt/vmwareapi/test_vif.py b/nova/tests/unit/virt/vmwareapi/test_vif.py index 59b2937866e..d0c9a244aa2 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vif.py +++ b/nova/tests/unit/virt/vmwareapi/test_vif.py @@ -188,7 +188,7 @@ def fake_call_method(module, method, *args, **kwargs): with test.nested( mock.patch.object(vm_util, 'get_add_vswitch_port_group_spec'), mock.patch.object(vm_util, 'get_host_ref'), - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'call_method', fake_call_method) ) as (_add_vswitch, _get_host, _call_method): network_util.create_port_group(self.session, 'pg_name', @@ -203,7 +203,7 @@ def fake_call_method(module, method, *args, **kwargs): with test.nested( mock.patch.object(vm_util, 'get_add_vswitch_port_group_spec'), mock.patch.object(vm_util, 'get_host_ref'), - mock.patch.object(self.session, '_call_method', + mock.patch.object(self.session, 'call_method', fake_call_method) ) as (_add_vswitch, _get_host, _call_method): self.assertRaises(vexc.VMwareDriverException, diff --git a/nova/tests/unit/virt/vmwareapi/test_vm_util.py b/nova/tests/unit/virt/vmwareapi/test_vm_util.py index b2edaddc559..7513c684ea5 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vm_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_vm_util.py @@ -127,7 +127,7 @@ def fake_call_method(*args): raise Exception('unexpected method call') session = fake.FakeSession() - with mock.patch.object(session, '_call_method', fake_call_method): + with mock.patch.object(session, 'call_method', fake_call_method): result = vm_util.get_stats_from_cluster(session, "cluster1") if connection_state == "connected" and not maintenance_mode: num_hosts = 2 @@ -482,7 +482,7 @@ def test_get_vmdk_path_and_adapter_type(self): filename = '[test_datastore] uuid/uuid.vmdk' devices = self._vmdk_path_and_adapter_type_devices(filename) session = fake.FakeSession() - with mock.patch.object(session, '_call_method', return_value=devices): + with mock.patch.object(session, 'call_method', return_value=devices): vmdk = vm_util.get_vmdk_info(session, None) self.assertEqual(constants.ADAPTER_TYPE_LSILOGICSAS, vmdk.adapter_type) @@ -495,7 +495,7 @@ def test_get_vmdk_path_and_adapter_type_with_match(self): n_filename = '[test_datastore] uuid/uuid.vmdk' devices = self._vmdk_path_and_adapter_type_devices(n_filename) session = fake.FakeSession() - with mock.patch.object(session, '_call_method', return_value=devices): + with mock.patch.object(session, 'call_method', return_value=devices): vmdk = vm_util.get_vmdk_info(session, None, uuid='uuid') self.assertEqual(constants.ADAPTER_TYPE_LSILOGICSAS, vmdk.adapter_type) @@ -507,7 +507,7 @@ def test_get_vmdk_path_and_adapter_type_with_nomatch(self): n_filename = '[test_datastore] diuu/diuu.vmdk' session = fake.FakeSession() devices = self._vmdk_path_and_adapter_type_devices_nomatch(n_filename) - with mock.patch.object(session, '_call_method', return_value=devices): + with mock.patch.object(session, 'call_method', return_value=devices): vmdk = vm_util.get_vmdk_info(session, None, uuid='uuid') self.assertIsNone(vmdk.adapter_type) self.assertIsNone(vmdk.path) @@ -1194,9 +1194,9 @@ def fake_wait_for_task(self, *args): fake_call_mock = mock.Mock(side_effect=fake_call_method) fake_wait_mock = mock.Mock(side_effect=fake_wait_for_task) with test.nested( - mock.patch.object(session, '_wait_for_task', + mock.patch.object(session, 'wait_for_task', fake_wait_mock), - mock.patch.object(session, '_call_method', + mock.patch.object(session, 'call_method', fake_call_mock) ) as (wait_for_task, call_method): vm_ref = vm_util.create_vm( @@ -1258,9 +1258,9 @@ def test_convert_vif_model(self): def test_power_on_instance_with_vm_ref(self): session = fake.FakeSession() with test.nested( - mock.patch.object(session, "_call_method", + mock.patch.object(session, "call_method", return_value='fake-task'), - mock.patch.object(session, "_wait_for_task"), + mock.patch.object(session, "wait_for_task"), ) as (fake_call_method, fake_wait_for_task): vm_util.power_on_instance(session, 'fake-vm-ref') fake_call_method.assert_called_once_with(session.vim, @@ -1271,9 +1271,9 @@ def test_power_on_instance_with_vm_ref(self): def test_power_on_instance_with_exception(self): session = fake.FakeSession() with test.nested( - mock.patch.object(session, "_call_method", + mock.patch.object(session, "call_method", return_value='fake-task'), - mock.patch.object(session, "_wait_for_task", + mock.patch.object(session, "wait_for_task", side_effect=exception.NovaException('fake')), ) as (fake_call_method, fake_wait_for_task): self.assertRaises(exception.NovaException, @@ -1287,10 +1287,10 @@ def test_power_on_instance_with_exception(self): def test_power_on_instance_with_power_state_exception(self): session = fake.FakeSession() with test.nested( - mock.patch.object(session, "_call_method", + mock.patch.object(session, "call_method", return_value='fake-task'), mock.patch.object( - session, "_wait_for_task", + session, "wait_for_task", side_effect=vexc.InvalidPowerStateException), ) as (fake_call_method, fake_wait_for_task): vm_util.power_on_instance(session, 'fake-vm-ref') @@ -1305,9 +1305,9 @@ def test_create_virtual_disk(self): with test.nested( mock.patch.object(vm_util, "get_vmdk_create_spec", return_value='fake-spec'), - mock.patch.object(session, "_call_method", + mock.patch.object(session, "call_method", return_value='fake-task'), - mock.patch.object(session, "_wait_for_task"), + mock.patch.object(session, "wait_for_task"), ) as (fake_get_spec, fake_call_method, fake_wait_for_task): vm_util.create_virtual_disk(session, 'fake-dc-ref', 'fake-adapter-type', 'fake-disk-type', @@ -1329,9 +1329,9 @@ def test_copy_virtual_disk(self): session = fake.FakeSession() dm = session.vim.service_content.virtualDiskManager with test.nested( - mock.patch.object(session, "_call_method", + mock.patch.object(session, "call_method", return_value='fake-task'), - mock.patch.object(session, "_wait_for_task"), + mock.patch.object(session, "wait_for_task"), ) as (fake_call_method, fake_wait_for_task): vm_util.copy_virtual_disk(session, 'fake-dc-ref', 'fake-source', 'fake-dest') @@ -1352,9 +1352,9 @@ def _create_fake_vm_objects(self): def test_reconfigure_vm(self): session = fake.FakeSession() with test.nested( - mock.patch.object(session, '_call_method', + mock.patch.object(session, 'call_method', return_value='fake_reconfigure_task'), - mock.patch.object(session, '_wait_for_task') + mock.patch.object(session, 'wait_for_task') ) as (_call_method, _wait_for_task): vm_util.reconfigure_vm(session, 'fake-ref', 'fake-spec') _call_method.assert_called_once_with(mock.ANY, @@ -1650,9 +1650,9 @@ def test_get_network_detach_config_spec(self): def test_power_off_instance(self): session = fake.FakeSession() with test.nested( - mock.patch.object(session, '_call_method', + mock.patch.object(session, 'call_method', return_value='fake-task'), - mock.patch.object(session, '_wait_for_task') + mock.patch.object(session, 'wait_for_task') ) as (fake_call_method, fake_wait_for_task): vm_util.power_off_instance(session, 'fake-vm-ref') fake_call_method.assert_called_once_with(session.vim, @@ -1663,9 +1663,9 @@ def test_power_off_instance(self): def test_power_off_instance_with_exception(self): session = fake.FakeSession() with test.nested( - mock.patch.object(session, '_call_method', + mock.patch.object(session, 'call_method', return_value='fake-task'), - mock.patch.object(session, '_wait_for_task', + mock.patch.object(session, 'wait_for_task', side_effect=exception.NovaException('fake')) ) as (fake_call_method, fake_wait_for_task): self.assertRaises(exception.NovaException, @@ -1679,10 +1679,10 @@ def test_power_off_instance_with_exception(self): def test_power_off_instance_power_state_exception(self): session = fake.FakeSession() with test.nested( - mock.patch.object(session, '_call_method', + mock.patch.object(session, 'call_method', return_value='fake-task'), mock.patch.object( - session, '_wait_for_task', + session, 'wait_for_task', side_effect=vexc.InvalidPowerStateException) ) as (fake_call_method, fake_wait_for_task): vm_util.power_off_instance(session, 'fake-vm-ref') @@ -1969,7 +1969,7 @@ def test_get_swap(self): devices = [root_disk, swap_disk] session = fake.FakeSession() - with mock.patch.object(session, '_call_method', + with mock.patch.object(session, 'call_method', return_value=devices) as mock_call: device = vm_util.get_swap(session, vm_ref) @@ -1981,7 +1981,7 @@ def test_create_folder(self): """Test create_folder when the folder doesn't exist""" child_folder = mock.sentinel.child_folder session = fake.FakeSession() - with mock.patch.object(session, '_call_method', + with mock.patch.object(session, 'call_method', side_effect=[child_folder]): parent_folder = mock.sentinel.parent_folder parent_folder.value = 'parent-ref' @@ -1989,7 +1989,7 @@ def test_create_folder(self): ret = vm_util.create_folder(session, parent_folder, child_name) self.assertEqual(child_folder, ret) - session._call_method.assert_called_once_with(session.vim, + session.call_method.assert_called_once_with(session.vim, 'CreateFolder', parent_folder, name=child_name) @@ -1999,7 +1999,7 @@ def test_create_folder_duplicate_name(self): session = fake.FakeSession() details = {'object': 'folder-1'} duplicate_exception = vexc.DuplicateName(details=details) - with mock.patch.object(session, '_call_method', + with mock.patch.object(session, 'call_method', side_effect=[duplicate_exception]): parent_folder = mock.sentinel.parent_folder parent_folder.value = 'parent-ref' @@ -2008,7 +2008,7 @@ def test_create_folder_duplicate_name(self): self.assertEqual('Folder', ret._type) self.assertEqual('folder-1', ret.value) - session._call_method.assert_called_once_with(session.vim, + session.call_method.assert_called_once_with(session.vim, 'CreateFolder', parent_folder, name=child_name) @@ -2040,9 +2040,9 @@ def test_get_vm_name(self): def test_rename_vm(self, mock_get_name): session = fake.FakeSession() with test.nested( - mock.patch.object(session, '_call_method', + mock.patch.object(session, 'call_method', return_value='fake_rename_task'), - mock.patch.object(session, '_wait_for_task') + mock.patch.object(session, 'wait_for_task') ) as (_call_method, _wait_for_task): vm_util.rename_vm(session, 'fake-ref', self._instance) _call_method.assert_called_once_with(mock.ANY, diff --git a/nova/tests/unit/virt/vmwareapi/test_vmops.py b/nova/tests/unit/virt/vmwareapi/test_vmops.py index 8a5421ab919..82d13d9cd82 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vmops.py +++ b/nova/tests/unit/virt/vmwareapi/test_vmops.py @@ -268,8 +268,8 @@ def fake_call_method(module, method, *args, **kwargs): return 'fake_remove_snapshot_task' with test.nested( - mock.patch.object(self._session, '_wait_for_task'), - mock.patch.object(self._session, '_call_method', fake_call_method) + mock.patch.object(self._session, 'wait_for_task'), + mock.patch.object(self._session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): self._vmops._delete_vm_snapshot("fake_vm_snapshot") _wait_for_task.assert_has_calls([ @@ -294,8 +294,8 @@ def fake_call_method(module, method, *args, **kwargs): return task_info with test.nested( - mock.patch.object(self._session, '_wait_for_task'), - mock.patch.object(self._session, '_call_method', fake_call_method) + mock.patch.object(self._session, 'wait_for_task'), + mock.patch.object(self._session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): snap = self._vmops._create_vm_snapshot(self._instance, "fake_vm_ref") @@ -324,7 +324,7 @@ def test_get_info(self, mock_value_cache, mock_update_cached_instances, mock_get_vm_ref.return_value = vmwareapi_fake.ManagedObjectReference( value='test_id') - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', return_value=result): info = self._vmops.get_info(self._instance) mock_get_vm_ref.assert_called_once_with(self._session, @@ -339,7 +339,7 @@ def test_get_info_when_ds_unavailable(self, mock_get_vm_ref): } mock_get_vm_ref.return_value = vmwareapi_fake.ManagedObjectReference( value='fake_powered_off') - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', return_value=result): info = self._vmops.get_info(self._instance) mock_get_vm_ref.assert_called_once_with(self._session, @@ -369,7 +369,7 @@ def test_get_info_instance_deleted(self, mock_value_cache, def mock_call_method(module, method, *args, **kwargs): raise vexc.ManagedObjectNotFoundException() - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', mock_call_method): self.assertRaises(exception.InstanceNotFound, self._vmops.get_info, @@ -391,7 +391,7 @@ def _test_get_datacenter_ref_and_name(self, ds_ref_exists=False): result.add_object(vmwareapi_fake.Datacenter(ds_ref=None)) result.add_object(vmwareapi_fake.Datacenter()) - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', return_value=result) as fake_call: dc_info = _vcvmops.get_datacenter_ref_and_name(instance_ds_ref) @@ -499,7 +499,7 @@ def fake_call_method(module, method, *args, **kwargs): mock.patch.object(vm_util, 'power_on_instance'), mock.patch.object(vm_util, 'find_rescue_device'), mock.patch.object(vm_util, 'get_vm_ref', return_value=vm_ref), - mock.patch.object(self._session, '_call_method', + mock.patch.object(self._session, 'call_method', fake_call_method), mock.patch.object(vm_util, 'power_off_instance') ) as (_power_on_instance, _find_rescue, _get_vm_ref, @@ -571,7 +571,7 @@ def fake_call_method(module, method, *args, **kwargs): with test.nested( mock.patch.object(vm_util, 'get_vm_ref', return_value=vm_ref), - mock.patch.object(self._session, '_call_method', + mock.patch.object(self._session, 'call_method', side_effect=fake_call_method) ) as (mock_get_vm_ref, mock_call_method): result = self._vmops._clean_shutdown(instance, timeout, @@ -1430,8 +1430,8 @@ def test_manage_image_cache_templates(self, mock_get_avlbl_ds, mock.patch.object(self._vmops, '_get_image_template_vms', return_value=[(expired_templ_vm_ref, 'n1'), (used_templ_vm_ref, 'n2')]), - mock.patch.object(self._session, '_call_method'), - mock.patch.object(self._session, '_wait_for_task')): + mock.patch.object(self._session, 'call_method'), + mock.patch.object(self._session, 'wait_for_task')): self._vmops.manage_image_cache(self._context, fake_instances) mock_destroy_vm.assert_called_once_with(self._session, expired_templ_vm_ref) @@ -1788,7 +1788,7 @@ def test_get_ds_browser(self): moref = vmwareapi_fake.ManagedObjectReference(value='datastore-100') self.assertIsNone(cache.get(moref.value)) mock_call_method = mock.Mock(return_value=ds_browser) - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', mock_call_method): ret = self._vmops._get_ds_browser(moref) mock_call_method.assert_called_once_with(vutil, @@ -2050,8 +2050,8 @@ def _test_spawn(self, extra_specs = vm_util.ExtraSpecs() with test.nested( - mock.patch.object(self._session, '_wait_for_task'), - mock.patch.object(self._session, '_call_method', + mock.patch.object(self._session, 'wait_for_task'), + mock.patch.object(self._session, 'call_method', mock_call_method), mock.patch.object(uuidutils, 'generate_uuid', return_value='tmp-uuid'), @@ -2803,7 +2803,7 @@ def test_fetch_vsphere_image(self): mock.patch.object( self._session, 'invoke_api', side_effect=[datacenter_moref, fake_copy_task]), - mock.patch.object(self._session, '_wait_for_task')) as ( + mock.patch.object(self._session, 'wait_for_task')) as ( invoke_api, wait_for_task): self._vmops._fetch_vsphere_image(self._context, vi, image_ds_loc) expected_calls = [ @@ -3132,9 +3132,9 @@ def fake_call_method(module, method, *args, **kwargs): with test.nested( mock.patch.object(vm_util, "get_vm_ref", return_value='fake-vm-ref'), - mock.patch.object(self._session, "_call_method", + mock.patch.object(self._session, "call_method", fake_call_method), - mock.patch.object(self._session, "_wait_for_task") + mock.patch.object(self._session, "wait_for_task") ) as (_get_vm_ref, fake_call_method, _wait_for_task): self._vmops.reboot(self._instance, self.network_info, reboot_type) _get_vm_ref.assert_called_once_with(self._session, @@ -3251,7 +3251,7 @@ def test_detach_interface(self, mock_get_vm_ref, _network_api = mock.Mock() self._vmops._network_api = _network_api - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', return_value='hardware-devices'): self._vmops.detach_interface(self._context, self._instance, self._network_values) @@ -3274,7 +3274,7 @@ def test_get_mks_console(self, mock_get_vm_ref): ticket.ticket = 'fira' ticket.sslThumbprint = 'aa:bb:cc:dd:ee:ff' ticket.cfgFile = '[ds1] fira/foo.vmx' - with mock.patch.object(self._session, '_call_method', + with mock.patch.object(self._session, 'call_method', return_value=ticket): console = self._vmops.get_mks_console(self._instance) self.assertEqual('esx1', console.host) diff --git a/nova/tests/unit/virt/vmwareapi/test_volumeops.py b/nova/tests/unit/virt/vmwareapi/test_volumeops.py index b665f134152..7e7cdfa220d 100644 --- a/nova/tests/unit/virt/vmwareapi/test_volumeops.py +++ b/nova/tests/unit/virt/vmwareapi/test_volumeops.py @@ -72,8 +72,8 @@ def fake_call_method(module, method, *args, **kwargs): 'fileOperation')) return 'fake_configure_task' with test.nested( - mock.patch.object(self._session, '_wait_for_task'), - mock.patch.object(self._session, '_call_method', + mock.patch.object(self._session, 'wait_for_task'), + mock.patch.object(self._session, 'call_method', fake_call_method) ) as (_wait_for_task, _call_method): fake_device = vmwareapi_fake.DataObject() @@ -106,7 +106,7 @@ def test_get_volume_uuid(self): uuid = '1234' opt_val = vmwareapi_fake.OptionValue('volume-%s' % uuid, 'volume-val') fake_call = self._fake_call_get_object_property(uuid, opt_val) - with mock.patch.object(self._session, "_call_method", fake_call): + with mock.patch.object(self._session, "call_method", fake_call): val = self._volumeops._get_volume_uuid(vm_ref, uuid) self.assertEqual('volume-val', val) @@ -115,7 +115,7 @@ def test_get_volume_uuid_not_found(self): 'vm-134') uuid = '1234' fake_call = self._fake_call_get_object_property(uuid, None) - with mock.patch.object(self._session, "_call_method", fake_call): + with mock.patch.object(self._session, "call_method", fake_call): val = self._volumeops._get_volume_uuid(vm_ref, uuid) self.assertIsNone(val) @@ -178,7 +178,7 @@ def test_get_vmdk_backed_disk_device(self, get_vmdk_backed_disk_device, session = mock.Mock() self._volumeops._session = session hardware_devices = mock.sentinel.hardware_devices - session._call_method.return_value = hardware_devices + session.call_method.return_value = hardware_devices disk_uuid = mock.sentinel.disk_uuid get_volume_uuid.return_value = disk_uuid @@ -192,7 +192,7 @@ def test_get_vmdk_backed_disk_device(self, get_vmdk_backed_disk_device, vm_ref, connection_info['data']) self.assertEqual(device, ret) - session._call_method.assert_called_once_with( + session.call_method.assert_called_once_with( vutil, "get_object_property", vm_ref, "config.hardware.device") get_volume_uuid.assert_called_once_with( vm_ref, connection_info['data']['volume_id']) @@ -206,7 +206,7 @@ def test_get_vmdk_backed_disk_device_with_missing_disk_device( session = mock.Mock() self._volumeops._session = session hardware_devices = mock.sentinel.hardware_devices - session._call_method.return_value = hardware_devices + session.call_method.return_value = hardware_devices disk_uuid = mock.sentinel.disk_uuid get_volume_uuid.return_value = disk_uuid @@ -218,7 +218,7 @@ def test_get_vmdk_backed_disk_device_with_missing_disk_device( self.assertRaises(exception.DiskNotFound, self._volumeops._get_vmdk_backed_disk_device, vm_ref, connection_info['data']) - session._call_method.assert_called_once_with( + session.call_method.assert_called_once_with( vutil, "get_object_property", vm_ref, "config.hardware.device") get_volume_uuid.assert_called_once_with( vm_ref, connection_info['data']['volume_id']) @@ -247,7 +247,7 @@ def test_detach_volume_vmdk(self): return_value='fake-disk-type'), mock.patch.object(self._volumeops, '_consolidate_vmdk_volume'), mock.patch.object(self._volumeops, 'detach_disk_from_vm'), - mock.patch.object(self._volumeops._session, '_call_method', + mock.patch.object(self._volumeops._session, 'call_method', return_value=[virtual_controller]) ) as (get_vm_ref, get_volume_ref, get_vmdk_backed_disk_device, _get_device_disk_type, consolidate_vmdk_volume, @@ -303,7 +303,7 @@ def test_detach_volume_vmdk_invalid(self): return_value=virtual_disk), mock.patch.object(vm_util, 'get_vm_state', return_value=power_state.RUNNING), - mock.patch.object(self._volumeops._session, '_call_method', + mock.patch.object(self._volumeops._session, 'call_method', return_value=[virtual_controller]) ) as (get_vm_ref, get_volume_ref, get_vmdk_backed_disk_device, get_vm_state, session_call_method): @@ -336,7 +336,7 @@ def test_detach_volume_iscsi(self, detach_disk_from_vm, iscsi_get_target, session = mock.Mock() self._volumeops._session = session hardware_devices = mock.sentinel.hardware_devices - session._call_method.return_value = hardware_devices + session.call_method.return_value = hardware_devices device = mock.sentinel.device get_rdm_disk.return_value = device @@ -347,7 +347,7 @@ def test_detach_volume_iscsi(self, detach_disk_from_vm, iscsi_get_target, get_vm_ref.assert_called_once_with(session, instance) iscsi_get_target.assert_called_once_with(connection_info['data']) - session._call_method.assert_called_once_with( + session.call_method.assert_called_once_with( vutil, "get_object_property", vm_ref, "config.hardware.device") get_rdm_disk.assert_called_once_with(hardware_devices, disk_uuid) detach_disk_from_vm.assert_called_once_with( @@ -388,7 +388,7 @@ def test_detach_volume_iscsi_with_missing_disk_device( session = mock.Mock() self._volumeops._session = session hardware_devices = mock.sentinel.hardware_devices - session._call_method.return_value = hardware_devices + session.call_method.return_value = hardware_devices get_rdm_disk.return_value = None @@ -399,7 +399,7 @@ def test_detach_volume_iscsi_with_missing_disk_device( connection_info, instance) get_vm_ref.assert_called_once_with(session, instance) iscsi_get_target.assert_called_once_with(connection_info['data']) - session._call_method.assert_called_once_with( + session.call_method.assert_called_once_with( vutil, "get_object_property", vm_ref, "config.hardware.device") get_rdm_disk.assert_called_once_with(hardware_devices, disk_uuid) self.assertFalse(detach_disk_from_vm.called) @@ -627,7 +627,7 @@ def test_iscsi_get_host_iqn(self): with test.nested( mock.patch.object(vm_util, 'get_host_ref_for_vm', return_value=host_mor), - mock.patch.object(self._volumeops._session, '_call_method', + mock.patch.object(self._volumeops._session, 'call_method', return_value=hbas) ) as (fake_get_host_ref_for_vm, fake_call_method): result = self._volumeops._iscsi_get_host_iqn(self._instance) @@ -652,7 +652,7 @@ def test_iscsi_get_host_iqn_instance_not_found(self): side_effect=exception.InstanceNotFound('fake')), mock.patch.object(vm_util, 'get_host_ref', return_value=host_mor), - mock.patch.object(self._volumeops._session, '_call_method', + mock.patch.object(self._volumeops._session, 'call_method', return_value=hbas) ) as (fake_get_host_ref_for_vm, fake_get_host_ref, diff --git a/nova/virt/vmwareapi/cluster_util.py b/nova/virt/vmwareapi/cluster_util.py index fcf45c2db6b..e805fa53d3c 100644 --- a/nova/virt/vmwareapi/cluster_util.py +++ b/nova/virt/vmwareapi/cluster_util.py @@ -25,7 +25,7 @@ def reconfigure_cluster(session, cluster, config_spec): - reconfig_task = session._call_method(session.vim, + reconfig_task = session.call_method(session.vim, "ReconfigureComputeResource_Task", cluster, spec=config_spec, modify=True) @@ -102,7 +102,7 @@ def fetch_cluster_groups(session, cluster_ref=None, cluster_config=None, raise exception.ValidationError(msg) if cluster_config is None: - cluster_config = session._call_method( + cluster_config = session.call_method( vutil, "get_object_property", cluster_ref, "configurationEx") groups = {} @@ -130,7 +130,7 @@ def fetch_cluster_rules(session, cluster_ref=None, cluster_config=None): raise exception.ValidationError(msg) if cluster_config is None: - cluster_config = session._call_method( + cluster_config = session.call_method( vutil, "get_object_property", cluster_ref, "configurationEx") return {r.name: r for r in getattr(cluster_config, 'rule', [])} @@ -163,7 +163,7 @@ def update_vm_group_membership(session, cluster, vm_group_name, vm_ref, The assumption is that an administrator defines rules with other means on that group. """ - cluster_config = session._call_method( + cluster_config = session.call_method( vutil, "get_object_property", cluster, "configurationEx") client_factory = session.vim.client.factory @@ -286,7 +286,7 @@ def add_rule(session, cluster_ref, rule): def get_rule(session, cluster_ref, rule_name): """Get a DRS rule from the cluster by name""" - cluster_config = session._call_method( + cluster_config = session.call_method( vutil, "get_object_property", cluster_ref, "configurationEx") return _get_rule(cluster_config, rule_name) @@ -305,7 +305,7 @@ def get_rules_by_prefix(session, cluster_ref, rule_prefix): Useful, if you don't know the policy of a server-group the rule was created for. """ - cluster_config = session._call_method( + cluster_config = session.call_method( vutil, "get_object_property", cluster_ref, "configurationEx") return [rule for rule in getattr(cluster_config, 'rules', []) @@ -330,7 +330,7 @@ def update_rule(session, cluster_ref, rule): def is_drs_enabled(session, cluster): """Check if DRS is enabled on a given cluster""" - drs_config = session._call_method(vutil, "get_object_property", cluster, + drs_config = session.call_method(vutil, "get_object_property", cluster, "configuration.drsConfig") if drs_config and hasattr(drs_config, 'enabled'): return drs_config.enabled diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 1d592ecf6ab..38eadee833d 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -212,11 +212,11 @@ def cleanup_host(self, host): def _register_openstack_extension(self): # Register an 'OpenStack' extension in vCenter - os_extension = self._session._call_method(vim_util, 'find_extension', + os_extension = self._session.call_method(vim_util, 'find_extension', constants.EXTENSION_KEY) if os_extension is None: try: - self._session._call_method(vim_util, 'register_extension', + self._session.call_method(vim_util, 'register_extension', constants.EXTENSION_KEY, constants.EXTENSION_TYPE_INSTANCE) LOG.info('Registered extension %s with vCenter', @@ -335,7 +335,7 @@ def get_console_output(self, context, instance): def _get_vcenter_uuid(self): """Retrieves the vCenter UUID.""" - about = self._session._call_method(nova_vim_util, 'get_about_info') + about = self._session.call_method(nova_vim_util, 'get_about_info') return about.instanceUuid def _create_nodename(self, mo_id): @@ -397,12 +397,12 @@ def get_cluster_metrics(self): self.datastore_free_space = 0 self.datastore_total = 0 - cluster_data = self._session._call_method(vim_util, + cluster_data = self._session.call_method(vim_util, 'get_object_properties_dict', cluster_ref, ['host', 'datastore', 'summary']) for datastore in cluster_data['datastore'][0]: - datastore_capacity = self._session._call_method( + datastore_capacity = self._session.call_method( vim_util, "get_object_properties_dict", datastore, @@ -412,7 +412,7 @@ def get_cluster_metrics(self): self.datastore_total += datastore_capacity['summary.capacity'] for cluster_host in cluster_data['host'][0]: - props = self._session._call_method(vim_util, + props = self._session.call_method(vim_util, "get_object_properties_dict", cluster_host, lst_properties) diff --git a/nova/virt/vmwareapi/ds_util.py b/nova/virt/vmwareapi/ds_util.py index a2a4508e3a3..54e1256084f 100644 --- a/nova/virt/vmwareapi/ds_util.py +++ b/nova/virt/vmwareapi/ds_util.py @@ -113,7 +113,7 @@ def get_datastore(session, cluster, datastore_regex=None, storage_policy=None, allowed_ds_types=ALL_SUPPORTED_DS_TYPES): """Get the datastore list and choose the most preferable one.""" - datastore_ret = session._call_method(vutil, + datastore_ret = session.call_method(vutil, "get_object_property", cluster, "datastore") @@ -123,7 +123,7 @@ def get_datastore(session, cluster, datastore_regex=None, raise exception.DatastoreNotFound() datastore_mors = datastore_ret.ManagedObjectReference - result = session._call_method(vim_util, + result = session.call_method(vim_util, "get_properties_for_a_collection_of_objects", "Datastore", datastore_mors, ["summary.type", "summary.name", @@ -173,12 +173,12 @@ def get_available_datastores(session, cluster=None, datastore_regex=None, dc_ref=None): """Get the datastore list and choose the first local storage.""" if cluster: - ds = session._call_method(vutil, + ds = session.call_method(vutil, "get_object_property", cluster, "datastore") elif dc_ref: - ds = session._call_method(vutil, + ds = session.call_method(vutil, "get_object_property", dc_ref, "datastore") @@ -189,7 +189,7 @@ def get_available_datastores(session, cluster=None, datastore_regex=None, return [] data_store_mors = ds.ManagedObjectReference # NOTE(garyk): use utility method to retrieve remote objects - result = session._call_method(vim_util, + result = session.call_method(vim_util, "get_properties_for_a_collection_of_objects", "Datastore", data_store_mors, ["summary.type", "summary.name", "summary.accessible", @@ -207,7 +207,7 @@ def get_allowed_datastore_types(disk_type): def get_datacenter_ref(session, dc_path): - return session._call_method( + return session.call_method( session.vim, "FindByInventoryPath", session.vim.service_content.searchIndex, @@ -217,13 +217,13 @@ def get_datacenter_ref(session, dc_path): def file_delete(session, ds_path, dc_ref): LOG.debug("Deleting the datastore file %s", ds_path) vim = session.vim - file_delete_task = session._call_method( + file_delete_task = session.call_method( vim, "DeleteDatastoreFile_Task", vim.service_content.fileManager, name=str(ds_path), datacenter=dc_ref) - session._wait_for_task(file_delete_task) + session.wait_for_task(file_delete_task) LOG.debug("Deleted the datastore file") @@ -231,7 +231,7 @@ def file_copy(session, src_file, src_dc_ref, dst_file, dst_dc_ref): LOG.debug("Copying the datastore file from %(src)s to %(dst)s", {'src': src_file, 'dst': dst_file}) vim = session.vim - copy_task = session._call_method( + copy_task = session.call_method( vim, "CopyDatastoreFile_Task", vim.service_content.fileManager, @@ -239,7 +239,7 @@ def file_copy(session, src_file, src_dc_ref, dst_file, dst_dc_ref): sourceDatacenter=src_dc_ref, destinationName=dst_file, destinationDatacenter=dst_dc_ref) - session._wait_for_task(copy_task) + session.wait_for_task(copy_task) LOG.debug("Copied the datastore file") @@ -269,7 +269,7 @@ def disk_move(session, dc_ref, src_file, dst_file): """ LOG.debug("Moving virtual disk from %(src)s to %(dst)s.", {'src': src_file, 'dst': dst_file}) - move_task = session._call_method( + move_task = session.call_method( session.vim, "MoveVirtualDisk_Task", session.vim.service_content.virtualDiskManager, @@ -278,7 +278,7 @@ def disk_move(session, dc_ref, src_file, dst_file): destName=str(dst_file), destDatacenter=dc_ref, force=False) - session._wait_for_task(move_task) + session.wait_for_task(move_task) LOG.info("Moved virtual disk from %(src)s to %(dst)s.", {'src': src_file, 'dst': dst_file}) @@ -287,7 +287,7 @@ def disk_copy(session, dc_ref, src_file, dst_file): """Copies the source virtual disk to the destination.""" LOG.debug("Copying virtual disk from %(src)s to %(dst)s.", {'src': src_file, 'dst': dst_file}) - copy_disk_task = session._call_method( + copy_disk_task = session.call_method( session.vim, "CopyVirtualDisk_Task", session.vim.service_content.virtualDiskManager, @@ -296,7 +296,7 @@ def disk_copy(session, dc_ref, src_file, dst_file): destName=str(dst_file), destDatacenter=dc_ref, force=False) - session._wait_for_task(copy_disk_task) + session.wait_for_task(copy_disk_task) LOG.info("Copied virtual disk from %(src)s to %(dst)s.", {'src': src_file, 'dst': dst_file}) @@ -304,13 +304,13 @@ def disk_copy(session, dc_ref, src_file, dst_file): def disk_delete(session, dc_ref, file_path): """Deletes a virtual disk.""" LOG.debug("Deleting virtual disk %s", file_path) - delete_disk_task = session._call_method( + delete_disk_task = session.call_method( session.vim, "DeleteVirtualDisk_Task", session.vim.service_content.virtualDiskManager, name=str(file_path), datacenter=dc_ref) - session._wait_for_task(delete_disk_task) + session.wait_for_task(delete_disk_task) LOG.info("Deleted virtual disk %s.", file_path) @@ -341,7 +341,7 @@ def file_move(session, dc_ref, src_file, dst_file): LOG.debug("Moving file from %(src)s to %(dst)s.", {'src': src_file, 'dst': dst_file}) vim = session.vim - move_task = session._call_method( + move_task = session.call_method( vim, "MoveDatastoreFile_Task", vim.service_content.fileManager, @@ -349,7 +349,7 @@ def file_move(session, dc_ref, src_file, dst_file): sourceDatacenter=dc_ref, destinationName=str(dst_file), destinationDatacenter=dc_ref) - session._wait_for_task(move_task) + session.wait_for_task(move_task) LOG.debug("File moved") @@ -369,13 +369,13 @@ def file_exists(session, ds_browser, ds_path, file_name): """Check if the file exists on the datastore.""" client_factory = session.vim.client.factory search_spec = search_datastore_spec(client_factory, file_name) - search_task = session._call_method(session.vim, + search_task = session.call_method(session.vim, "SearchDatastore_Task", ds_browser, datastorePath=str(ds_path), searchSpec=search_spec) try: - task_info = session._wait_for_task(search_task) + task_info = session.wait_for_task(search_task) except vexc.FileNotFoundException: return False @@ -388,12 +388,12 @@ def file_size(session, ds_browser, ds_path, file_name): """Returns the size of the specified file.""" client_factory = session.vim.client.factory search_spec = search_datastore_spec(client_factory, file_name) - search_task = session._call_method(session.vim, + search_task = session.call_method(session.vim, "SearchDatastore_Task", ds_browser, datastorePath=str(ds_path), searchSpec=search_spec) - task_info = session._wait_for_task(search_task) + task_info = session.wait_for_task(search_task) if hasattr(task_info.result, 'file'): return task_info.result.file[0].fileSize @@ -404,7 +404,7 @@ def mkdir(session, ds_path, dc_ref): DataStore. """ LOG.debug("Creating directory with path %s", ds_path) - session._call_method(session.vim, "MakeDirectory", + session.call_method(session.vim, "MakeDirectory", session.vim.service_content.fileManager, name=str(ds_path), datacenter=dc_ref, createParentDirectories=True) @@ -416,13 +416,13 @@ def get_sub_folders(session, ds_browser, ds_path): If the path does not exist then an empty set is returned. """ - search_task = session._call_method( + search_task = session.call_method( session.vim, "SearchDatastore_Task", ds_browser, datastorePath=str(ds_path)) try: - task_info = session._wait_for_task(search_task) + task_info = session.wait_for_task(search_task) except vexc.FileNotFoundException: return set() # populate the folder entries @@ -489,7 +489,7 @@ def get_dc_info(session, ds_ref): """Get the datacenter name and the reference.""" dc_info = _DS_DC_MAPPING.get(ds_ref.value) if not dc_info: - dcs = session._call_method(vim_util, "get_objects", + dcs = session.call_method(vim_util, "get_objects", "Datacenter", ["name", "datastore", "vmFolder"]) _update_datacenter_cache_from_objects(session, dcs) dc_info = _DS_DC_MAPPING.get(ds_ref.value) @@ -508,7 +508,7 @@ def get_connected_hosts(session, datastore): :return: List of managed object references of all connected hosts """ - host_mounts = session._call_method(vutil, 'get_object_property', + host_mounts = session.call_method(vutil, 'get_object_property', datastore, 'host') if not hasattr(host_mounts, 'DatastoreHostMount'): return [] diff --git a/nova/virt/vmwareapi/host.py b/nova/virt/vmwareapi/host.py index ce9928cb855..ca90bed5270 100644 --- a/nova/virt/vmwareapi/host.py +++ b/nova/virt/vmwareapi/host.py @@ -72,7 +72,7 @@ def __init__(self, session, host_name, cluster, datastore_regex): except exception.ComputeHostNotFound: # this can happend on newly-added hosts self._auto_service_disabled = False - about_info = self._session._call_method(vim_util, "get_about_info") + about_info = self._session.call_method(vim_util, "get_about_info") self._hypervisor_type = about_info.name self._hypervisor_version = versionutils.convert_version_to_int( str(about_info.version)) diff --git a/nova/virt/vmwareapi/images.py b/nova/virt/vmwareapi/images.py index 06b06161dd6..147ad03a0ee 100644 --- a/nova/virt/vmwareapi/images.py +++ b/nova/virt/vmwareapi/images.py @@ -404,10 +404,10 @@ def _import_image(session, read_handle, vm_import_spec, vm_name, vm_folder_ref, imported_vm_ref = vm_ref break try: - destroy_task = session._call_method(session.vim, + destroy_task = session.call_method(session.vim, "Destroy_Task", vm_ref) - session._wait_for_task(destroy_task) + session.wait_for_task(destroy_task) except vexc.ManagedObjectNotFoundException: # another agent destroyed the VM in the meantime pass @@ -431,13 +431,13 @@ def _wait_for_import_task(session, vm_ref): waited = False try: - task_collector = session._call_method(session.vim, + task_collector = session.call_method(session.vim, "CreateCollectorForTasks", session.vim.service_content.taskManager, filter=task_filter_spec) while True: - page_tasks = session._call_method(session.vim, + page_tasks = session.call_method(session.vim, "ReadNextTasks", task_collector, maxCount=10) @@ -447,7 +447,7 @@ def _wait_for_import_task(session, vm_ref): for ti in page_tasks: if ti.descriptionId == "ResourcePool.ImportVAppLRO": try: - session._wait_for_task(ti.task) + session.wait_for_task(ti.task) waited = True except vexc.VimException as e: LOG.debug("Awaiting previous import on VM %s " @@ -458,7 +458,7 @@ def _wait_for_import_task(session, vm_ref): return waited finally: if task_collector: - session._call_method(session.vim, + session.call_method(session.vim, "DestroyCollector", task_collector) diff --git a/nova/virt/vmwareapi/network_util.py b/nova/virt/vmwareapi/network_util.py index fb80d022200..b78fc318538 100644 --- a/nova/virt/vmwareapi/network_util.py +++ b/nova/virt/vmwareapi/network_util.py @@ -74,7 +74,7 @@ def _get_network_obj(session, network_objects, network_name): for network in network_refs: # Get network properties if network._type == 'DistributedVirtualPortgroup': - props = session._call_method(vutil, + props = session.call_method(vutil, "get_object_property", network, "config") @@ -84,14 +84,14 @@ def _get_network_obj(session, network_objects, network_name): if network_name in net_name: network_obj['type'] = 'DistributedVirtualPortgroup' network_obj['dvpg'] = props.key - dvs_props = session._call_method(vutil, + dvs_props = session.call_method(vutil, "get_object_property", props.distributedVirtualSwitch, "uuid") network_obj['dvsw'] = dvs_props return network_obj else: - props = session._call_method(vutil, + props = session.call_method(vutil, "get_object_property", network, "summary.name") @@ -105,7 +105,7 @@ def get_network_with_the_name(session, network_name="vmnet0", cluster=None): """Gets reference to the network whose name is passed as the argument. """ - vm_networks = session._call_method(vim_util, + vm_networks = session.call_method(vim_util, 'get_object_properties', None, cluster, 'ClusterComputeResource', ['network']) @@ -124,7 +124,7 @@ def get_vswitch_for_vlan_interface(session, vlan_interface, cluster=None): """ # Get the list of vSwitches on the Host System host_mor = vm_util.get_host_ref(session, cluster) - vswitches_ret = session._call_method(vutil, + vswitches_ret = session.call_method(vutil, "get_object_property", host_mor, "config.network.vswitch") @@ -148,7 +148,7 @@ def get_vswitch_for_vlan_interface(session, vlan_interface, cluster=None): def check_if_vlan_interface_exists(session, vlan_interface, cluster=None): """Checks if the vlan_interface exists on the esx host.""" host_mor = vm_util.get_host_ref(session, cluster) - physical_nics_ret = session._call_method(vutil, + physical_nics_ret = session.call_method(vutil, "get_object_property", host_mor, "config.network.pnic") @@ -165,7 +165,7 @@ def check_if_vlan_interface_exists(session, vlan_interface, cluster=None): def get_vlanid_and_vswitch_for_portgroup(session, pg_name, cluster=None): """Get the vlan id and vswitch associated with the port group.""" host_mor = vm_util.get_host_ref(session, cluster) - port_grps_on_host_ret = session._call_method(vutil, + port_grps_on_host_ret = session.call_method(vutil, "get_object_property", host_mor, "config.network.portgroup") @@ -193,14 +193,14 @@ def create_port_group(session, pg_name, vswitch_name, vlan_id=0, cluster=None): pg_name, vlan_id) host_mor = vm_util.get_host_ref(session, cluster) - network_system_mor = session._call_method(vutil, + network_system_mor = session.call_method(vutil, "get_object_property", host_mor, "configManager.networkSystem") LOG.debug("Creating Port Group with name %s on " "the ESX host", pg_name) try: - session._call_method(session.vim, + session.call_method(session.vim, "AddPortGroup", network_system_mor, portgrp=add_prt_grp_spec) except vexc.AlreadyExistsException: diff --git a/nova/virt/vmwareapi/session.py b/nova/virt/vmwareapi/session.py index f98493427de..64c1722d6b4 100644 --- a/nova/virt/vmwareapi/session.py +++ b/nova/virt/vmwareapi/session.py @@ -54,7 +54,7 @@ def _is_vim_object(module): """Check if the module is a VIM Object instance.""" return isinstance(module, vim.Vim) - def _call_method(self, module, method, *args, **kwargs): + def call_method(self, module, method, *args, **kwargs): """Calls a method within the module specified with args provided. """ @@ -62,9 +62,3 @@ def _call_method(self, module, method, *args, **kwargs): return self.invoke_api(module, method, self.vim, *args, **kwargs) return self.invoke_api(module, method, *args, **kwargs) - - def _wait_for_task(self, task_ref): - """Return a Deferred that will give the result of the given task. - The task is polled until it completes. - """ - return self.wait_for_task(task_ref) diff --git a/nova/virt/vmwareapi/special_spawning.py b/nova/virt/vmwareapi/special_spawning.py index e0bd02fc50c..4befa92c49c 100644 --- a/nova/virt/vmwareapi/special_spawning.py +++ b/nova/virt/vmwareapi/special_spawning.py @@ -75,7 +75,7 @@ def __init__(self, driver): def _get_group(self, cluster_config=None): """Return the hostgroup or None if not found.""" if cluster_config is None: - cluster_config = self._session._call_method( + cluster_config = self._session.call_method( vutil, "get_object_property", self._cluster, "configurationEx") if not cluster_config: # that should never happen. we should not procede with whatever @@ -100,7 +100,7 @@ def _get_group(self, cluster_config=None): def _get_hosts_in_cluster(self, cluster_ref): """Return a list of HostSystem morefs belonging to the cluster""" - result = self._session._call_method( + result = self._session.call_method( vim_util, 'get_inner_objects', cluster_ref, 'host', 'HostSystem') with vutil.WithRetrieval(self._session.vim, result) as objects: return [obj.obj for obj in objects] @@ -108,7 +108,7 @@ def _get_hosts_in_cluster(self, cluster_ref): def _get_vms_on_host(self, host_ref): """Return a list of VMs uuids with their memory size and state""" vm_data = [] - vm_ret = self._session._call_method(vutil, + vm_ret = self._session.call_method(vutil, "get_object_property", host_ref, "vm") @@ -117,7 +117,7 @@ def _get_vms_on_host(self, host_ref): return vm_data vm_mors = vm_ret.ManagedObjectReference - result = self._session._call_method(vutil, + result = self._session.call_method(vutil, "get_properties_for_a_collection_of_objects", "VirtualMachine", vm_mors, ["config.instanceUuid", "runtime.powerState", @@ -183,7 +183,7 @@ def free_host(self, context): hostgroup. If that's already the case, return whether there are running VMs left on the host, i.e. the process is finished. """ - cluster_config = self._session._call_method( + cluster_config = self._session.call_method( vutil, "get_object_property", self._cluster, "configurationEx") # check if DRS is enabled, so freeing up can work @@ -252,7 +252,7 @@ def free_host(self, context): return FREE_HOST_STATE_ERROR # filter hosts which are in a wrong state - result = self._session._call_method(vim_util, + result = self._session.call_method(vim_util, "get_properties_for_a_collection_of_objects", "HostSystem", [host_objs[h] for h in vms_per_host], @@ -319,7 +319,7 @@ def free_host(self, context): 'host.') return FREE_HOST_STATE_ERROR - runtime_summary = self._session._call_method( + runtime_summary = self._session.call_method( vutil, "get_object_property", host_ref, 'summary.runtime') if (runtime_summary.inMaintenanceMode is True or runtime_summary.connectionState != "connected"): diff --git a/nova/virt/vmwareapi/vim_util.py b/nova/virt/vmwareapi/vim_util.py index d835f25f916..0d83bc141ac 100644 --- a/nova/virt/vmwareapi/vim_util.py +++ b/nova/virt/vmwareapi/vim_util.py @@ -162,7 +162,7 @@ def get_about_info(vim): def get_entity_name(session, entity): - return session._call_method(vutil, 'get_object_property', + return session.call_method(vutil, 'get_object_property', entity, 'name') diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 1a4f41a6e85..6139efceed2 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -140,11 +140,11 @@ def __iter__(self): self._page_items = None if self.reverse_page_order: - self.session._call_method(self.session.vim, + self.session.call_method(self.session.vim, "ResetCollector", self.history_collector) else: - self.session._call_method(self.session.vim, + self.session.call_method(self.session.vim, "RewindCollector", self.history_collector) @@ -164,7 +164,7 @@ def _load_page(self): self._load_latest_page() if not self._page_items: - self._page_items = self.session._call_method( + self._page_items = self.session.call_method( self.session.vim, self.read_page_method, self.history_collector, maxCount=self.max_page_size) @@ -182,7 +182,7 @@ def _load_latest_page(self): def destroy_collector(self): if self.history_collector: - self.session._call_method(self.session.vim, + self.session.call_method(self.session.vim, "DestroyCollector", self.history_collector) @@ -190,7 +190,7 @@ def destroy_collector(self): class TaskHistoryCollectorItems(HistoryCollectorItems): def __init__(self, session, task_filter_spec, reverse_page_order=False, max_page_size=10): - task_collector = session._call_method( + task_collector = session.call_method( session.vim, "CreateCollectorForTasks", session.vim.service_content.taskManager, @@ -212,7 +212,7 @@ def __del__(self): class EventHistoryCollectorItems(HistoryCollectorItems): def __init__(self, session, event_filter_spec, reverse_page_order=False, max_page_size=10): - event_collector = session._call_method( + event_collector = session.call_method( session.vim, "CreateCollectorForEvents", session.vim.service_content.eventManager, @@ -905,7 +905,7 @@ def _get_device_disk_type(device): def get_hardware_devices(session, vm_ref): - hardware_devices = session._call_method(vutil, + hardware_devices = session.call_method(vutil, "get_object_property", vm_ref, "config.hardware.device") @@ -1219,9 +1219,9 @@ def relocate_vm(session, vm_ref, res_pool=None, datastore=None, host=None, client_factory = session.vim.client.factory rel_spec = spec or relocate_vm_spec(client_factory, res_pool, datastore, host, disk_move_type) - relocate_task = session._call_method(session.vim, "RelocateVM_Task", + relocate_task = session.call_method(session.vim, "RelocateVM_Task", vm_ref, spec=rel_spec) - session._wait_for_task(relocate_task) + session.wait_for_task(relocate_task) def get_machine_id_change_spec(client_factory, machine_id_str): @@ -1297,7 +1297,7 @@ def _get_allocated_vnc_ports(session): # TODO(rgerganov): bug #1256944 # The VNC port should be unique per host, not per vCenter vnc_ports = set() - result = session._call_method(vim_util, "get_objects", + result = session.call_method(vim_util, "get_objects", "VirtualMachine", [VNC_CONFIG_KEY]) with vutil.WithRetrieval(session.vim, result) as objects: for obj in objects: @@ -1337,13 +1337,13 @@ def get_vm_ref_from_name(session, vm_name, base_obj=None, path=None): """ property_list = ["name"] if not base_obj: # Legacy: It doesn't scale - vms = session._call_method( + vms = session.call_method( vim_util, "get_objects", "VirtualMachine", property_list) else: if not path: raise ValueError("Method needs base_obj and path") - vms = session._call_method( + vms = session.call_method( vim_util, "get_inner_objects", base_obj, path, "VirtualMachine", property_list) @@ -1359,7 +1359,7 @@ def _get_vm_ref_from_vm_uuid(session, instance_uuid): instance_uuid, more specifically all VM's on the backend that have 'config_spec.instanceUuid' set to 'instance_uuid'. """ - vm_refs = session._call_method( + vm_refs = session.call_method( session.vim, "FindAllByUuid", session.vim.service_content.searchIndex, @@ -1371,7 +1371,7 @@ def _get_vm_ref_from_vm_uuid(session, instance_uuid): def find_by_inventory_path(session, inv_path): - return session._call_method( + return session.call_method( session.vim, "FindByInventoryPath", session.vim.service_content.searchIndex, @@ -1380,7 +1380,7 @@ def find_by_inventory_path(session, inv_path): def _get_vm_ref_from_extraconfig(session, instance_uuid): """Get reference to the VM with the uuid specified.""" - vms = session._call_method(vim_util, "get_objects", + vms = session.call_method(vim_util, "get_objects", "VirtualMachine", ['config.extraConfig["nvp.vm-uuid"]']) return _get_object_from_results(session, vms, instance_uuid, _get_object_for_optionvalue) @@ -1414,20 +1414,20 @@ def search_vm_ref_by_identifier(session, identifier): def get_host_ref_for_vm(session, vm_ref): """Get a MoRef to the ESXi host currently running an instance.""" - return session._call_method(vutil, "get_object_property", - vm_ref, "runtime.host") + return session.call_method(vutil, "get_object_property", + vm_ref, "runtime.host") def get_host_name_for_vm(session, vm_ref): """Get the hostname of the ESXi host currently running an instance.""" host_ref = get_host_ref_for_vm(session, vm_ref) - return session._call_method(vutil, "get_object_property", - host_ref, "name") + return session.call_method(vutil, "get_object_property", + host_ref, "name") def get_vm_state(session, vm_ref): - vm_state = session._call_method(vutil, "get_object_property", + vm_state = session.call_method(vutil, "get_object_property", vm_ref, "runtime.powerState") return constants.POWER_STATES[vm_state] @@ -1525,7 +1525,7 @@ def get_stats_from_cluster(session, cluster): get_hosts_and_reservations_for_cluster(session, cluster) if host_mors: - result = session._call_method(vim_util, + result = session.call_method(vim_util, "get_properties_for_a_collection_of_objects", "HostSystem", host_mors, ["summary.hardware", "summary.runtime", @@ -1592,7 +1592,7 @@ def get_hosts_and_reservations_for_cluster(session, cluster): props = ["host", "resourcePool", admission_policy_key] if CONF.vmware.hostgroup_reservations_json_file: props.append("configurationEx") - prop_dict = session._call_method(vutil, + prop_dict = session.call_method(vutil, "get_object_properties_dict", cluster, props) @@ -1619,13 +1619,13 @@ def get_hosts_and_reservations_for_cluster(session, cluster): def get_host_ref(session, cluster=None): """Get reference to a host within the cluster specified.""" if cluster is None: - results = session._call_method(vim_util, "get_objects", + results = session.call_method(vim_util, "get_objects", "HostSystem") - session._call_method(vutil, 'cancel_retrieval', + session.call_method(vutil, 'cancel_retrieval', results) host_mor = results.objects[0].obj else: - host_ret = session._call_method(vutil, "get_object_property", + host_ret = session.call_method(vutil, "get_object_property", cluster, "host") if not host_ret or not host_ret.ManagedObjectReference: msg = _('No host available on cluster') @@ -1674,7 +1674,7 @@ def get_vmdk_volume_disk(hardware_devices, path=None): def get_res_pool_ref(session, cluster): """Get the resource pool.""" # Get the root resource pool of the cluster - res_pool_ref = session._call_method(vutil, + res_pool_ref = session.call_method(vutil, "get_object_property", cluster, "resourcePool") @@ -1684,7 +1684,7 @@ def get_res_pool_ref(session, cluster): def get_all_cluster_mors(session): """Get all the clusters in the vCenter.""" try: - results = session._call_method(vim_util, "get_objects", + results = session.call_method(vim_util, "get_objects", "ClusterComputeResource", ["name"]) with vutil.WithRetrieval(session.vim, results) as objects: return list(objects) @@ -1719,12 +1719,12 @@ def get_vmdk_adapter_type(adapter_type): def create_vm(session, vm_folder, config_spec, res_pool_ref): """Create VM on ESX host.""" LOG.debug("Creating VM on the ESX host") - vm_create_task = session._call_method( + vm_create_task = session.call_method( session.vim, "CreateVM_Task", vm_folder, config=config_spec, pool=res_pool_ref) try: - task_info = session._wait_for_task(vm_create_task) + task_info = session.wait_for_task(vm_create_task) except vexc.VMwareDriverException: # An invalid guestId will result in an error with no specific fault # type and the generic error 'A specified parameter was not correct'. @@ -1748,9 +1748,9 @@ def destroy_vm(session, vm_ref): """Destroy a VM instance. Assumes VM is powered off.""" try: LOG.debug("Destroying the VM") - destroy_task = session._call_method(session.vim, "Destroy_Task", + destroy_task = session.call_method(session.vim, "Destroy_Task", vm_ref) - session._wait_for_task(destroy_task) + session.wait_for_task(destroy_task) LOG.info("Destroyed the VM") except vexc.VimFaultException as e: with excutils.save_and_reraise_exception() as ctx: @@ -1767,7 +1767,7 @@ def mark_vm_as_template(session, vm_ref): """Mark a VM instance as template. Assumes VM is powered off.""" try: LOG.debug("Marking the VM as template") - session._call_method(session.vim, "MarkAsTemplate", vm_ref) + session.call_method(session.vim, "MarkAsTemplate", vm_ref) LOG.info("Marked the VM as template") except Exception: LOG.exception(_('Mark VM as template failed')) @@ -1791,7 +1791,7 @@ def create_virtual_disk(session, dc_ref, adapter_type, disk_type, adapter_type, disk_type) - vmdk_create_task = session._call_method( + vmdk_create_task = session.call_method( session.vim, "CreateVirtualDisk_Task", session.vim.service_content.virtualDiskManager, @@ -1799,7 +1799,7 @@ def create_virtual_disk(session, dc_ref, adapter_type, disk_type, datacenter=dc_ref, spec=vmdk_create_spec) - session._wait_for_task(vmdk_create_task) + session.wait_for_task(vmdk_create_task) LOG.debug("Created Virtual Disk of size %(vmdk_file_size_in_kb)s" " KB and type %(disk_type)s", {"vmdk_file_size_in_kb": size_in_kb, @@ -1822,41 +1822,41 @@ def copy_virtual_disk(session, dc_ref, source, dest): LOG.debug("Copying Virtual Disk %(source)s to %(dest)s", {'source': source, 'dest': dest}) vim = session.vim - vmdk_copy_task = session._call_method( + vmdk_copy_task = session.call_method( vim, "CopyVirtualDisk_Task", vim.service_content.virtualDiskManager, sourceName=source, sourceDatacenter=dc_ref, destName=dest) - session._wait_for_task(vmdk_copy_task) + session.wait_for_task(vmdk_copy_task) LOG.debug("Copied Virtual Disk %(source)s to %(dest)s", {'source': source, 'dest': dest}) def reconfigure_vm(session, vm_ref, config_spec): """Reconfigure a VM according to the config spec.""" - reconfig_task = session._call_method(session.vim, + reconfig_task = session.call_method(session.vim, "ReconfigVM_Task", vm_ref, spec=config_spec) - session._wait_for_task(reconfig_task) + session.wait_for_task(reconfig_task) def power_on_instance(session, vm_ref): """Power on the specified instance.""" LOG.debug("Powering on the VM") try: - poweron_task = session._call_method( + poweron_task = session.call_method( session.vim, "PowerOnVM_Task", vm_ref) - session._wait_for_task(poweron_task) + session.wait_for_task(poweron_task) LOG.debug("Powered on the VM") except vexc.InvalidPowerStateException: LOG.debug("VM already powered on") def _get_vm_port_indices(session, vm_ref): - extra_config = session._call_method(vutil, + extra_config = session.call_method(vutil, 'get_object_property', vm_ref, 'config.extraConfig') @@ -1886,7 +1886,7 @@ def get_attach_port_index(session, vm_ref): def get_vm_detach_port_index(session, vm_ref, iface_id): - extra_config = session._call_method(vutil, + extra_config = session.call_method(vutil, 'get_object_property', vm_ref, 'config.extraConfig') @@ -1903,9 +1903,9 @@ def power_off_instance(session, vm_ref): LOG.debug("Powering off the VM") try: - poweroff_task = session._call_method(session.vim, + poweroff_task = session.call_method(session.vim, "PowerOffVM_Task", vm_ref) - session._wait_for_task(poweroff_task) + session.wait_for_task(poweroff_task) LOG.debug("Powered off the VM") except vexc.InvalidPowerStateException: LOG.debug("VM already powered off") @@ -1987,7 +1987,7 @@ def create_folder(session, parent_folder_ref, name): LOG.debug("Creating folder: %(name)s. Parent ref: %(parent)s.", {'name': name, 'parent': parent_folder_ref.value}) try: - folder = session._call_method(session.vim, "CreateFolder", + folder = session.call_method(session.vim, "CreateFolder", parent_folder_ref, name=name) LOG.info("Created folder: %(name)s in parent %(parent)s.", {'name': name, 'parent': parent_folder_ref.value}) @@ -2016,9 +2016,9 @@ def _get_vm_name(display_name, id_): def rename_vm(session, vm_ref, instance): vm_name = _get_vm_name(instance.display_name, instance.uuid) - rename_task = session._call_method(session.vim, "Rename_Task", vm_ref, + rename_task = session.call_method(session.vim, "Rename_Task", vm_ref, newName=vm_name) - session._wait_for_task(rename_task) + session.wait_for_task(rename_task) def create_service_locator_name_password(client_factory, username, password): diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 337ea06b972..0a0775a46bb 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -179,7 +179,7 @@ def _get_base_folder(self): def _extend_virtual_disk(self, requested_size, name, dc_ref): service_content = self._session.vim.service_content LOG.debug("Extending root virtual disk to %s", requested_size) - vmdk_extend_task = self._session._call_method( + vmdk_extend_task = self._session.call_method( self._session.vim, "ExtendVirtualDisk_Task", service_content.virtualDiskManager, @@ -188,7 +188,7 @@ def _extend_virtual_disk(self, requested_size, name, dc_ref): newCapacityKb=requested_size, eagerZero=False) try: - self._session._wait_for_task(vmdk_extend_task) + self._session.wait_for_task(vmdk_extend_task) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error('Extending virtual disk failed with error: %s', @@ -416,7 +416,7 @@ def _get_storage_policy(self, flavor): def _get_esx_host_and_cookies(self, datastore, dc_path, file_path): hosts = datastore.get_connected_hosts(self._session) host = ds_obj.Datastore.choose_host(hosts) - host_name = self._session._call_method(vutil, 'get_object_property', + host_name = self._session.call_method(vutil, 'get_object_property', host, 'name') url = ds_obj.DatastoreURL('https', host_name, file_path, dc_path, datastore.name) @@ -644,7 +644,7 @@ def _unregister_template_vm(self, templ_vm_ref): try: LOG.debug("Unregistering the template VM %s", templ_vm_ref.value) - self._session._call_method(self._session.vim, + self._session.call_method(self._session.vim, "UnregisterVM", templ_vm_ref) LOG.debug("Unregistered the template VM") except Exception as excep: @@ -764,7 +764,7 @@ def _fetch_image_from_other_datastores(self, vi): clone_spec = vm_util.clone_vm_spec(client_factory, rel_spec, template=True) - templ_vm_clone_task = self._session._call_method( + templ_vm_clone_task = self._session.call_method( self._session.vim, "CloneVM_Task", other_templ_vm_ref, @@ -776,7 +776,7 @@ def _fetch_image_from_other_datastores(self, vi): spec=clone_spec) try: task_info = \ - self._session._wait_for_task(templ_vm_clone_task) + self._session.wait_for_task(templ_vm_clone_task) except vexc.FileNotFoundException: LOG.warning("Could not find files for template VM %s", other_templ_vm_ref.value) @@ -983,7 +983,7 @@ def _create_image_template(self, context, vi, extra_specs): destroy_templ_exc) def _build_template_vm_inventory_path(self, vi): - vm_folder_name = self._session._call_method(vutil, + vm_folder_name = self._session.call_method(vutil, "get_object_property", vi.dc_info.vmFolder, "name") @@ -1053,7 +1053,7 @@ def _create_instance_from_image_template(self, context, res_pool=self._root_resource_pool, disk_move_type="moveAllDiskBackingsAndDisallowSharing") clone_spec = vm_util.clone_vm_spec(client_factory, rel_spec) - vm_clone_task = self._session._call_method( + vm_clone_task = self._session.call_method( self._session.vim, "CloneVM_Task", templ_vm_ref, @@ -1062,7 +1062,7 @@ def _create_instance_from_image_template(self, context, type_='Instances'), name=vi.instance.uuid, spec=clone_spec) - task_info = self._session._wait_for_task(vm_clone_task) + task_info = self._session.wait_for_task(vm_clone_task) vm_ref = task_info.result root_vmdk_info = vm_util.get_vmdk_info(self._session, @@ -1394,16 +1394,16 @@ def _attach_cdrom_to_vm(self, vm_ref, datastore, file_path): def _create_vm_snapshot(self, instance, vm_ref, image_id=None): LOG.debug("Creating Snapshot of the VM instance") - snapshot_task = self._session._call_method( + snapshot_task = self._session.call_method( self._session.vim, "CreateSnapshot_Task", vm_ref, name="%s-snapshot" % (image_id or instance.uuid), description="Taking Snapshot of the VM", memory=False, quiesce=True) - self._session._wait_for_task(snapshot_task) + self._session.wait_for_task(snapshot_task) LOG.debug("Created Snapshot of the VM instance") - task_info = self._session._call_method(vutil, + task_info = self._session.call_method(vutil, "get_object_property", snapshot_task, "info") @@ -1413,11 +1413,11 @@ def _create_vm_snapshot(self, instance, vm_ref, image_id=None): @retry_if_task_in_progress def _delete_vm_snapshot(self, snapshot): LOG.debug("Deleting Snapshot of the VM instance") - delete_snapshot_task = self._session._call_method( + delete_snapshot_task = self._session.call_method( self._session.vim, "RemoveSnapshot_Task", snapshot, removeChildren=False, consolidate=True) - self._session._wait_for_task(delete_snapshot_task) + self._session.wait_for_task(delete_snapshot_task) LOG.debug("Deleted Snapshot of the VM instance") def _create_vm_clone(self, instance, vm_ref, snapshot_ref, dc_info, @@ -1497,7 +1497,7 @@ def _create_vm_clone(self, instance, vm_ref, snapshot_ref, dc_info, config=config_spec) LOG.debug("Cloning VM %s", vm_name) - vm_clone_task = self._session._call_method( + vm_clone_task = self._session.call_method( self._session.vim, "CloneVM_Task", vm_ref, @@ -1506,9 +1506,9 @@ def _create_vm_clone(self, instance, vm_ref, snapshot_ref, dc_info, type_='Images'), name=vm_name, spec=clone_spec) - self._session._wait_for_task(vm_clone_task) + self._session.wait_for_task(vm_clone_task) LOG.info("Cloned VM %s", vm_name) - task_info = self._session._call_method(vutil, + task_info = self._session.call_method(vutil, "get_object_property", vm_clone_task, "info") @@ -1541,7 +1541,7 @@ def _get_vm_and_vmdk_attribs(): raise error_util.NoRootDiskDefined() lst_properties = ["datastore", "summary.config.guestId"] - props = self._session._call_method(vutil, + props = self._session.call_method(vutil, "get_object_properties_dict", vm_ref, lst_properties) @@ -1621,14 +1621,14 @@ def reboot(self, instance, network_info, reboot_type="SOFT"): tools_running_status == "guestToolsRunning" and reboot_type == "SOFT"): LOG.debug("Rebooting guest OS of VM") - self._session._call_method(self._session.vim, "RebootGuest", + self._session.call_method(self._session.vim, "RebootGuest", vm_ref) LOG.debug("Rebooted guest OS of VM") else: LOG.debug("Doing hard reboot of VM") - reset_task = self._session._call_method(self._session.vim, + reset_task = self._session.call_method(self._session.vim, "ResetVM_Task", vm_ref) - self._session._wait_for_task(reset_task) + self._session.wait_for_task(reset_task) LOG.debug("Did hard reboot of VM") def _destroy_instance(self, instance, destroy_disks=True): @@ -1637,7 +1637,7 @@ def _destroy_instance(self, instance, destroy_disks=True): vm_ref = vm_util.get_vm_ref(self._session, instance) lst_properties = ["config.files.vmPathName", "runtime.powerState", "datastore"] - props = self._session._call_method(vutil, + props = self._session.call_method(vutil, "get_object_properties_dict", vm_ref, lst_properties) @@ -1656,7 +1656,7 @@ def _destroy_instance(self, instance, destroy_disks=True): # Un-register the VM try: LOG.debug("Unregistering the VM") - self._session._call_method(self._session.vim, + self._session.call_method(self._session.vim, "UnregisterVM", vm_ref) LOG.debug("Unregistered the VM") except Exception as excep: @@ -1716,16 +1716,16 @@ def unpause(self, instance): def suspend(self, instance): """Suspend the specified instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) - pwr_state = self._session._call_method(vutil, + pwr_state = self._session.call_method(vutil, "get_object_property", vm_ref, "runtime.powerState") # Only PoweredOn VMs can be suspended. if pwr_state == "poweredOn": LOG.debug("Suspending the VM") - suspend_task = self._session._call_method(self._session.vim, + suspend_task = self._session.call_method(self._session.vim, "SuspendVM_Task", vm_ref) - self._session._wait_for_task(suspend_task) + self._session.wait_for_task(suspend_task) LOG.debug("Suspended the VM") # Raise Exception if VM is poweredOff elif pwr_state == "poweredOff": @@ -1738,16 +1738,16 @@ def suspend(self, instance): def resume(self, instance): """Resume the specified instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) - pwr_state = self._session._call_method(vutil, + pwr_state = self._session.call_method(vutil, "get_object_property", vm_ref, "runtime.powerState") if pwr_state.lower() == "suspended": LOG.debug("Resuming the VM") - suspend_task = self._session._call_method( + suspend_task = self._session.call_method( self._session.vim, "PowerOnVM_Task", vm_ref) - self._session._wait_for_task(suspend_task) + self._session.wait_for_task(suspend_task) LOG.debug("Resumed the VM") else: reason = _("instance is not in a suspended state") @@ -1866,7 +1866,7 @@ def _clean_shutdown(self, instance, timeout, retry_interval): LOG.debug("Soft shutdown instance, timeout: %d", timeout) - self._session._call_method(self._session.vim, + self._session.call_method(self._session.vim, "ShutdownGuest", vm_ref) @@ -1890,7 +1890,7 @@ def _clean_shutdown(self, instance, timeout, retry_interval): def is_instance_in_resource_pool(self, instance): try: vm_ref = vm_util.get_vm_ref(self._session, instance) - res_pool = self._session._call_method(vutil, "get_object_property", + res_pool = self._session.call_method(vutil, "get_object_property", vm_ref, "resourcePool") return vutil.get_moref_value(res_pool) == \ @@ -1913,7 +1913,7 @@ def _get_instance_props(self, vm_ref): if set(vm_props.keys()).issuperset(lst_properties): return vm_props else: - return self._session._call_method( + return self._session.call_method( vutil, "get_object_properties_dict", vm_ref, lst_properties) @@ -2409,7 +2409,7 @@ def _get_vm_props(session, instance): if CONF.vmware.use_property_collector: LOG.debug("VM instance data was not found on the cache.") - return session._call_method( + return session.call_method( vutil, "get_object_properties_dict", vm_ref, [powerstate_property]) @@ -2427,7 +2427,7 @@ def _get_diagnostics(self, instance): lst_properties = ["summary.config", "summary.quickStats", "summary.runtime"] - vm_props = self._session._call_method(vutil, + vm_props = self._session.call_method(vutil, "get_object_properties_dict", vm_ref, lst_properties) @@ -2466,7 +2466,7 @@ def get_instance_diagnostics(self, instance): def _get_vnc_console_connection(self, instance): """Return connection info for a vnc console.""" vm_ref = vm_util.get_vm_ref(self._session, instance) - opt_value = self._session._call_method(vutil, + opt_value = self._session.call_method(vutil, 'get_object_property', vm_ref, vm_util.VNC_CONFIG_KEY) @@ -2538,7 +2538,7 @@ def _get_and_set_vnc_config(self, client_factory, instance, vm_ref): def _get_ds_browser(self, ds_ref): ds_browser = self._datastore_browser_mapping.get(ds_ref.value) if not ds_browser: - ds_browser = self._session._call_method(vutil, + ds_browser = self._session.call_method(vutil, "get_object_property", ds_ref, "browser") @@ -3005,7 +3005,7 @@ def _list_instances_in_cluster(self, additional_properties=None, vutil.get_moref_value(self._cluster)) vms = [] if self._root_resource_pool: - vms = self._session._call_method( + vms = self._session.call_method( vim_util, 'get_inner_objects', self._root_resource_pool, 'vm', 'VirtualMachine', properties) return_properties = additional_properties is not None or include_moref @@ -3034,7 +3034,7 @@ def get_vnc_console(self, instance): def get_mks_console(self, instance): vm_ref = vm_util.get_vm_ref(self._session, instance) - ticket = self._session._call_method(self._session.vim, + ticket = self._session.call_method(self._session.vim, 'AcquireTicket', vm_ref, ticketType='mks') @@ -3069,7 +3069,7 @@ def update_cached_instances(self): if self._property_collector is None: pc = vim.service_content.propertyCollector - self._property_collector = self._session._call_method( + self._property_collector = self._session.call_method( self._session.vim, "CreatePropertyCollector", pc) vim.CreateFilter(self._property_collector, @@ -3419,6 +3419,6 @@ def place_vm(self, context, instance): if getattr(rule, "vmGroupName", None) == vm_group_name: placement_rules.append(rule) - result = self._session._call_method(self._session.vim, "PlaceVm", + result = self._session.call_method(self._session.vim, "PlaceVm", self._cluster, placementSpec=placement_spec) return result diff --git a/nova/virt/vmwareapi/volumeops.py b/nova/virt/vmwareapi/volumeops.py index 63e28117b5f..3ebf4cd0f8b 100644 --- a/nova/virt/vmwareapi/volumeops.py +++ b/nova/virt/vmwareapi/volumeops.py @@ -95,7 +95,7 @@ def _add_volume_details_to_config_spec(self, config_spec, volume_uuid, def _get_volume_uuid(self, vm_ref, volume_uuid): prop = 'config.extraConfig["volume-%s"]' % volume_uuid - opt_val = self._session._call_method(vutil, + opt_val = self._session.call_method(vutil, 'get_object_property', vm_ref, prop) @@ -138,7 +138,7 @@ def _iscsi_get_target(self, data): lst_properties = ["config.storageDevice.hostBusAdapter", "config.storageDevice.scsiTopology", "config.storageDevice.scsiLun"] - prop_dict = self._session._call_method(vutil, + prop_dict = self._session.call_method(vutil, "get_object_properties_dict", host_mor, lst_properties) @@ -208,19 +208,19 @@ def _iscsi_add_send_target_host(self, storage_system_mor, hba_device, send_tgt = client_factory.create('ns0:HostInternetScsiHbaSendTarget') (send_tgt.address, send_tgt.port) = target_portal.split(':') LOG.debug("Adding iSCSI host %s to send targets", send_tgt.address) - self._session._call_method( + self._session.call_method( self._session.vim, "AddInternetScsiSendTargets", storage_system_mor, iScsiHbaDevice=hba_device, targets=[send_tgt]) def _iscsi_rescan_hba(self, target_portal): """Rescan the iSCSI HBA to discover iSCSI targets.""" host_mor = vm_util.get_host_ref(self._session, self._cluster) - storage_system_mor = self._session._call_method( + storage_system_mor = self._session.call_method( vutil, "get_object_property", host_mor, "configManager.storageSystem") - hbas_ret = self._session._call_method( + hbas_ret = self._session.call_method( vutil, "get_object_property", storage_system_mor, @@ -248,7 +248,7 @@ def _iscsi_rescan_hba(self, target_portal): else: return LOG.debug("Rescanning HBA %s", hba_device) - self._session._call_method(self._session.vim, + self._session.call_method(self._session.vim, "RescanHba", storage_system_mor, hbaDevice=hba_device) LOG.debug("Rescanned HBA %s ", hba_device) @@ -288,7 +288,7 @@ def _iscsi_get_host_iqn(self, vm_ref): else: host_mor = vm_util.get_host_ref(self._session, self._cluster) - hbas_ret = self._session._call_method( + hbas_ret = self._session.call_method( vutil, "get_object_property", host_mor, @@ -404,18 +404,18 @@ def attach_volume(self, connection_info, instance, adapter_type=None): def _get_host_of_vm(self, vm_ref): """Get the ESX host of given VM.""" - return self._session._call_method(vutil, 'get_object_property', + return self._session.call_method(vutil, 'get_object_property', vm_ref, 'runtime').host def _get_res_pool_of_host(self, host): """Get the resource pool of given host's cluster.""" # Get the compute resource, the host belongs to - compute_res = self._session._call_method(vutil, + compute_res = self._session.call_method(vutil, 'get_object_property', host, 'parent') # Get resource pool from the compute resource - return self._session._call_method(vutil, + return self._session.call_method(vutil, 'get_object_property', compute_res, 'resourcePool') @@ -681,10 +681,10 @@ def delete_shadow_vms(self, block_device_info): try: data = connection_info["data"] volume_ref = self._get_volume_ref(data["volume"]) - destroy_task = session._call_method(session.vim, + destroy_task = session.call_method(session.vim, "Destroy_Task", volume_ref) - session._wait_for_task(destroy_task) + session.wait_for_task(destroy_task) deleted.append("{volume_id} ({volume})".format(**data)) except oslo_vmw_exceptions.ManagedObjectNotFoundException: LOG.debug("Volume %s already deleted", From f8699bb9b5c470d6b747d7f415eaeeedcc29aaa9 Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Wed, 3 Nov 2021 10:23:22 +0100 Subject: [PATCH 8/8] Vmware: StableMoRefProxy for MoRef recovery By encapsulating all the paramters for searching for the vm-ref again, we can move the retry logic to the session object, where we can try to recover the vm-ref should it result in a ManagedObjectNotFound exception Change-Id: Id382cadd685a635cc7a4a83f69b58075521c8771 --- nova/tests/unit/virt/vmwareapi/fake.py | 135 +++++++++------- .../unit/virt/vmwareapi/test_driver_api.py | 41 +++-- .../unit/virt/vmwareapi/test_vim_util.py | 6 +- .../tests/unit/virt/vmwareapi/test_vm_util.py | 4 +- nova/tests/unit/virt/vmwareapi/test_vmops.py | 70 +++++--- .../unit/virt/vmwareapi/test_volumeops.py | 24 ++- nova/virt/vmwareapi/driver.py | 2 +- nova/virt/vmwareapi/session.py | 52 +++++- nova/virt/vmwareapi/vm_util.py | 151 ++++++------------ nova/virt/vmwareapi/vmops.py | 90 +++++------ nova/virt/vmwareapi/volumeops.py | 16 +- 11 files changed, 321 insertions(+), 270 deletions(-) diff --git a/nova/tests/unit/virt/vmwareapi/fake.py b/nova/tests/unit/virt/vmwareapi/fake.py index 55286d21fa7..c827839c0e9 100644 --- a/nova/tests/unit/virt/vmwareapi/fake.py +++ b/nova/tests/unit/virt/vmwareapi/fake.py @@ -22,8 +22,9 @@ import collections import sys +import six + from oslo_log import log as logging -from oslo_serialization import jsonutils from oslo_utils import units from oslo_utils import uuidutils from oslo_vmware import exceptions as vexc @@ -79,20 +80,27 @@ def cleanup(): def _create_object(table, table_obj): """Create an object in the db.""" _db_content.setdefault(table, {}) - _db_content[table][table_obj.obj] = table_obj + _db_content[table][table_obj.obj.value] = table_obj -def _get_object(obj_ref): +def get_object(obj_ref): """Get object for the give reference.""" - return _db_content[obj_ref.type][obj_ref] + return _db_content[obj_ref.type][obj_ref.value] -def _get_objects(obj_type): +def get_objects(obj_type): """Get objects of the type.""" - lst_objs = FakeRetrieveResult() - for key in _db_content[obj_type]: - lst_objs.add_object(_db_content[obj_type][key]) - return lst_objs + return six.itervalues(_db_content[obj_type]) + + +def get_first_object(obj_type): + """Get the first object of an object type""" + return next(six.itervalues(_db_content[obj_type])) + + +def get_first_object_ref(obj_type): + """Get the first reference of an object type""" + return get_first_object(obj_type).obj def _convert_to_array_of_mor(mors): @@ -140,16 +148,14 @@ def add_object(self, object): def _get_object_refs(obj_type): - """Get object References of the type.""" - lst_objs = [] - for key in _db_content[obj_type]: - lst_objs.append(key) - return lst_objs + """Get iterator over object References of the type.""" + for obj in _db_content[obj_type].values(): + yield obj.obj def _update_object(table, table_obj): """Update objects of the type.""" - _db_content[table][table_obj.obj] = table_obj + _db_content[table][table_obj.obj.value] = table_obj class Prop(object): @@ -176,6 +182,9 @@ def __init__(self, name="ManagedObject", value=None): self.type = name self._type = name + def __repr__(self): + return "{}:{}".format(self._type, self.value) + class ObjectContent(object): """ObjectContent array holds dynamic properties.""" @@ -261,8 +270,11 @@ def _generate_moid(self, prefix): return prefix + "-" + str(self.__class__._counter) def __repr__(self): - return jsonutils.dumps({elem.name: elem.val - for elem in self.propSet}) + # We can't just dump the managed-object, because it may be circular + return "{}:{}({})".format(self.obj._type, self.obj.value, + ", ".join( + "{}={}".format(p.name, p.val if p.name == "name" else "<>") + for p in self.propSet)) class DataObject(object): @@ -592,8 +604,7 @@ def __init__(self, name="test_ResPool", value="resgroup-test"): class DatastoreHostMount(DataObject): def __init__(self, value='host-100'): super(DatastoreHostMount, self).__init__() - host_ref = (_db_content["HostSystem"] - [list(_db_content["HostSystem"].keys())[0]].obj) + host_ref = get_first_object_ref("HostSystem") host_system = DataObject() host_system.ManagedObjectReference = [host_ref] host_system.value = value @@ -609,6 +620,7 @@ def __init__(self, name="test_cluster"): self.set("host", None) self.set("datastore", None) self.set("resourcePool", None) + self.set("vm", []) summary = DataObject() summary.numHosts = 0 @@ -630,9 +642,15 @@ def __init__(self, name="test_cluster"): configuration.dasConfig.admissionControlPolicy = policy self.set("configuration.dasConfig.admissionControlPolicy", policy) + vm_list = DataObject() + vm_list.ManagedObjectReference = [] + self.set("vm", vm_list) + def _add_root_resource_pool(self, r_pool): if r_pool: self.set("resourcePool", r_pool) + pool = get_object(r_pool) + self.set("vm", pool.get("vm")) def _add_host(self, host_sys): if host_sys: @@ -668,7 +686,7 @@ def _update_summary(self): # Compute the aggregate stats summary.numHosts = len(hosts.ManagedObjectReference) for host_ref in hosts.ManagedObjectReference: - host_sys = _get_object(host_ref) + host_sys = get_object(host_ref) connected = host_sys.get("connected") host_summary = host_sys.get("summary") summary.numCpuCores += host_summary.hardware.numCpuCores @@ -726,14 +744,18 @@ def __init__(self, name="ha-host", connected=True, ds_ref=None, maintenance_mode=False): super(HostSystem, self).__init__("host") self.set("name", name) - if _db_content.get("HostNetworkSystem", None) is None: + + if not _db_content.get("HostNetworkSystem", None): create_host_network_system() - if not _get_object_refs('HostStorageSystem'): + + if not _db_content.get("HostStorageSystem", None): create_host_storage_system() - host_net_key = list(_db_content["HostNetworkSystem"].keys())[0] - host_net_sys = _db_content["HostNetworkSystem"][host_net_key].obj - self.set("configManager.networkSystem", host_net_sys) - host_storage_sys_key = _get_object_refs('HostStorageSystem')[0] + + host_net_obj = get_first_object("HostNetworkSystem") + host_net_ref = host_net_obj.obj + self.set("configManager.networkSystem", host_net_ref) + + host_storage_sys_key = get_first_object_ref('HostStorageSystem') self.set("configManager.storageSystem", host_storage_sys_key) if not ds_ref: @@ -813,10 +835,9 @@ def __init__(self, name="ha-host", connected=True, ds_ref=None, self.set("config.network.pnic", net_info_pnic) self.set("connected", connected) - if _db_content.get("Network", None) is None: + if not _db_content.get("Network", None): create_network() - net_ref = _db_content["Network"][ - list(_db_content["Network"].keys())[0]].obj + net_ref = get_first_object_ref("Network") network_do = DataObject() network_do.ManagedObjectReference = [net_ref] self.set("network", network_do) @@ -855,7 +876,7 @@ def __init__(self, name="ha-host", connected=True, ds_ref=None, self.set("config.storageDevice.hostBusAdapter", host_bus_adapter_array) # Set the same on the storage system managed object - host_storage_sys = _get_object(host_storage_sys_key) + host_storage_sys = get_object(host_storage_sys_key) host_storage_sys.set('storageDeviceInfo.hostBusAdapter', host_bus_adapter_array) @@ -918,15 +939,13 @@ def __init__(self, name="ha-datacenter", ds_ref=None): self.set("name", name) if _db_content.get("Folder", None) is None: create_folder() - folder_ref = _db_content["Folder"][ - list(_db_content["Folder"].keys())[0]].obj + folder_ref = get_first_object_ref("Folder") folder_do = DataObject() folder_do.ManagedObjectReference = [folder_ref] self.set("vmFolder", folder_ref) if _db_content.get("Network", None) is None: create_network() - net_ref = _db_content["Network"][ - list(_db_content["Network"].keys())[0]].obj + net_ref = get_first_object_ref("Network") network_do = DataObject() network_do.ManagedObjectReference = [net_ref] self.set("network", network_do) @@ -1004,8 +1023,10 @@ def create_network(): def create_cluster(name, ds_ref): cluster = ClusterComputeResource(name=name) - cluster._add_host(_get_object_refs("HostSystem")[0]) - cluster._add_host(_get_object_refs("HostSystem")[1]) + for i, host in enumerate(_get_object_refs("HostSystem")): + cluster._add_host(host) + if i >= 1: + break cluster._add_datastore(ds_ref) cluster._add_root_resource_pool(create_res_pool()) _create_object('ClusterComputeResource', cluster) @@ -1027,16 +1048,15 @@ def create_vm(uuid=None, name=None, devices = [] if vmPathName is None: - vm_path = ds_obj.DatastorePath( - list(_db_content['Datastore'].values())[0]) + vm_path = ds_obj.DatastorePath(get_first_object("Datastore")) else: vm_path = ds_obj.DatastorePath.parse(vmPathName) if res_pool_ref is None: - res_pool_ref = list(_db_content['ResourcePool'].keys())[0] + res_pool_ref = get_first_object_ref("ResourcePool") if host_ref is None: - host_ref = list(_db_content["HostSystem"].keys())[0] + host_ref = get_first_object_ref("HostSystem") # Fill in the default path to the vmx file if we were only given a # datastore. Note that if you create a VM with vmPathName '[foo]', when you @@ -1047,7 +1067,7 @@ def create_vm(uuid=None, name=None, for key, value in _db_content["Datastore"].items(): if value.get('summary.name') == vm_path.datastore: - ds = key + ds = value.obj break else: ds = create_datastore(vm_path.datastore, 1024, 500) @@ -1067,7 +1087,7 @@ def create_vm(uuid=None, name=None, vm = VirtualMachine(**vm_dict) _create_object("VirtualMachine", vm) - res_pool = _get_object(res_pool_ref) + res_pool = get_object(res_pool_ref) res_pool.vm.ManagedObjectReference.append(vm.obj) return vm.obj @@ -1140,10 +1160,10 @@ def _get_vm_mdo(vm_ref): """Gets the Virtual Machine with the ref from the db.""" if _db_content.get("VirtualMachine", None) is None: raise exception.NotFound("There is no VM registered") - if vm_ref not in _db_content.get("VirtualMachine"): + if vm_ref.value not in _db_content.get("VirtualMachine"): raise exception.NotFound("Virtual Machine with ref %s is not " - "there" % vm_ref) - return _db_content.get("VirtualMachine")[vm_ref] + "there" % vm_ref.value) + return _db_content.get("VirtualMachine")[vm_ref.value] def _merge_extraconfig(existing, changes): @@ -1394,11 +1414,10 @@ def _snapshot_vm(self, method): def _find_all_by_uuid(self, *args, **kwargs): uuid = kwargs.get('uuid') vm_refs = [] - for vm_ref in _db_content.get("VirtualMachine"): - vm = _get_object(vm_ref) + for vm in _db_content.get("VirtualMachine").values(): vm_uuid = vm.get("summary.config.instanceUuid") if vm_uuid == uuid: - vm_refs.append(vm_ref) + vm_refs.append(vm.obj) return vm_refs def _delete_snapshot(self, method, *args, **kwargs): @@ -1460,7 +1479,7 @@ def _unregister_vm(self, method, *args, **kwargs): """Unregisters a VM from the Host System.""" vm_ref = args[0] _get_vm_mdo(vm_ref) - del _db_content["VirtualMachine"][vm_ref] + del _db_content["VirtualMachine"][vm_ref.value] task_mdo = create_task(method, "success") return task_mdo.obj @@ -1534,10 +1553,10 @@ def _set_power_state(self, method, vm_ref, pwr_state="poweredOn"): if _db_content.get("VirtualMachine", None) is None: raise exception.NotFound("No Virtual Machine has been " "registered yet") - if vm_ref not in _db_content.get("VirtualMachine"): + vm_mdo = _db_content.get("VirtualMachine").get(vm_ref.value) + if not vm_mdo: raise exception.NotFound("Virtual Machine with ref %s is not " - "there" % vm_ref) - vm_mdo = _db_content.get("VirtualMachine").get(vm_ref) + "there" % vm_ref.value) vm_mdo.set("runtime.powerState", pwr_state) task_mdo = create_task(method, "success") return task_mdo.obj @@ -1566,7 +1585,8 @@ def _retrieve_properties(self, method, *args, **kwargs): # This means that we are retrieving props for all managed # data objects of the specified 'type' in the entire # inventory. This gets invoked by vim_util.get_objects. - mdo_refs = _db_content[spec_type] + mdo_refs = [obj.obj + for obj in _db_content[spec_type].values()] elif obj_ref.type != spec_type: # This means that we are retrieving props for the managed # data objects in the parent object's 'path' property. @@ -1576,7 +1596,7 @@ def _retrieve_properties(self, method, *args, **kwargs): # path = 'datastore' # the above will retrieve all datastores in the given # cluster. - parent_mdo = _db_content[obj_ref.type][obj_ref] + parent_mdo = _db_content[obj_ref.type][obj_ref.value] path = obj.selectSet[0].path mdo_refs = parent_mdo.get(path).ManagedObjectReference else: @@ -1586,7 +1606,7 @@ def _retrieve_properties(self, method, *args, **kwargs): mdo_refs = [obj_ref] for mdo_ref in mdo_refs: - mdo = _db_content[spec_type][mdo_ref] + mdo = _db_content[spec_type][mdo_ref.value] prop_list = [] for prop_name in properties: prop = Prop(prop_name, mdo.get(prop_name)) @@ -1600,14 +1620,13 @@ def _retrieve_properties(self, method, *args, **kwargs): def _add_port_group(self, method, *args, **kwargs): """Adds a port group to the host system.""" - _host_sk = list(_db_content["HostSystem"].keys())[0] - host_mdo = _db_content["HostSystem"][_host_sk] + host_mdo = get_first_object("HostSystem") host_mdo._add_port_group(kwargs.get("portgrp")) def _add_iscsi_send_tgt(self, method, *args, **kwargs): """Adds a iscsi send target to the hba.""" send_targets = kwargs.get('targets') - host_storage_sys = _get_objects('HostStorageSystem').objects[0] + host_storage_sys = get_first_object('HostStorageSystem') iscsi_hba_array = host_storage_sys.get('storageDeviceInfo' '.hostBusAdapter') iscsi_hba = iscsi_hba_array.HostHostBusAdapter[0] diff --git a/nova/tests/unit/virt/vmwareapi/test_driver_api.py b/nova/tests/unit/virt/vmwareapi/test_driver_api.py index 5b5a2b94d96..c1ecc9316c7 100644 --- a/nova/tests/unit/virt/vmwareapi/test_driver_api.py +++ b/nova/tests/unit/virt/vmwareapi/test_driver_api.py @@ -431,8 +431,8 @@ def _create_vm(self, node=None, num_instances=1, uuid=None, def _get_vm_record(self): # Get record for VM - vms = vmwareapi_fake._get_objects("VirtualMachine") - for vm in vms.objects: + vms = vmwareapi_fake.get_objects("VirtualMachine") + for vm in vms: if vm.get('name') == vm_util._get_vm_name(self._display_name, self.uuid): return vm @@ -1282,7 +1282,8 @@ def mock_upload_image(self, context, image, instance, session, **kwargs): def test_get_vm_ref_using_extra_config(self): self._create_vm() vm_ref = vm_util._get_vm_ref_from_extraconfig(self.conn._session, - self.instance['uuid']) + self.conn._cluster_ref, + self.instance['uuid']) self.assertIsNotNone(vm_ref, 'VM Reference cannot be none') # Disrupt the fake Virtual Machine object so that extraConfig # cannot be matched. @@ -1290,27 +1291,34 @@ def test_get_vm_ref_using_extra_config(self): fake_vm.get('config.extraConfig["nvp.vm-uuid"]').value = "" # We should not get a Virtual Machine through extraConfig. vm_ref = vm_util._get_vm_ref_from_extraconfig(self.conn._session, - self.instance['uuid']) + self.conn._cluster_ref, + self.instance['uuid']) self.assertIsNone(vm_ref, 'VM Reference should be none') # Check if we can find the Virtual Machine using the name. - vm_ref = vm_util.get_vm_ref(self.conn._session, self.instance) + vm_ref = vm_util.get_vm_ref(self.conn._session, self.conn._cluster_ref, + self.instance) self.assertIsNotNone(vm_ref, 'VM Reference cannot be none') @mock.patch.object(vmops.VMwareVMOps, 'update_cached_instances') def test_search_vm_ref_by_identifier(self, mock_update_cached_instances): self._create_vm() vm_ref = vm_util.search_vm_ref_by_identifier(self.conn._session, - self.instance['uuid']) + self.conn._cluster_ref, + self.instance['uuid']) self.assertIsNotNone(vm_ref, 'VM Reference cannot be none') fake_vm = self._get_vm_record() fake_vm.set("summary.config.instanceUuid", "foo") fake_vm.set("name", "foo") fake_vm.get('config.extraConfig["nvp.vm-uuid"]').value = "foo" self.assertIsNone(vm_util.search_vm_ref_by_identifier( - self.conn._session, self.instance['uuid']), + self.conn._session, + self.conn._cluster_ref, + self.instance['uuid']), "VM Reference should be none") self.assertIsNotNone( - vm_util.search_vm_ref_by_identifier(self.conn._session, "foo"), + vm_util.search_vm_ref_by_identifier(self.conn._session, + self.conn._cluster_ref, + "foo"), "VM Reference should not be none") def test_get_object_for_optionvalue(self): @@ -1607,7 +1615,8 @@ def test_resume_state_on_host_boot(self, mock_get_vm_ref, self.conn.resume_state_on_host_boot(self.context, self.instance, 'network_info') mock_get_vm_ref.assert_called_once_with(self.conn._session, - self.instance) + self.conn._cluster_ref, + self.instance) mock_get_vm_state.assert_called_once_with(self.conn._session, mock.sentinel.vm_ref) mock_reboot.assert_called_once_with(self.context, self.instance, @@ -1627,6 +1636,7 @@ def test_resume_state_on_host_boot_no_reboot(self): self.instance, 'network_info') mock_get_vm_ref.assert_called_once_with(self.conn._session, + self.conn._cluster_ref, self.instance) mock_get_vm_state.assert_called_once_with(self.conn._session, mock.sentinel.vm_ref) @@ -1964,6 +1974,7 @@ def test_attach_vmdk_disk_to_vm(self): '/dev/vdc') get_vm_ref.assert_called_once_with(self.conn._session, + self.conn._cluster_ref, self.instance) get_volume_ref.assert_called_once_with( connection_info['data']['volume']) @@ -2045,8 +2056,8 @@ def test_attach_iscsi_disk_to_vm(self): def test_iscsi_rescan_hba(self): fake_target_portal = 'fake_target_host:port' - host_storage_sys = vmwareapi_fake._get_objects( - "HostStorageSystem").objects[0] + host_storage_sys = vmwareapi_fake.get_first_object( + "HostStorageSystem") iscsi_hba_array = host_storage_sys.get('storageDeviceInfo' '.hostBusAdapter') iscsi_hba = iscsi_hba_array.HostHostBusAdapter[0] @@ -2054,7 +2065,8 @@ def test_iscsi_rescan_hba(self): self.assertRaises(AttributeError, getattr, iscsi_hba, 'configuredSendTarget') # Rescan HBA with the target portal - vops = volumeops.VMwareVolumeOps(self.conn._session) + vops = volumeops.VMwareVolumeOps(self.conn._session, + self.conn._cluster_ref) vops._iscsi_rescan_hba(fake_target_portal) # Check if HBA has the target portal configured self.assertEqual('fake_target_host', @@ -2066,9 +2078,10 @@ def test_iscsi_rescan_hba(self): def test_iscsi_get_target(self): data = {'target_portal': 'fake_target_host:port', 'target_iqn': 'fake_target_iqn'} - host = vmwareapi_fake._get_objects('HostSystem').objects[0] + host = vmwareapi_fake.get_first_object('HostSystem') host._add_iscsi_target(data) - vops = volumeops.VMwareVolumeOps(self.conn._session) + vops = volumeops.VMwareVolumeOps(self.conn._session, + self.conn._cluster_ref) result = vops._iscsi_get_target(data) self.assertEqual(('fake-device', 'fake-uuid'), result) diff --git a/nova/tests/unit/virt/vmwareapi/test_vim_util.py b/nova/tests/unit/virt/vmwareapi/test_vim_util.py index bdd9cf569d3..42b56fe2169 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vim_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_vim_util.py @@ -28,12 +28,12 @@ def setUp(self): def test_get_inner_objects(self): property = ['summary.name'] # Get the fake datastores directly from the cluster - cluster_refs = fake._get_object_refs('ClusterComputeResource') - cluster = fake._get_object(cluster_refs[0]) + cluster = fake.get_first_object('ClusterComputeResource') + cluster_ref = cluster.obj expected_ds = cluster.datastore.ManagedObjectReference # Get the fake datastores using inner objects utility method result = vim_util.get_inner_objects( - self.vim, cluster_refs[0], 'datastore', 'Datastore', property) + self.vim, cluster_ref, 'datastore', 'Datastore', property) datastores = [oc.obj for oc in result.objects] self.assertEqual(expected_ds, datastores) diff --git a/nova/tests/unit/virt/vmwareapi/test_vm_util.py b/nova/tests/unit/virt/vmwareapi/test_vm_util.py index 7513c684ea5..906189f9728 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vm_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_vm_util.py @@ -2068,7 +2068,7 @@ def setUp(self): self.session = VMwareAPISession() # Create a fake VirtualMachine running on a known host - self.host_ref = list(fake._db_content['HostSystem'].keys())[0] + self.host_ref = fake.get_first_object_ref("HostSystem") self.vm_ref = fake.create_vm(host_ref=self.host_ref) def test_get_host_ref_for_vm(self): @@ -2076,6 +2076,6 @@ def test_get_host_ref_for_vm(self): self.assertEqual(self.host_ref, ret) def test_get_host_name_for_vm(self): - host = fake._get_object(self.host_ref) + host = fake.get_object(self.host_ref) ret = vm_util.get_host_name_for_vm(self.session, self.vm_ref) self.assertEqual(host.name, ret) diff --git a/nova/tests/unit/virt/vmwareapi/test_vmops.py b/nova/tests/unit/virt/vmwareapi/test_vmops.py index 82d13d9cd82..01646f05065 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vmops.py +++ b/nova/tests/unit/virt/vmwareapi/test_vmops.py @@ -79,7 +79,8 @@ def setUp(self): self._virtapi = mock.Mock() self._image_id = nova.tests.unit.image.fake.get_valid_image_id() - fake_ds_ref = vmwareapi_fake.ManagedObjectReference(value='fake-ds') + fake_ds_ref = vmwareapi_fake.ManagedObjectReference(name='fake-ds', + value='Datastore') self._ds = ds_obj.Datastore( ref=fake_ds_ref, name='fake_ds', capacity=10 * units.Gi, @@ -87,9 +88,9 @@ def setUp(self): self._dc_info = ds_util.DcInfo( ref='fake_dc_ref', name='fake_dc', - vmFolder=vmwareapi_fake.ManagedObjectReference - (name='fake_vm_folder', - value='Folder')) + vmFolder=vmwareapi_fake.ManagedObjectReference( + name='fake_vm_folder', + value='Folder')) cluster = vmwareapi_fake.create_cluster('fake_cluster', fake_ds_ref) self._uuid = uuidsentinel.foo self._instance_values = { @@ -109,7 +110,7 @@ def setUp(self): root_gb=10, ephemeral_gb=0, swap=0, extra_specs={}) self._instance.flavor = self._flavor - self._volumeops = volumeops.VMwareVolumeOps(self._session) + self._volumeops = volumeops.VMwareVolumeOps(self._session, cluster.obj) self._vmops = vmops.VMwareVMOps(self._session, self._virtapi, self._volumeops, cluster=cluster.obj) @@ -328,7 +329,8 @@ def test_get_info(self, mock_value_cache, mock_update_cached_instances, return_value=result): info = self._vmops.get_info(self._instance) mock_get_vm_ref.assert_called_once_with(self._session, - self._instance) + self._cluster.obj, + self._instance) expected = hardware.InstanceInfo(state=power_state.RUNNING) self.assertEqual(expected, info) @@ -343,17 +345,19 @@ def test_get_info_when_ds_unavailable(self, mock_get_vm_ref): return_value=result): info = self._vmops.get_info(self._instance) mock_get_vm_ref.assert_called_once_with(self._session, - self._instance) + self._cluster.obj, + self._instance) self.assertEqual(hardware.InstanceInfo(state=power_state.SHUTDOWN), info) - @mock.patch.object(vm_util, 'get_vm_ref') + @mock.patch.object(vm_util, 'search_vm_ref_by_identifier') @mock.patch.object(vmops.VMwareVMOps, 'update_cached_instances') @mock.patch.object(vm_util, '_VM_VALUE_CACHE') def test_get_info_instance_deleted(self, mock_value_cache, mock_update_cached_instances, - mock_get_vm_ref): + mock_search_vm_ref): vm_util.vm_value_cache_reset() + vm_ref_value = mock.sentinel.missing_ref props = ['summary.config.numCpu', 'summary.config.memorySizeMB', 'runtime.powerState'] prop_cpu = vmwareapi_fake.Prop(props[0], 4) @@ -363,19 +367,25 @@ def test_get_info_instance_deleted(self, mock_value_cache, obj_content = vmwareapi_fake.ObjectContent(None, prop_list=prop_list) result = vmwareapi_fake.FakeRetrieveResult() result.add_object(obj_content) - mock_get_vm_ref.return_value = vmwareapi_fake.ManagedObjectReference( - value='fake_powered_off') + mock_search_vm_ref.side_effect = [ + vmwareapi_fake.ManagedObjectReference(value=vm_ref_value), + None + ] def mock_call_method(module, method, *args, **kwargs): - raise vexc.ManagedObjectNotFoundException() + raise vexc.ManagedObjectNotFoundException( + details={'obj': vm_ref_value} + ) - with mock.patch.object(self._session, 'call_method', + with mock.patch.object(vutil, 'get_object_properties_dict', mock_call_method): self.assertRaises(exception.InstanceNotFound, self._vmops.get_info, self._instance) - mock_get_vm_ref.assert_called_once_with(self._session, - self._instance) + mock_search_vm_ref.assert_has_calls(2 * [ + mock.call(self._session, + self._cluster.obj, + self._instance.uuid)]) def _test_get_datacenter_ref_and_name(self, ds_ref_exists=False): instance_ds_ref = mock.Mock() @@ -511,7 +521,9 @@ def fake_call_method(module, method, *args, **kwargs): vm_ref) else: self.assertFalse(_power_on_instance.called) + _get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, self._instance) _power_off.assert_called_once_with(self._session, vm_ref) _volumeops.detach_disk_from_vm.assert_called_once_with( @@ -579,6 +591,7 @@ def fake_call_method(module, method, *args, **kwargs): self.assertEqual(succeeds, result) mock_get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, self._instance) def test_clean_shutdown_first_time(self): @@ -657,7 +670,8 @@ def _test_finish_migration(self, power_on=True, self._instance.flavor.root_gb * units.Gi, 'fake-device') fake_get_vmdk_info.return_value = vmdk - vm_ref_calls = [mock.call(self._session, self._instance)] + vm_ref_calls = [mock.call(self._session, + self._cluster.obj, self._instance)] try: self._vmops.finish_migration(context=self._context, migration=migration, @@ -866,7 +880,9 @@ def _test_finish_revert_migration(self, fake_list_instances, except test.TestingException: pass - vm_ref_calls = [mock.call(self._session, self._instance)] + vm_ref_calls = [mock.call(self._session, + self._cluster.obj, + self._instance)] fake_power_off.assert_called_once_with(self._session, 'fake-ref') # Validate VM reconfiguration @@ -1190,6 +1206,7 @@ def test_confirm_migration(self, fake_get_vm_ref, fake_get_browser, self._instance, None) fake_get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, self._instance) fake_get_vmdk_info.assert_called_once_with( self._session, 'fake-ref', uuid=self._instance.uuid) @@ -1235,6 +1252,7 @@ def _test_migrate_disk_and_power_off(self, fake_get_vm_ref, fake_progress, flavor) fake_get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, self._instance) fake_power_off.assert_called_once_with(self._session, @@ -1316,6 +1334,7 @@ def test_finish_migration_root_block_device(self, fake_get_vm_ref, image_meta=self._image_meta, power_on=True) fake_get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, self._instance) fake_resize_create_eph_swap.assert_called_once_with( 'fake-ref', self._instance, None) @@ -2480,7 +2499,7 @@ def test_build_virtual_machine(self, mock_create_folder, self._metadata, None) - vm = vmwareapi_fake._get_object(vm_ref) + vm = vmwareapi_fake.get_object(vm_ref) # Test basic VM parameters self.assertEqual(self._instance.uuid, vm.name) @@ -2503,7 +2522,7 @@ def test_build_virtual_machine(self, mock_create_folder, datastores = vm.datastore.ManagedObjectReference self.assertEqual(1, len(datastores)) - datastore = vmwareapi_fake._get_object(datastores[0]) + datastore = vmwareapi_fake.get_object(datastores[0]) self.assertEqual(self._ds.name, datastore.get('summary.name')) # Test that the VM's network is configured as specified @@ -3138,6 +3157,7 @@ def fake_call_method(module, method, *args, **kwargs): ) as (_get_vm_ref, fake_call_method, _wait_for_task): self._vmops.reboot(self._instance, self.network_info, reboot_type) _get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, self._instance) if reboot_type == "HARD": _wait_for_task.assert_has_calls([ @@ -3225,7 +3245,9 @@ def test_attach_interface(self, mock_get_vm_ref, mock_extra_specs.return_value = extra_specs self._vmops.attach_interface(self._context, self._instance, self._image_meta, self._network_values) - mock_get_vm_ref.assert_called_once_with(self._session, self._instance) + mock_get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, + self._instance) mock_get_attach_port_index.assert_called_once_with(self._session, 'fake-ref') mock_get_network_attach_config_spec.assert_called_once_with( @@ -3255,7 +3277,9 @@ def test_detach_interface(self, mock_get_vm_ref, return_value='hardware-devices'): self._vmops.detach_interface(self._context, self._instance, self._network_values) - mock_get_vm_ref.assert_called_once_with(self._session, self._instance) + mock_get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, + self._instance) mock_get_detach_port_index.assert_called_once_with(self._session, 'fake-ref', None) mock_get_network_detach_config_spec.assert_called_once_with( @@ -3334,7 +3358,9 @@ def test_attach_interface_with_limits(self, mock_get_vm_ref, self._vmops.attach_interface(self._context, self._instance, self._image_meta, self._network_values) - mock_get_vm_ref.assert_called_once_with(self._session, self._instance) + mock_get_vm_ref.assert_called_once_with(self._session, + self._cluster.obj, + self._instance) mock_get_attach_port_index.assert_called_once_with(self._session, 'fake-ref') mock_get_network_attach_config_spec.assert_called_once_with( diff --git a/nova/tests/unit/virt/vmwareapi/test_volumeops.py b/nova/tests/unit/virt/vmwareapi/test_volumeops.py index 7e7cdfa220d..10ac0adbfad 100644 --- a/nova/tests/unit/virt/vmwareapi/test_volumeops.py +++ b/nova/tests/unit/virt/vmwareapi/test_volumeops.py @@ -41,8 +41,9 @@ def setUp(self): stubs.set_stubs(self) self._session = VMwareAPISession() self._context = context.RequestContext('fake_user', 'fake_project') - - self._volumeops = volumeops.VMwareVolumeOps(self._session) + self._cluster = mock.sentinel.cluster + self._volumeops = volumeops.VMwareVolumeOps(self._session, + self._cluster) self._image_id = image_fake.get_valid_image_id() self._instance_values = { 'name': 'fake_name', @@ -143,6 +144,7 @@ def test_attach_volume_vmdk_invalid(self): instance) get_vm_ref.assert_called_once_with(self._volumeops._session, + self._volumeops._cluster, instance) get_volume_ref.assert_called_once_with( connection_info['data']['volume']) @@ -264,6 +266,7 @@ def test_detach_volume_vmdk(self): self._volumeops._detach_volume_vmdk(connection_info, instance) get_vm_ref.assert_called_once_with(self._volumeops._session, + self._volumeops._cluster, instance) get_volume_ref.assert_called_once_with( connection_info['data']['volume']) @@ -312,6 +315,7 @@ def test_detach_volume_vmdk_invalid(self): instance) get_vm_ref.assert_called_once_with(self._volumeops._session, + self._volumeops._cluster, instance) get_volume_ref.assert_called_once_with( connection_info['data']['volume']) @@ -345,7 +349,7 @@ def test_detach_volume_iscsi(self, detach_disk_from_vm, iscsi_get_target, instance = mock.sentinel.instance self._volumeops._detach_volume_iscsi(connection_info, instance) - get_vm_ref.assert_called_once_with(session, instance) + get_vm_ref.assert_called_once_with(session, self._cluster, instance) iscsi_get_target.assert_called_once_with(connection_info['data']) session.call_method.assert_called_once_with( vutil, "get_object_property", vm_ref, "config.hardware.device") @@ -368,7 +372,9 @@ def test_detach_volume_iscsi_with_missing_iscsi_target( exception.StorageError, self._volumeops._detach_volume_iscsi, connection_info, instance) - get_vm_ref.assert_called_once_with(self._volumeops._session, instance) + get_vm_ref.assert_called_once_with(self._volumeops._session, + self._volumeops._cluster, + instance) iscsi_get_target.assert_called_once_with(connection_info['data']) @mock.patch.object(vm_util, 'get_vm_ref') @@ -397,7 +403,10 @@ def test_detach_volume_iscsi_with_missing_disk_device( self.assertRaises( exception.DiskNotFound, self._volumeops._detach_volume_iscsi, connection_info, instance) - get_vm_ref.assert_called_once_with(session, instance) + + get_vm_ref.assert_called_once_with(self._volumeops._session, + self._volumeops._cluster, + instance) iscsi_get_target.assert_called_once_with(connection_info['data']) session.call_method.assert_called_once_with( vutil, "get_object_property", vm_ref, "config.hardware.device") @@ -440,6 +449,7 @@ def _test_attach_volume_vmdk(self, adapter_type=None): adapter_type) get_vm_ref.assert_called_once_with(self._volumeops._session, + self._volumeops._cluster, self._instance) get_volume_ref.assert_called_once_with( connection_info['data']['volume']) @@ -478,6 +488,7 @@ def _test_attach_volume_iscsi(self, adapter_type=None): adapter_type) get_vm_ref.assert_called_once_with(self._volumeops._session, + self._volumeops._cluster, self._instance) iscsi_discover_target.assert_called_once_with( connection_info['data']) @@ -560,7 +571,7 @@ def test_consolidate_vmdk_volume_with_relocate( disk_type) get_vmdk_base_volume_device.assert_called_once_with(volume_ref) - relocate_vm.assert_called_once_with(self._session, + relocate_vm.assert_called_once_with(self._volumeops._session, volume_ref, rp, datastore, host) detach_disk_from_vm.assert_called_once_with( volume_ref, original_device, destroy_disk=True) @@ -684,6 +695,7 @@ def test_get_volume_connector(self): connector = self._volumeops.get_volume_connector(self._instance) fake_get_vm_ref.assert_called_once_with(self._volumeops._session, + self._volumeops._cluster, self._instance) fake_iscsi_get_host_iqn.assert_called_once_with(vm_ref) diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 38eadee833d..b9a9bf7293f 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -240,7 +240,7 @@ def resume_state_on_host_boot(self, context, instance, network_info, """resume guest state when a host is booted.""" # Check if the instance is running already and avoid doing # anything if it is. - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster_ref, instance) state = vm_util.get_vm_state(self._session, vm_ref) ignored_states = [power_state.RUNNING, power_state.SUSPENDED] if state in ignored_states: diff --git a/nova/virt/vmwareapi/session.py b/nova/virt/vmwareapi/session.py index 64c1722d6b4..5e159c4ab69 100644 --- a/nova/virt/vmwareapi/session.py +++ b/nova/virt/vmwareapi/session.py @@ -15,14 +15,43 @@ # License for the specific language governing permissions and limitations # under the License. +import abc +import six +import sys + from oslo_vmware import api +from oslo_vmware import exceptions as vexc from oslo_vmware import vim +from oslo_vmware.vim_util import get_moref_value import nova.conf - CONF = nova.conf.CONF +@six.add_metaclass(abc.ABCMeta) +class StableMoRefProxy(object): + """Abstract Basis class which acts as a proxy + for Managed-Object-References (MoRef). + Those references are usually "stable", meaning + they don't change over the life-time of the object. + + But usually doesn't mean always. In that case, we + need to fetch the reference again via some search method, + which uses a guaranteed stable identifier (names, uuids, ...) + """ + def __init__(self, ref): + self.moref = ref + + @abc.abstractmethod + def fetch_moref(self): + """Updates the moref field or raises + same exception the initial search would have + """ + + def __getattr__(self, name): + return getattr(self.moref, name) + + class VMwareAPISession(api.VMwareAPISession): """Sets up a session with the VC/ESX host and handles all the calls made to the host. @@ -58,7 +87,22 @@ def call_method(self, module, method, *args, **kwargs): """Calls a method within the module specified with args provided. """ - if not self._is_vim_object(module): - return self.invoke_api(module, method, self.vim, *args, **kwargs) + try: + if not self._is_vim_object(module): + return self.invoke_api(module, method, self.vim, + *args, **kwargs) + + return self.invoke_api(module, method, *args, **kwargs) + except vexc.ManagedObjectNotFoundException as monfe: + obj = monfe.details.get("obj") + any_change = False + for arg in args: + if (isinstance(arg, StableMoRefProxy) + and obj == get_moref_value(arg.moref)): + arg.fetch_moref() + any_change = True + + if not any_change: + six.reraise(*sys.exc_info()) - return self.invoke_api(module, method, *args, **kwargs) + return self.call_method(module, method, *args, **kwargs) diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 6139efceed2..d59bb0ebf28 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -40,6 +40,7 @@ from nova.i18n import _ from nova.network import model as network_model from nova.virt.vmwareapi import constants +from nova.virt.vmwareapi.session import StableMoRefProxy from nova.virt.vmwareapi import vim_util LOG = logging.getLogger(__name__) @@ -253,91 +254,16 @@ 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(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) - return vm_ref - - -def vm_ref_cache_from_instance(func): - @six.wraps(func) - def wrapper(session, instance): - id_ = instance.uuid - return _vm_ref_cache(id_, func, session, instance) - return wrapper - - -def vm_ref_cache_heal_from_instance(func): - """Decorator for a function working with a cached ManagedObject reference - for an instance - - Invalidates the cache in case of matching ManagedObjectNotFoundException - Most functions rely on the reference to be stable over the life-time of an - instance, and do not handle this exception, they expect InstanceNotFound - - By invalidating the cache, we solve two issues: - 1. We have a chance to recover from such a rare change - 2. If not, we now raise InstanceNotFound, which is actually handled - - The main motivator though is the live-vm migration across vcenters, - which can make the VM "disappear" - - An operator also can de-register and re-register a vm, or need to recover - the vsphere service, resulting in changed mo-refs, - requiring a restart to clear the cache. - - WARNING: Care needs to be taken in applying the decorator: - It requires, that the function in question is idempotent (up to the point - where the vm_ref is being used) - """ - @six.wraps(func) - def wrapper(session, instance, *args, **kwargs): - try: - return func(session, instance, *args, **kwargs) - except vexc.ManagedObjectNotFoundException as e: - with excutils.save_and_reraise_exception() as ctx: - id_ = instance.uuid - vm_ref = vm_ref_cache_get(id_) - # if there was nothing in the cache, there's nothing to heal - if vm_ref is None: - return # noqa - - # we are missing details about the issue, so raise it - if not e.details: - return # noqa - - obj = e.details.get("obj") - # A different moref may be invalid, nothing we can do about it - if obj != vm_ref.value: - return # noqa - - vm_ref_cache_delete(id_) - ctx.reraise = False - - # In case the reference has been passed - kw_vm_ref = kwargs.get("vm_ref", None) - if kw_vm_ref and kw_vm_ref.value == vm_ref.value: - kwargs.pop("vm_ref") - - # Unlikely, but we might run into the same situation again. - LOG.info("Trying to recover possible vm-ref incoherence") - return wrapper(session, instance, *args, **kwargs) - - return wrapper +def vm_ref_cache_get(id_): + return _VM_REFS_CACHE.get(id_) # the config key which stores the VNC port @@ -1328,6 +1254,12 @@ def _get_object_from_results(session, results, value, func): return func(objects, value) +def _get_vms_relative(session, base_obj, path, property_list): + return session.call_method(vim_util, "get_inner_objects", + base_obj, path, + "VirtualMachine", property_list) + + def get_vm_ref_from_name(session, vm_name, base_obj=None, path=None): """Get reference to the VM with the name specified. @@ -1336,16 +1268,10 @@ def get_vm_ref_from_name(session, vm_name, base_obj=None, path=None): It is far more optimal to use _get_vm_ref_from_vm_uuid. """ property_list = ["name"] - if not base_obj: # Legacy: It doesn't scale - vms = session.call_method( - vim_util, "get_objects", - "VirtualMachine", property_list) - else: - if not path: - raise ValueError("Method needs base_obj and path") - vms = session.call_method( - vim_util, "get_inner_objects", base_obj, path, - "VirtualMachine", property_list) + + if not path or not base_obj: + raise ValueError("Method needs base_obj and path") + vms = _get_vms_relative(session, base_obj, path, property_list) return _get_object_from_results(session, vms, vm_name, _get_object_for_value) @@ -1378,26 +1304,40 @@ def find_by_inventory_path(session, inv_path): inventoryPath=inv_path) -def _get_vm_ref_from_extraconfig(session, instance_uuid): +def _get_vm_ref_from_extraconfig(session, cluster, instance_uuid): """Get reference to the VM with the uuid specified.""" - vms = session.call_method(vim_util, "get_objects", - "VirtualMachine", ['config.extraConfig["nvp.vm-uuid"]']) + + vms = _get_vms_relative(session, cluster, "vm", + ['config.extraConfig["nvp.vm-uuid"]']) + return _get_object_from_results(session, vms, instance_uuid, _get_object_for_optionvalue) -@vm_ref_cache_from_instance -def get_vm_ref(session, instance): - """Get reference to the VM through uuid or vm name.""" - uuid = instance.uuid - vm_ref = (search_vm_ref_by_identifier(session, uuid) or - get_vm_ref_from_name(session, instance.name)) - if vm_ref is None: - raise exception.InstanceNotFound(instance_id=uuid) - return vm_ref +class StableVmRefUuid(StableMoRefProxy): + def __init__(self, session, cluster, uuid, moref=None): + super(StableVmRefUuid, self).__init__(moref) + self._session = session + self._cluster = cluster + self._uuid = uuid + if not moref: + self.fetch_moref() + + def fetch_moref(self): + vm_value_cache_delete(self._uuid) + self.moref = search_vm_ref_by_identifier(self._session, + self._cluster, self._uuid) + if not self.moref: + raise exception.InstanceNotFound(instance_id=self._uuid) + vm_ref_cache_update(self._uuid, self) + + +def get_vm_ref(session, cluster, instance): + """Get reference to the VM through uuid.""" + return StableVmRefUuid(session, cluster, instance.uuid) -def search_vm_ref_by_identifier(session, identifier): +def search_vm_ref_by_identifier(session, cluster, identifier): """Searches VM reference using the identifier. This method is primarily meant to separate out part of the logic for @@ -1406,8 +1346,7 @@ def search_vm_ref_by_identifier(session, identifier): use get_vm_ref instead. """ vm_ref = (_get_vm_ref_from_vm_uuid(session, identifier) or - _get_vm_ref_from_extraconfig(session, identifier) or - get_vm_ref_from_name(session, identifier)) + _get_vm_ref_from_extraconfig(session, cluster, identifier)) return vm_ref diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 0a0775a46bb..6d30f506375 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -1145,7 +1145,7 @@ def update_admin_vm_group_membership(self, instance, remove=False): vm_group_name = self._get_admin_group_name_for_instance(instance) if not vm_group_name: return - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) cluster_util.update_vm_group_membership(self._session, self._cluster, vm_group_name, vm_ref, remove=remove) @@ -1192,7 +1192,8 @@ def spawn(self, context, instance, image_meta, injected_files, # Cache the vm_ref. This saves a remote call to the VC. This uses the # instance uuid. - vm_util.vm_ref_cache_update(instance.uuid, vm_ref) + vm_util.vm_ref_cache_update(instance.uuid, vm_util.StableVmRefUuid( + self._session, self._cluster, instance.uuid, vm_ref)) # Update all DRS related rules self.update_cluster_placement(context, instance) @@ -1282,7 +1283,7 @@ def disable_drs_if_needed(self, instance): utils.is_large_vm(int(instance.memory_mb), instance.flavor): behavior = constants.DRS_BEHAVIOR_PARTIALLY_AUTOMATED LOG.debug("Adding DRS override '%s' for big VM.", behavior) - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) cluster_util.update_cluster_drs_vm_override(self._session, self._cluster, vm_ref, @@ -1530,7 +1531,7 @@ def snapshot(self, context, instance, image_id, update_task_state, 5. Delete the linked clone VM 6. Deletes the snapshot in original instance. """ - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) def _get_vm_and_vmdk_attribs(): # Get the vmdk info that the VM is pointing to @@ -1603,7 +1604,7 @@ def _get_vm_and_vmdk_attribs(): def reboot(self, instance, network_info, reboot_type="SOFT"): """Reboot a VM instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) props = self._get_instance_props(vm_ref) pwr_state = props.get('runtime.powerState') @@ -1634,7 +1635,7 @@ def reboot(self, instance, network_info, reboot_type="SOFT"): def _destroy_instance(self, instance, destroy_disks=True): # Destroy a VM instance try: - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) lst_properties = ["config.files.vmPathName", "runtime.powerState", "datastore"] props = self._session.call_method(vutil, @@ -1715,7 +1716,7 @@ def unpause(self, instance): def suspend(self, instance): """Suspend the specified instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) pwr_state = self._session.call_method(vutil, "get_object_property", vm_ref, @@ -1737,7 +1738,7 @@ def suspend(self, instance): def resume(self, instance): """Resume the specified instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) pwr_state = self._session.call_method(vutil, "get_object_property", vm_ref, @@ -1763,7 +1764,7 @@ def rescue(self, context, instance, network_info, image_meta): Attach the image that the instance was created from and boot from it. """ - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # Get the root disk vmdk object vmdk = vm_util.get_vmdk_info(self._session, vm_ref, @@ -1810,7 +1811,7 @@ def rescue(self, context, instance, network_info, image_meta): def unrescue(self, instance, power_on=True): """Unrescue the specified instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # Get the rescue device and detach it from the instance. try: rescue_device = self._get_rescue_device(instance, vm_ref) @@ -1837,7 +1838,7 @@ def power_off(self, instance, timeout=0, retry_interval=0): retry_interval): return - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) vm_util.power_off_instance(self._session, vm_ref) self.update_cached_instances() @@ -1852,7 +1853,7 @@ def _clean_shutdown(self, instance, timeout, retry_interval): False otherwise. """ LOG.debug("Performing Soft shutdown on instance") - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) props = self._get_instance_props(vm_ref) @@ -1889,7 +1890,7 @@ def _clean_shutdown(self, instance, timeout, retry_interval): def is_instance_in_resource_pool(self, instance): try: - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) res_pool = self._session.call_method(vutil, "get_object_property", vm_ref, "resourcePool") @@ -1918,7 +1919,7 @@ def _get_instance_props(self, vm_ref): vm_ref, lst_properties) def power_on(self, instance): - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) vm_util.power_on_instance(self._session, vm_ref) self.update_cached_instances() @@ -2039,7 +2040,7 @@ def migrate_disk_and_power_off(self, context, instance, dest, flavor): """Transfers the disk of a running instance in multiple phases, turning off the instance before the end. """ - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) vmdk = vm_util.get_vmdk_info(self._session, vm_ref, uuid=instance.uuid) @@ -2068,7 +2069,7 @@ def migrate_disk_and_power_off(self, context, instance, dest, flavor): def confirm_migration(self, migration, instance, network_info): """Confirms a resize, destroying the source VM.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) vmdk = vm_util.get_vmdk_info(self._session, vm_ref, uuid=instance.uuid) if not vmdk.device: @@ -2113,7 +2114,7 @@ def _revert_migration_update_disks(self, vm_ref, instance, vmdk, def finish_revert_migration(self, context, instance, network_info, block_device_info, power_on=True): """Finish reverting a resize.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # Ensure that the VM is off vm_util.power_off_instance(self._session, vm_ref) client_factory = self._session.vim.client.factory @@ -2159,7 +2160,7 @@ def finish_migration(self, context, migration, instance, disk_info, network_info, image_meta, resize_instance=False, block_device_info=None, power_on=True): """Completes a resize, turning on the migrated instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) flavor = instance.flavor boot_from_volume = compute_utils.is_volume_backed_instance(context, @@ -2315,7 +2316,7 @@ def moref(item): service["ssl_thumbprint"], ) - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) device_config_spec = [] relocate_spec.deviceChange = device_config_spec @@ -2399,31 +2400,22 @@ def get_info(self, instance): if not vm_util._VM_VALUE_CACHE: self.update_cached_instances() - @vm_util.vm_ref_cache_heal_from_instance - def _get_vm_props(session, instance): - vm_ref = vm_util.get_vm_ref(self._session, instance) - vm_props = vm_util._VM_VALUE_CACHE.get(vm_ref.value, {}) - if vm_props and powerstate_property in vm_props: - return vm_props - + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) + vm_props = vm_util._VM_VALUE_CACHE.get(vm_ref.value, {}) + if not vm_props or powerstate_property not in vm_props: if CONF.vmware.use_property_collector: LOG.debug("VM instance data was not found on the cache.") - return session.call_method( - vutil, "get_object_properties_dict", - vm_ref, [powerstate_property]) - - try: - vm_props = _get_vm_props(self._session, instance) - except vexc.ManagedObjectNotFoundException: - raise exception.InstanceNotFound(instance_id=instance.uuid) + vm_props = self._session.call_method(vutil, + "get_object_properties_dict", + vm_ref, [powerstate_property]) return hardware.InstanceInfo( state=constants.POWER_STATES[vm_props[powerstate_property]]) def _get_diagnostics(self, instance): """Return data about VM diagnostics.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) lst_properties = ["summary.config", "summary.quickStats", "summary.runtime"] @@ -2465,7 +2457,7 @@ def get_instance_diagnostics(self, instance): def _get_vnc_console_connection(self, instance): """Return connection info for a vnc console.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) opt_value = self._session.call_method(vutil, 'get_object_property', vm_ref, @@ -2512,7 +2504,7 @@ def _set_machine_id(self, client_factory, instance, network_info, and reconfigure the network interfaces. """ if vm_ref is None: - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) machine_id_change_spec = vm_util.get_machine_id_change_spec( client_factory, @@ -2770,7 +2762,7 @@ def _get_valid_vms_from_retrieve_result(self, retrieve_result, def instance_exists(self, instance): try: - vm_util.get_vm_ref(self._session, instance) + vm_util.get_vm_ref(self._session, self._cluster, instance) return True except exception.InstanceNotFound: return False @@ -2782,7 +2774,7 @@ def attach_interface(self, context, instance, image_meta, vif): vif_model = vm_util.convert_vif_model(vif_model) vif_info = vmwarevif.get_vif_dict(self._session, self._cluster, vif_model, utils.is_neutron(), vif) - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # Ensure that there is not a race with the port index management with lockutils.lock(instance.uuid, lock_file_prefix='nova-vmware-hot-plug'): @@ -2810,7 +2802,7 @@ def attach_interface(self, context, instance, image_meta, vif): def detach_interface(self, context, instance, vif): """Detach an interface from the instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # Ensure that there is not a race with the port index management with lockutils.lock(instance.uuid, lock_file_prefix='nova-vmware-hot-plug'): @@ -3022,7 +3014,7 @@ def get_vnc_console(self, instance): # a VNC proxy. Instead, you need to tell OpenStack to talk # directly to the ESX host running the VM you are attempting # to connect to via VNC. - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) vnc_console = self._get_vnc_console_connection(instance) host_name = vm_util.get_host_name_for_vm(self._session, vm_ref) vnc_console['host'] = host_name @@ -3033,7 +3025,7 @@ def get_vnc_console(self, instance): return ctype.ConsoleVNC(**vnc_console) def get_mks_console(self, instance): - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) ticket = self._session.call_method(self._session.vim, 'AcquireTicket', vm_ref, @@ -3108,7 +3100,9 @@ def update_cached_instances(self): instance_uuid = changes.get("config.instanceUuid") if update.kind == "enter": - vm_util.vm_ref_cache_update(instance_uuid, vm_ref) + vm_util.vm_ref_cache_update(instance_uuid, + vm_util.StableVmRefUuid(self._session, + self._cluster, instance_uuid, vm_ref)) elif update.kind == "modify": old_instance_uuid = values.get( "config.instanceUuid") @@ -3119,7 +3113,9 @@ def update_cached_instances(self): vm_util.vm_ref_cache_delete( old_instance_uuid) vm_util.vm_ref_cache_update( - instance_uuid, vm_ref) + instance_uuid, + vm_util.StableVmRefUuid(self._session, + self._cluster, instance_uuid, vm_ref)) values.update(changes) LOG.debug("%s.%s.%s -> %s", vm_ref["_type"], @@ -3176,7 +3172,8 @@ def update_vmref_cache(self): if vm_uuid != props.get('config.instanceUuid'): continue - vm_util.vm_ref_cache_update(vm_uuid, props['obj']) + vm_util.vm_ref_cache_update(vm_uuid, vm_util.StableVmRefUuid( + self._session, self._cluster, vm_uuid, props['obj'])) def set_compute_host(self, compute_host): """Called by the driver on init_host() so we know the compute host""" @@ -3295,7 +3292,8 @@ def _sync_sync_server_group(context, sg_uuid): continue try: - moref = vm_util.get_vm_ref(self._session, instance) + moref = vm_util.get_vm_ref(self._session, self._cluster, + instance) except exception.InstanceNotFound: LOG.warning('Could not find moref for instance %s. ' 'Ignoring member of server-group %s', diff --git a/nova/virt/vmwareapi/volumeops.py b/nova/virt/vmwareapi/volumeops.py index 3ebf4cd0f8b..5df63cecadf 100644 --- a/nova/virt/vmwareapi/volumeops.py +++ b/nova/virt/vmwareapi/volumeops.py @@ -36,7 +36,7 @@ class VMwareVolumeOps(object): """Management class for Volume-related tasks.""" - def __init__(self, session, cluster=None): + def __init__(self, session, cluster): self._session = session self._cluster = cluster @@ -311,7 +311,7 @@ def _get_connection_capabilities(self): def get_volume_connector(self, instance): """Return volume connector information.""" try: - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) except exception.InstanceNotFound: vm_ref = None iqn = self._iscsi_get_host_iqn(vm_ref) @@ -339,7 +339,7 @@ def _get_vmdk_base_volume_device(self, volume_ref): def _attach_volume_vmdk(self, connection_info, instance, adapter_type=None): """Attach vmdk volume storage to VM instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) LOG.debug("_attach_volume_vmdk: %s", connection_info) data = connection_info['data'] volume_ref = self._get_volume_ref(data['volume']) @@ -369,7 +369,7 @@ def _attach_volume_vmdk(self, connection_info, instance, def _attach_volume_iscsi(self, connection_info, instance, adapter_type=None): """Attach iscsi volume storage to VM instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # Attach Volume to VM LOG.debug("_attach_volume_iscsi: %s", connection_info) @@ -522,7 +522,7 @@ def _get_vmdk_backed_disk_device(self, vm_ref, connection_info_data): def _detach_volume_vmdk(self, connection_info, instance): """Detach volume storage to VM instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # Detach Volume from VM LOG.debug("_detach_volume_vmdk: %s", connection_info) data = connection_info['data'] @@ -558,7 +558,7 @@ def _detach_volume_vmdk(self, connection_info, instance): def _detach_volume_iscsi(self, connection_info, instance): """Detach volume storage to VM instance.""" - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # Detach Volume from VM LOG.debug("_detach_volume_iscsi: %s", connection_info) data = connection_info['data'] @@ -625,7 +625,7 @@ def fixup_shadow_vms(self, instance, shadow_vms): # This should sensibly moved out to cinder: # Cinder can delete the old shadow-vm, as soon as the attachment # for the vm prior the vmotion gets deleted - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) for device in vm_util.get_hardware_devices(self._session, vm_ref): class_name = device.__class__.__name__ @@ -704,7 +704,7 @@ def map_volumes_to_devices(self, instance, disk_infos): dicts to a a device by the stored volume_id """ remapped = {} - vm_ref = vm_util.get_vm_ref(self._session, instance) + vm_ref = vm_util.get_vm_ref(self._session, self._cluster, instance) # TODO(fwiesel) Create a function # _get_vmdk_backed_disk_devices (plural) # so we do not have two calls for each device