def test_unplug_vifs(self, mock_vm_get, mock_unplug, mock_get_wrap): """Tests that a delete of the vif can be done.""" inst = powervm.TEST_INSTANCE # Mock up the CNA responses. cnas = [cna('AABBCCDDEEFF'), cna('AABBCCDDEE11'), cna('AABBCCDDEE22')] mock_vm_get.return_value = cnas # Mock up the network info. This also validates that they will be # sanitized to upper case. net_info = [ {'address': 'aa:bb:cc:dd:ee:ff'}, {'address': 'aa:bb:cc:dd:ee:22'}, {'address': 'aa:bb:cc:dd:ee:33'} ] # Mock out the instance wrapper mock_get_wrap.return_value = self.mock_lpar_wrap # Mock out the vif driver def validate_unplug(adapter, instance, vif, cna_w_list=None): self.assertEqual(adapter, self.apt) self.assertEqual(instance, inst) self.assertIn(vif, net_info) self.assertEqual(cna_w_list, cnas) mock_unplug.side_effect = validate_unplug # Run method p_vifs = tf_net.UnplugVifs(self.apt, inst, net_info) p_vifs.execute() # Make sure the unplug was invoked, so that we know that the validation # code was called self.assertEqual(3, mock_unplug.call_count)
def _setup_flow_and_run(): # Define the flow flow = tf_lf.Flow("destroy") # Power Off the LPAR. If its disks are about to be deleted, issue a # hard shutdown. flow.add( tf_vm.PowerOff(self.adapter, instance, force_immediate=destroy_disks)) # The FeedTask accumulates storage disconnection tasks to be run in # parallel. stg_ftsk = pvm_par.build_active_vio_feed_task( self.adapter, xag=[pvm_const.XAG.VIO_SMAP]) # Call the unplug VIFs task. While CNAs get removed from the LPAR # directly on the destroy, this clears up the I/O Host side. flow.add(tf_net.UnplugVifs(self.adapter, instance, network_info)) # Add the disconnect/deletion of the vOpt to the transaction # manager. if configdrive.required_by(instance): flow.add( tf_stg.DeleteVOpt(self.adapter, instance, stg_ftsk=stg_ftsk)) # Extract the block devices. bdms = driver.block_device_info_get_mapping(block_device_info) # Determine if there are volumes to detach. If so, remove each # volume (within the transaction manager) for bdm, vol_drv in self._vol_drv_iter(context, instance, bdms, stg_ftsk=stg_ftsk): flow.add(tf_stg.DetachVolume(vol_drv)) # Detach the disk storage adapters flow.add(tf_stg.DetachDisk(self.disk_dvr, instance)) # Accumulated storage disconnection tasks next flow.add(stg_ftsk) # Delete the storage disks if destroy_disks: flow.add(tf_stg.DeleteDisk(self.disk_dvr)) # TODO(thorst, efried) Add LPAR id based scsi map clean up task flow.add(tf_vm.Delete(self.adapter, instance)) # Build the engine & run! tf_base.run(flow, instance=instance)
def test_unplug_vifs_invalid_state(self, mock_get_wrap): """Tests that the delete raises an exception if bad VM state.""" inst = powervm.TEST_INSTANCE # Mock out the instance wrapper mock_get_wrap.return_value = self.mock_lpar_wrap # Mock that the state is incorrect self.mock_lpar_wrap.can_modify_io.return_value = False, 'bad' # Run method p_vifs = tf_net.UnplugVifs(self.apt, inst, mock.Mock()) self.assertRaises(exception.VirtualInterfaceUnplugException, p_vifs.execute)
def unplug_vifs(self, instance, network_info): """Unplug VIFs from networks.""" self._log_operation('unplug_vifs', instance) # Define the flow flow = tf_lf.Flow("unplug_vifs") # Run the detach flow.add(tf_net.UnplugVifs(self.adapter, instance, network_info)) # Run the flow try: tf_base.run(flow, instance=instance) except exc.InstanceNotFound: LOG.warning('VM was not found during unplug operation as it is ' 'already possibly deleted.', instance=instance) except Exception: LOG.exception("PowerVM error trying to unplug vifs.", instance=instance) raise exc.InterfaceDetachFailed(instance_uuid=instance.uuid)