diff --git a/etc/nova/nova.conf.sample b/etc/nova/nova.conf.sample index 9a760cf3a63e..50f36d5f7d7a 100644 --- a/etc/nova/nova.conf.sample +++ b/etc/nova/nova.conf.sample @@ -3118,6 +3118,20 @@ #wsdl_location= +# +# Options defined in nova.virt.vmwareapi.vim_util +# + +# The maximum number of ObjectContent data objects that should +# be returned in a single result. A positive value will cause +# the operation to suspend the retrieval when the count of +# objects reaches the specified maximum. The server may still +# limit the count to something less than the configured value. +# Any remaining objects may be retrieved with additional +# requests. (integer value) +#maximum_objects=100 + + # # Options defined in nova.virt.vmwareapi.vmops # diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py index af3f83536f4b..1ee1b64168d0 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py @@ -175,7 +175,7 @@ class VMwareAPIVMTestCase(test.TestCase): # Get record for VM vms = vmwareapi_fake._get_objects("VirtualMachine") - vm = vms[0] + vm = vms.objects[0] # Check that m1.large above turned into the right thing. mem_kib = long(self.type_data['memory_mb']) << 10 @@ -521,10 +521,10 @@ class VMwareAPIVMTestCase(test.TestCase): def fake_get_vm_ref_from_name(session, vm_name): self.assertEquals(self.vm_name, vm_name) - return vmwareapi_fake._get_objects("VirtualMachine")[0] + return vmwareapi_fake._get_objects("VirtualMachine").objects[0] def fake_get_vm_ref_from_uuid(session, vm_uuid): - return vmwareapi_fake._get_objects("VirtualMachine")[0] + return vmwareapi_fake._get_objects("VirtualMachine").objects[0] def fake_call_method(*args, **kwargs): pass diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py index 0456dfecec75..df08ea28d644 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py @@ -42,8 +42,10 @@ class VMwareVMUtilTestCase(test.TestCase): fake.reset() def test_get_datastore_ref_and_name(self): + fake_objects = fake.FakeRetrieveResult() + fake_objects.add_object(fake.Datastore()) result = vm_util.get_datastore_ref_and_name( - fake_session([fake.Datastore()])) + fake_session(fake_objects)) self.assertEquals(result[1], "fake-ds") self.assertEquals(result[2], 1024 * 1024 * 1024 * 1024) @@ -66,9 +68,10 @@ class VMwareVMUtilTestCase(test.TestCase): fake_host_id = fake_host_sys.obj.value fake_host_name = "ha-host" - + fake_objects = fake.FakeRetrieveResult() + fake_objects.add_object(fake_host_sys) ref = vm_util.get_host_ref_from_id( - fake_session([fake_host_sys]), fake_host_id, ['name']) + fake_session(fake_objects), fake_host_id, ['name']) self.assertIsInstance(ref, fake.HostSystem) self.assertEqual(fake_host_id, ref.obj.value) @@ -84,9 +87,11 @@ class VMwareVMUtilTestCase(test.TestCase): "vm-123", "VirtualMachine")) fake_vm.propSet.append( fake.Property('name', 'vm-123')) + fake_objects = fake.FakeRetrieveResult() + fake_objects.add_object(fake_vm) vm_ref = vm_util.get_vm_ref_from_name( - fake_session([fake_vm]), 'vm-123') + fake_session(fake_objects), 'vm-123') self.assertIsNotNone(vm_ref) @@ -98,8 +103,12 @@ class VMwareVMUtilTestCase(test.TestCase): 'host-123', 'HostSystem')) ])] + fake_objects = fake.FakeRetrieveResult() + for results in fake_results: + fake_objects.add_object(results) + host_id = vm_util.get_host_id_from_vm_ref( - fake_session(fake_results), vm_ref) + fake_session(fake_objects), vm_ref) self.assertEqual('host-123', host_id) @@ -109,6 +118,7 @@ class VMwareVMUtilTestCase(test.TestCase): DynamicProperty = namedtuple('Property', ['name', 'val']) MoRef = namedtuple('Val', ['value']) + good_objects = fake.FakeRetrieveResult() results_good = [ ObjectContent(propSet=[ DynamicProperty(name='name', val=MoRef(value='vm-123'))]), @@ -121,7 +131,10 @@ class VMwareVMUtilTestCase(test.TestCase): ObjectContent(propSet=[ DynamicProperty( name='something', val=MoRef(value='thing'))]), ] + for result in results_good: + good_objects.add_object(result) + bad_objects = fake.FakeRetrieveResult() results_bad = [ ObjectContent(propSet=[ DynamicProperty(name='name', val=MoRef(value='vm-123'))]), @@ -131,22 +144,24 @@ class VMwareVMUtilTestCase(test.TestCase): ObjectContent(propSet=[ DynamicProperty( name='something', val=MoRef(value='thing'))]), ] + for result in results_bad: + bad_objects.add_object(result) prop = vm_util.property_from_property_set( - 'runtime.host', results_good) + 'runtime.host', good_objects) self.assertIsNotNone(prop) value = prop.val.value self.assertEqual('host-123', value) prop2 = vm_util.property_from_property_set( - 'runtime.host', results_bad) + 'runtime.host', bad_objects) self.assertIsNone(prop2) - prop3 = vm_util.property_from_property_set('foo', results_good) + prop3 = vm_util.property_from_property_set('foo', good_objects) self.assertIsNotNone(prop3) val3 = prop3.val.value self.assertEqual('bar1', val3) - prop4 = vm_util.property_from_property_set('foo', results_bad) + prop4 = vm_util.property_from_property_set('foo', bad_objects) self.assertIsNotNone(prop4) self.assertEqual('bar1', prop4.val) diff --git a/nova/virt/vmwareapi/error_util.py b/nova/virt/vmwareapi/error_util.py index 9527c51d1509..47655cd221ce 100644 --- a/nova/virt/vmwareapi/error_util.py +++ b/nova/virt/vmwareapi/error_util.py @@ -67,7 +67,7 @@ class FaultCheckers(object): @staticmethod def retrieveproperties_fault_checker(resp_obj): """ - Checks the RetrieveProperties response for errors. Certain faults + Checks the RetrievePropertiesEx response for errors. Certain faults are sent as part of the SOAP body as property of missingSet. For example NotAuthenticated fault. """ @@ -91,5 +91,5 @@ class FaultCheckers(object): if fault_list: exc_msg_list = ', '.join(fault_list) raise VimFaultException(fault_list, Exception(_("Error(s) %s " - "occurred in the call to RetrieveProperties") % + "occurred in the call to RetrievePropertiesEx") % exc_msg_list)) diff --git a/nova/virt/vmwareapi/fake.py b/nova/virt/vmwareapi/fake.py index 21d50fb78460..98172e0da597 100644 --- a/nova/virt/vmwareapi/fake.py +++ b/nova/virt/vmwareapi/fake.py @@ -77,12 +77,22 @@ def _create_object(table, table_obj): def _get_objects(obj_type): """Get objects of the type.""" - lst_objs = [] + lst_objs = FakeRetrieveResult() for key in _db_content[obj_type]: - lst_objs.append(_db_content[obj_type][key]) + lst_objs.add_object(_db_content[obj_type][key]) return lst_objs +class FakeRetrieveResult(object): + """Object to retrieve a ObjectContent list.""" + + def __init__(self): + self.objects = [] + + def add_object(self, object): + self.objects.append(object) + + class Property(object): """Property Object base class.""" @@ -317,16 +327,19 @@ class ClusterComputeResource(ManagedObject): super(ClusterComputeResource, self).__init__("ClusterComputeResource", value="domain-test") r_pool = DataObject() - r_pool.ManagedObjectReference = [_get_objects("ResourcePool")[0].obj] + obj = _get_objects("ResourcePool").objects[0].obj + r_pool.ManagedObjectReference = [obj] self.set("resourcePool", r_pool) host_sys = DataObject() - host_sys.ManagedObjectReference = [_get_objects("HostSystem")[0].obj] + obj = _get_objects("HostSystem").objects[0].obj + host_sys.ManagedObjectReference = [obj] self.set("host", host_sys) self.set("name", "test_cluster") datastore = DataObject() - datastore.ManagedObjectReference = [_get_objects("Datastore")[0].obj] + obj = _get_objects("Datastore").objects[0].obj + datastore.ManagedObjectReference = [obj] self.set("datastore", datastore) @@ -773,6 +786,14 @@ class FakeVim(object): task_mdo = create_task(method, "success") return task_mdo.obj + def _retrieve_properties_continue(self, method, *args, **kwargs): + """Continues the retrieve.""" + return FakeRetrieveResult() + + def _retrieve_properties_cancel(self, method, *args, **kwargs): + """Cancels the retrieve.""" + return None + def _retrieve_properties(self, method, *args, **kwargs): """Retrieves properties based on the type.""" spec_set = kwargs.get("specSet")[0] @@ -781,7 +802,7 @@ class FakeVim(object): if not isinstance(properties, list): properties = properties.split() objs = spec_set.objectSet - lst_ret_objs = [] + lst_ret_objs = FakeRetrieveResult() for obj in objs: try: obj_ref = obj.obj @@ -797,14 +818,14 @@ class FakeVim(object): temp_mdo = ManagedObject(mdo.objName, mdo.obj) for prop in properties: temp_mdo.set(prop, mdo.get(prop)) - lst_ret_objs.append(temp_mdo) + lst_ret_objs.add_object(temp_mdo) else: if obj_ref in _db_content[type]: mdo = _db_content[type][obj_ref] temp_mdo = ManagedObject(mdo.objName, obj_ref) for prop in properties: temp_mdo.set(prop, mdo.get(prop)) - lst_ret_objs.append(temp_mdo) + lst_ret_objs.add_object(temp_mdo) except Exception as exc: LOG.exception(exc) continue @@ -872,9 +893,15 @@ class FakeVim(object): elif attr_name == "MakeDirectory": return lambda *args, **kwargs: self._make_dir(attr_name, *args, **kwargs) - elif attr_name == "RetrieveProperties": + elif attr_name == "RetrievePropertiesEx": return lambda *args, **kwargs: self._retrieve_properties( attr_name, *args, **kwargs) + elif attr_name == "ContinueRetrievePropertiesEx": + return lambda *args, **kwargs: self._retrieve_properties_continue( + attr_name, *args, **kwargs) + elif attr_name == "CancelRetrievePropertiesEx": + return lambda *args, **kwargs: self._retrieve_properties_cancel( + attr_name, *args, **kwargs) elif attr_name == "AcquireCloneTicket": return lambda *args, **kwargs: self._just_return() elif attr_name == "AddPortGroup": diff --git a/nova/virt/vmwareapi/host.py b/nova/virt/vmwareapi/host.py index 4bba8f9f0d0b..3521ead4694b 100644 --- a/nova/virt/vmwareapi/host.py +++ b/nova/virt/vmwareapi/host.py @@ -35,8 +35,7 @@ class Host(object): def host_power_action(self, host, action): """Reboots or shuts down the host.""" - host_mor = self._session._call_method(vim_util, "get_objects", - "HostSystem")[0].obj + host_mor = vm_util.get_host_ref(self._session) LOG.debug(_("%(action)s %(host)s"), {'action': action, 'host': host}) if action == "reboot": host_task = self._session._call_method( @@ -59,8 +58,7 @@ class Host(object): """Start/Stop host maintenance window. On start, it triggers guest VMs evacuation. """ - host_mor = self._session._call_method(vim_util, "get_objects", - "HostSystem")[0].obj + host_mor = vm_util.get_host_ref(self._session) LOG.debug(_("Set maintenance mod on %(host)s to %(mode)s"), {'host': host, 'mode': mode}) if mode: @@ -103,8 +101,7 @@ class HostState(object): def update_status(self): """Update the current state of the host. """ - host_mor = self._session._call_method(vim_util, "get_objects", - "HostSystem")[0].obj + host_mor = vm_util.get_host_ref(self._session) summary = self._session._call_method(vim_util, "get_dynamic_property", host_mor, diff --git a/nova/virt/vmwareapi/vim_util.py b/nova/virt/vmwareapi/vim_util.py index e131e007d77f..885b19999db4 100644 --- a/nova/virt/vmwareapi/vim_util.py +++ b/nova/virt/vmwareapi/vim_util.py @@ -19,6 +19,22 @@ The VMware API utility module. """ +from oslo.config import cfg + + +vmware_opts = cfg.IntOpt('maximum_objects', default=100, + help='The maximum number of ObjectContent data ' + 'objects that should be returned in a single ' + 'result. A positive value will cause the ' + 'operation to suspend the retrieval when the ' + 'count of objects reaches the specified ' + 'maximum. The server may still limit the count ' + 'to something less than the configured value. ' + 'Any remaining objects may be retrieved with ' + 'additional requests.') +CONF = cfg.CONF +CONF.register_opt(vmware_opts, 'vmware') + def build_selection_spec(client_factory, name): """Builds the selection spec.""" @@ -143,15 +159,20 @@ def get_object_properties(vim, collector, mobj, type, properties): object_spec.skip = False property_filter_spec.propSet = [property_spec] property_filter_spec.objectSet = [object_spec] - return vim.RetrieveProperties(usecoll, specSet=[property_filter_spec]) + options = client_factory.create('ns0:RetrieveOptions') + options.maxObjects = CONF.vmware.maximum_objects + return vim.RetrievePropertiesEx(usecoll, specSet=[property_filter_spec], + options=options) def get_dynamic_property(vim, mobj, type, property_name): """Gets a particular property of the Managed Object.""" obj_content = get_object_properties(vim, None, mobj, type, [property_name]) + if hasattr(obj_content, 'token'): + vim.CancelRetrievePropertiesEx(token=obj_content.token) property_value = None - if obj_content: - dynamic_property = obj_content[0].propSet + if obj_content.objects: + dynamic_property = obj_content.objects[0].propSet if dynamic_property: property_value = dynamic_property[0].val return property_value @@ -172,8 +193,25 @@ def get_objects(vim, type, properties_to_collect=None, all=False): property_filter_spec = build_property_filter_spec(client_factory, [property_spec], [object_spec]) - return vim.RetrieveProperties(vim.get_service_content().propertyCollector, - specSet=[property_filter_spec]) + options = client_factory.create('ns0:RetrieveOptions') + options.maxObjects = CONF.vmware.maximum_objects + return vim.RetrievePropertiesEx( + vim.get_service_content().propertyCollector, + specSet=[property_filter_spec], options=options) + + +def cancel_retrieve(vim, token): + """Cancels the retrieve operation.""" + return vim.CancelRetrievePropertiesEx( + vim.get_service_content().propertyCollector, + token=token) + + +def continue_to_get_objects(vim, token): + """Continues to get the list of objects of the type specified.""" + return vim.ContinueRetrievePropertiesEx( + vim.get_service_content().propertyCollector, + token=token) def get_prop_spec(client_factory, spec_type, properties): @@ -217,5 +255,8 @@ def get_properties_for_a_collection_of_objects(vim, type, lst_obj_specs.append(get_obj_spec(client_factory, obj)) prop_filter_spec = get_prop_filter_spec(client_factory, lst_obj_specs, [prop_spec]) - return vim.RetrieveProperties(vim.get_service_content().propertyCollector, - specSet=[prop_filter_spec]) + options = client_factory.create('ns0:RetrieveOptions') + options.maxObjects = CONF.vmware.maximum_objects + return vim.RetrievePropertiesEx( + vim.get_service_content().propertyCollector, + specSet=[prop_filter_spec], options=options) diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 3996189d9293..d9e40f1f62f0 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -498,23 +498,64 @@ def search_datastore_spec(client_factory, file_name): return search_spec +def _get_token(results): + """Get the token from the property results.""" + return getattr(results, 'token', None) + + +def _get_reference_for_value(results, value): + for object in results.objects: + if object.obj.value == value: + return object + + +def _get_object_for_value(results, value): + for object in results.objects: + if object.propSet[0].val == value: + return object.obj + + +def _get_object_from_results(session, results, value, func): + while results: + token = _get_token(results) + object = func(results, value) + if object: + if token: + session._call_method(vim_util, + "cancel_retrieve", + token) + return object + + if token: + results = session._call_method(vim_util, + "continue_to_get_objects", + token) + else: + return None + + +def _cancel_retrieve_if_necessary(session, results): + token = _get_token(results) + if token: + results = session._call_method(vim_util, + "cancel_retrieve", + token) + + def get_vm_ref_from_name(session, vm_name): """Get reference to the VM with the name specified.""" vms = session._call_method(vim_util, "get_objects", "VirtualMachine", ["name"]) - for vm in vms: - if vm.propSet[0].val == vm_name: - return vm.obj - return None + return _get_object_from_results(session, vms, vm_name, + _get_object_for_value) def get_vm_ref_from_uuid(session, instance_uuid): """Get reference to the VM with the uuid specified.""" vms = session._call_method(vim_util, "get_objects", "VirtualMachine", ["name"]) - for vm in vms: - if vm.propSet[0].val == instance_uuid: - return vm.obj + return _get_object_from_results(session, vms, instance_uuid, + _get_object_for_value) def get_vm_ref(session, instance): @@ -536,10 +577,8 @@ def get_host_ref_from_id(session, host_id, property_list=None): host_refs = session._call_method( vim_util, "get_objects", "HostSystem", property_list) - - for ref in host_refs: - if ref.obj.value == host_id: - return ref + return _get_object_from_results(session, host_refs, host_id, + _get_reference_for_value) def get_host_id_from_vm_ref(session, vm_ref): @@ -600,7 +639,7 @@ def property_from_property_set(property_name, property_set): :return: the value of the property. ''' - for prop in property_set: + for prop in property_set.objects: p = _property_from_propSet(prop.propSet, property_name) if p is not None: return p @@ -643,17 +682,17 @@ def get_cluster_ref_from_name(session, cluster_name): """Get reference to the cluster with the name specified.""" cls = session._call_method(vim_util, "get_objects", "ClusterComputeResource", ["name"]) - for cluster in cls: - if cluster.propSet[0].val == cluster_name: - return cluster.obj - return None + return _get_object_from_results(session, cls, cluster_name, + _get_object_for_value) def get_host_ref(session, cluster=None): """Get reference to a host within the cluster specified.""" if cluster is None: - host_mor = session._call_method(vim_util, "get_objects", - "HostSystem")[0].obj + results = session._call_method(vim_util, "get_objects", + "HostSystem") + _cancel_retrieve_if_necessary(session, results) + host_mor = results.objects[0].obj else: host_ret = session._call_method(vim_util, "get_dynamic_property", cluster, "ClusterComputeResource", @@ -667,6 +706,26 @@ def get_host_ref(session, cluster=None): return host_mor +def _get_datastore_ref_and_name(data_stores): + for elem in data_stores.objects: + ds_name = None + ds_type = None + ds_cap = None + ds_free = None + for prop in elem.propSet: + if prop.name == "summary.type": + ds_type = prop.val + elif prop.name == "summary.name": + ds_name = prop.val + elif prop.name == "summary.capacity": + ds_cap = prop.val + elif prop.name == "summary.freeSpace": + ds_free = prop.val + # Local storage identifier + if ds_type == "VMFS" or ds_type == "NFS": + return elem.obj, ds_name, ds_cap, ds_free + + def get_datastore_ref_and_name(session, cluster=None, host=None): """Get the datastore list and choose the first local storage.""" if cluster is None and host is None: @@ -693,22 +752,20 @@ def get_datastore_ref_and_name(session, cluster=None, host=None): "Datastore", data_store_mors, ["summary.type", "summary.name", "summary.capacity", "summary.freeSpace"]) - for elem in data_stores: - ds_name = None - ds_type = None - ds_cap = None - ds_free = None - for prop in elem.propSet: - if prop.name == "summary.type": - ds_type = prop.val - elif prop.name == "summary.name": - ds_name = prop.val - elif prop.name == "summary.capacity": - ds_cap = prop.val - elif prop.name == "summary.freeSpace": - ds_free = prop.val - # Local storage identifier - if ds_type == "VMFS" or ds_type == "NFS": - return elem.obj, ds_name, ds_cap, ds_free - raise exception.DatastoreNotFound() + while data_stores: + token = _get_token(data_stores) + results = _get_datastore_ref_and_name(data_stores) + if results: + if token: + session._call_method(vim_util, + "cancel_retrieve", + token) + return results + if token: + data_stores = session._call_method(vim_util, + "continue_to_get_objects", + token) + else: + raise exception.DatastoreNotFound() + raise exception.DatastoreNotFound() diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index d7e37a4fbc68..4ba9cbd80f4e 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -94,17 +94,27 @@ class VMwareVMOps(object): "VirtualMachine", ["name", "runtime.connectionState"]) lst_vm_names = [] - for vm in vms: - vm_name = None - conn_state = None - for prop in vm.propSet: - if prop.name == "name": - vm_name = prop.val - elif prop.name == "runtime.connectionState": - conn_state = prop.val - # Ignoring the orphaned or inaccessible VMs - if conn_state not in ["orphaned", "inaccessible"]: - lst_vm_names.append(vm_name) + + while vms: + token = vm_util._get_token(vms) + for vm in vms.objects: + vm_name = None + conn_state = None + for prop in vm.propSet: + if prop.name == "name": + vm_name = prop.val + elif prop.name == "runtime.connectionState": + conn_state = prop.val + # Ignoring the orphaned or inaccessible VMs + if conn_state not in ["orphaned", "inaccessible"]: + lst_vm_names.append(vm_name) + if token: + vms = self._session._call_method(vim_util, + "continue_to_get_objects", + token) + else: + break + LOG.debug(_("Got total of %s instances") % str(len(lst_vm_names))) return lst_vm_names @@ -579,6 +589,22 @@ class VMwareVMOps(object): _clean_temp_data() + def _get_values_from_object_properties(self, props, query): + while props: + token = vm_util._get_token(props) + for elem in props.objects: + for prop in elem.propSet: + for key in query.keys(): + if prop.name == key: + query[key] = prop.val + break + if token: + props = self._session._call_method(vim_util, + "continue_to_get_objects", + token) + else: + break + def reboot(self, instance, network_info): """Reboot a VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) @@ -589,17 +615,13 @@ class VMwareVMOps(object): props = self._session._call_method(vim_util, "get_object_properties", None, vm_ref, "VirtualMachine", lst_properties) - pwr_state = None - tools_status = None - tools_running_status = False - for elem in props: - for prop in elem.propSet: - if prop.name == "runtime.powerState": - pwr_state = prop.val - elif prop.name == "summary.guest.toolsStatus": - tools_status = prop.val - elif prop.name == "summary.guest.toolsRunningStatus": - tools_running_status = prop.val + query = {'runtime.powerState': None, + 'summary.guest.toolsStatus': None, + 'summary.guest.toolsRunningStatus': False} + self._get_values_from_object_properties(props, query) + pwr_state = query['runtime.powerState'] + tools_status = query['summary.guest.toolsStatus'] + tools_running_status = query['summary.guest.toolsRunningStatus'] # Raise an exception if the VM is not powered On. if pwr_state not in ["poweredOn"]: @@ -659,14 +681,11 @@ class VMwareVMOps(object): props = self._session._call_method(vim_util, "get_object_properties", None, vm_ref, "VirtualMachine", lst_properties) - pwr_state = None - for elem in props: - vm_config_pathname = None - for prop in elem.propSet: - if prop.name == "runtime.powerState": - pwr_state = prop.val - elif prop.name == "config.files.vmPathName": - vm_config_pathname = prop.val + query = {'runtime.powerState': None, + 'config.files.vmPathName': None} + self._get_values_from_object_properties(props, query) + pwr_state = query['runtime.powerState'] + vm_config_pathname = query['config.files.vmPathName'] if vm_config_pathname: _ds_path = vm_util.split_datastore_path(vm_config_pathname) datastore_name, vmx_file_path = _ds_path @@ -1039,23 +1058,15 @@ class VMwareVMOps(object): vm_props = self._session._call_method(vim_util, "get_object_properties", None, vm_ref, "VirtualMachine", lst_properties) - max_mem = None - pwr_state = None - num_cpu = None - for elem in vm_props: - for prop in elem.propSet: - if prop.name == "summary.config.numCpu": - num_cpu = int(prop.val) - elif prop.name == "summary.config.memorySizeMB": - # In MB, but we want in KB - max_mem = int(prop.val) * 1024 - elif prop.name == "runtime.powerState": - pwr_state = VMWARE_POWER_STATES[prop.val] - - return {'state': pwr_state, + query = {'summary.config.numCpu': None, + 'summary.config.memorySizeMB': None, + 'runtime.powerState': None} + self._get_values_from_object_properties(vm_props, query) + max_mem = int(query['summary.config.memorySizeMB']) * 1024 + return {'state': VMWARE_POWER_STATES[query['runtime.powerState']], 'max_mem': max_mem, 'mem': max_mem, - 'num_cpu': num_cpu, + 'num_cpu': int(query['summary.config.numCpu']), 'cpu_time': 0} def get_diagnostics(self, instance): @@ -1190,12 +1201,14 @@ class VMwareVMOps(object): """Get the datacenter name and the reference.""" dc_obj = self._session._call_method(vim_util, "get_objects", "Datacenter", ["name"]) - return dc_obj[0].obj, dc_obj[0].propSet[0].val + vm_util._cancel_retrieve_if_necessary(self._session, dc_obj) + return dc_obj.objects[0].obj, dc_obj.objects[0].propSet[0].val def _get_host_ref_from_name(self, host_name): """Get reference to the host with the name specified.""" host_objs = self._session._call_method(vim_util, "get_objects", "HostSystem", ["name"]) + vm_util._cancel_retrieve_if_necessary(self._session, host_objs) for host in host_objs: if host.propSet[0].val == host_name: return host.obj @@ -1205,16 +1218,19 @@ class VMwareVMOps(object): """Get the Vm folder ref from the datacenter.""" dc_objs = self._session._call_method(vim_util, "get_objects", "Datacenter", ["vmFolder"]) + vm_util._cancel_retrieve_if_necessary(self._session, dc_objs) # There is only one default datacenter in a standalone ESX host - vm_folder_ref = dc_objs[0].propSet[0].val + vm_folder_ref = dc_objs.objects[0].propSet[0].val return vm_folder_ref def _get_res_pool_ref(self): # Get the resource pool. Taking the first resource pool coming our # way. Assuming that is the default resource pool. if self._cluster is None: - res_pool_ref = self._session._call_method(vim_util, "get_objects", - "ResourcePool")[0].obj + results = self._session._call_method(vim_util, "get_objects", + "ResourcePool") + vm_util._cancel_retrieve_if_necessary(self._session, results) + res_pool_ref = results.objects[0].obj else: res_pool_ref = self._session._call_method(vim_util, "get_dynamic_property",