def test_get_vm_qp(self): def adapter_read(root_type, root_id=None, suffix_type=None, suffix_parm=None): json_str = (u'{"IsVirtualServiceAttentionLEDOn":"false","Migration' u'State":"Not_Migrating","CurrentProcessingUnits":0.1,' u'"ProgressState":null,"PartitionType":"AIX/Linux","Pa' u'rtitionID":1,"AllocatedVirtualProcessors":1,"Partiti' u'onState":"not activated","RemoteRestartState":"Inval' u'id","OperatingSystemVersion":"Unknown","AssociatedMa' u'nagedSystem":"https://9.1.2.3:12443/rest/api/uom/Man' u'agedSystem/98498bed-c78a-3a4f-b90a-4b715418fcb6","RM' u'CState":"inactive","PowerManagementMode":null,"Parti' u'tionName":"lpar-1-06674231-lpar","HasDedicatedProces' u'sors":"false","ResourceMonitoringIPAddress":null,"Re' u'ferenceCode":"00000000","CurrentProcessors":null,"Cu' u'rrentMemory":512,"SharingMode":"uncapped"}') self.assertEqual('LogicalPartition', root_type) self.assertEqual('lpar_uuid', root_id) self.assertEqual('quick', suffix_type) resp = mock.MagicMock() if suffix_parm is None: resp.body = json_str elif suffix_parm == 'PartitionID': resp.body = '1' elif suffix_parm == 'CurrentProcessingUnits': resp.body = '0.1' elif suffix_parm == 'AssociatedManagedSystem': # The double quotes are important resp.body = ('"https://9.1.2.3:12443/rest/api/uom/ManagedSyste' 'm/98498bed-c78a-3a4f-b90a-4b715418fcb6"') else: self.fail('Unhandled quick property key %s' % suffix_parm) return resp ms_href = ('https://9.1.2.3:12443/rest/api/uom/ManagedSystem/98498bed-' 'c78a-3a4f-b90a-4b715418fcb6') self.apt.read.side_effect = adapter_read self.assertEqual(1, vm.get_vm_id(self.apt, 'lpar_uuid')) self.assertEqual(ms_href, vm.get_vm_qp(self.apt, 'lpar_uuid', 'AssociatedManagedSystem')) self.assertEqual(0.1, vm.get_vm_qp(self.apt, 'lpar_uuid', 'CurrentProcessingUnits')) qp_dict = vm.get_vm_qp(self.apt, 'lpar_uuid') self.assertEqual(ms_href, qp_dict['AssociatedManagedSystem']) self.assertEqual(1, qp_dict['PartitionID']) self.assertEqual(0.1, qp_dict['CurrentProcessingUnits']) resp = mock.MagicMock() resp.status = 404 self.apt.read.side_effect = pvm_exc.Error('message', response=resp) self.assertRaises(exception.InstanceNotFound, vm.get_vm_qp, self.apt, 'lpar_uuid') resp.status = 500 self.apt.read.side_effect = pvm_exc.Error('message', response=resp) self.assertRaises(pvm_exc.Error, vm.get_vm_qp, self.apt, 'lpar_uuid')
def disconnect_image_disk(self, context, instance, lpar_uuid, disk_type=None): """Disconnects the storage adapters from the image disk. :param context: nova context for operation :param instance: instance to disconnect the image for. :param lpar_uuid: The UUID for the pypowervm LPAR element. :param disk_type: The list of disk types to remove or None which means to remove all disks from the VM. :return: A list of all the backing storage elements that were disconnected from the I/O Server and VM. """ lpar_qps = vm.get_vm_qp(self.adapter, lpar_uuid) lpar_id = lpar_qps['PartitionID'] host_uuid = pvm_u.get_req_path_uuid( lpar_qps['AssociatedManagedSystem'], preserve_case=True) lu_set = set() # The mappings will normally be the same on all VIOSes, unless a VIOS # was down when a disk was added. So for the return value, we need to # collect the union of all relevant mappings from all VIOSes. for vios_uuid in self._vios_uuids(host_uuid=host_uuid): for lu in tsk_map.remove_lu_mapping( self.adapter, vios_uuid, lpar_id, disk_prefixes=disk_type): lu_set.add(lu) return list(lu_set)
def _emit_event(self, pvm_uuid, inst): # Get the current state try: pvm_state = vm.get_vm_qp(self._driver.adapter, pvm_uuid, 'PartitionState') except exception.InstanceNotFound: LOG.debug("LPAR %s was deleted while event was delayed.", pvm_uuid, instance=inst) return LOG.debug('New state %s for partition %s', pvm_state, pvm_uuid, instance=inst) inst = _get_instance(inst, pvm_uuid) if inst is None: LOG.debug("Not emitting LifecycleEvent: no instance for LPAR %s", pvm_uuid) return # If we're in the middle of a nova-driven operation, no event necessary if inst.task_state in _NO_EVENT_TASK_STATES: LOG.debug("Not emitting LifecycleEvent: instance task_state is %s", inst.task_state, instance=inst) return # See if it's really a change of state from what OpenStack knows transition = vm.translate_event(pvm_state, inst.power_state) if transition is None: LOG.debug( "No LifecycleEvent necessary for pvm_state(%s) and " "power_state(%s).", pvm_state, power_state.STATE_MAP[inst.power_state], instance=inst) return # Log as if normal event lce = event.LifecycleEvent(inst.uuid, transition) LOG.info('Sending LifecycleEvent for instance state change to: %s', pvm_state, instance=inst) self._driver.emit_event(lce) # Delete out the queue del self._delayed_event_threads[pvm_uuid]
def connect_disk(self, context, instance, disk_info, lpar_uuid): """Connects the disk image to the Virtual Machine. :param context: nova context for the transaction. :param instance: nova instance to connect the disk to. :param disk_info: The pypowervm storage element returned from create_disk_from_image. Ex. VOptMedia, VDisk, LU, or PV. :param: lpar_uuid: The pypowervm UUID that corresponds to the VM. """ # Create the LU structure lu = pvm_stg.LU.bld_ref(self.adapter, disk_info.name, disk_info.udid) # Add the mapping to *each* VIOS on the LPAR's host. # Note that the LPAR's host is likely to be the same as self.host_uuid, # but this is safer. host_href = vm.get_vm_qp(self.adapter, lpar_uuid, 'AssociatedManagedSystem') host_uuid = pvm_u.get_req_path_uuid(host_href, preserve_case=True) for vios_uuid in self._vios_uuids(host_uuid=host_uuid): tsk_map.add_vscsi_mapping(host_uuid, vios_uuid, lpar_uuid, lu)
def _handle_inst_event(self, inst, pvm_uuid, details): """Handle an instance event. This method will check if an instance event signals a change in the state of the instance as known to OpenStack and if so, trigger an event upward. :param inst: the instance object. :param pvm_uuid: the PowerVM uuid of the vm :param details: Parsed Details from the event """ # If the state of the vm changed see if it should be handled if 'PartitionState' in details: # Get the current state pvm_state = vm.get_vm_qp(self._driver.adapter, pvm_uuid, 'PartitionState') self._lifecycle_handler.process(inst, pvm_state) # If the NVRAM has changed for this instance and a store is configured. if 'NVRAM' in details and self._driver.nvram_mgr is not None: # Schedule the NVRAM for the instance to be stored. self._driver.nvram_mgr.store(inst)
def test_get_vm_qp(self): def adapter_read(root_type, root_id=None, suffix_type=None, suffix_parm=None, helpers=None): json_str = (u'{"IsVirtualServiceAttentionLEDOn":"false","Migration' u'State":"Not_Migrating","CurrentProcessingUnits":0.1,' u'"ProgressState":null,"PartitionType":"AIX/Linux","Pa' u'rtitionID":1,"AllocatedVirtualProcessors":1,"Partiti' u'onState":"not activated","RemoteRestartState":"Inval' u'id","OperatingSystemVersion":"Unknown","AssociatedMa' u'nagedSystem":"https://9.1.2.3:12443/rest/api/uom/Man' u'agedSystem/98498bed-c78a-3a4f-b90a-4b715418fcb6","RM' u'CState":"inactive","PowerManagementMode":null,"Parti' u'tionName":"lpar-1-06674231-lpar","HasDedicatedProces' u'sors":"false","ResourceMonitoringIPAddress":null,"Re' u'ferenceCode":"00000000","CurrentProcessors":null,"Cu' u'rrentMemory":512,"SharingMode":"uncapped"}') self.assertEqual('LogicalPartition', root_type) self.assertEqual('lpar_uuid', root_id) self.assertEqual('quick', suffix_type) resp = mock.MagicMock() if suffix_parm is None: resp.body = json_str elif suffix_parm == 'PartitionID': resp.body = '1' elif suffix_parm == 'CurrentProcessingUnits': resp.body = '0.1' elif suffix_parm == 'AssociatedManagedSystem': # The double quotes are important resp.body = ('"https://9.1.2.3:12443/rest/api/uom/ManagedSyste' 'm/98498bed-c78a-3a4f-b90a-4b715418fcb6"') else: self.fail('Unhandled quick property key %s' % suffix_parm) return resp def adpt_read_no_log(*args, **kwds): helpers = kwds['helpers'] try: helpers.index(pvm_log.log_helper) except ValueError: # Successful path since the logger shouldn't be there return adapter_read(*args, **kwds) self.fail('Log helper was found when it should not be') ms_href = ('https://9.1.2.3:12443/rest/api/uom/ManagedSystem/98498bed-' 'c78a-3a4f-b90a-4b715418fcb6') self.apt.read.side_effect = adapter_read self.assertEqual(1, vm.get_vm_id(self.apt, 'lpar_uuid')) self.assertEqual( ms_href, vm.get_vm_qp(self.apt, 'lpar_uuid', 'AssociatedManagedSystem')) self.apt.read.side_effect = adpt_read_no_log self.assertEqual( 0.1, vm.get_vm_qp(self.apt, 'lpar_uuid', 'CurrentProcessingUnits', log_errors=False)) qp_dict = vm.get_vm_qp(self.apt, 'lpar_uuid', log_errors=False) self.assertEqual(ms_href, qp_dict['AssociatedManagedSystem']) self.assertEqual(1, qp_dict['PartitionID']) self.assertEqual(0.1, qp_dict['CurrentProcessingUnits']) resp = mock.MagicMock() resp.status = 404 self.apt.read.side_effect = pvm_exc.HttpNotFound(resp) self.assertRaises(exception.InstanceNotFound, vm.get_vm_qp, self.apt, 'lpar_uuid', log_errors=False) self.apt.read.side_effect = pvm_exc.Error("message", response=None) self.assertRaises(pvm_exc.Error, vm.get_vm_qp, self.apt, 'lpar_uuid', log_errors=False) resp.status = 500 self.apt.read.side_effect = pvm_exc.Error("message", response=resp) self.assertRaises(pvm_exc.Error, vm.get_vm_qp, self.apt, 'lpar_uuid', log_errors=False)