def test_detach_volume(self): vol_dvr = mock.Mock(connection_info={'data': {'volume_id': '1'}}) task = tf_stg.DetachVolume(vol_dvr) task.execute() vol_dvr.detach_volume.assert_called_once_with() task.revert('result', 'flow failures') vol_dvr.reset_stg_ftsk.assert_called_once_with() vol_dvr.detach_volume.assert_called_once_with() # Validate args on taskflow.task.Task instantiation with mock.patch('taskflow.task.Task.__init__') as tf: tf_stg.DetachVolume(vol_dvr) tf.assert_called_once_with(name='detach_vol_1')
def detach_volume(self, context, connection_info, instance, mountpoint, encryption=None): """Detach the volume attached to the instance. :param context: security context :param connection_info: Volume connection information from the block device mapping :param instance: nova.objects.instance.Instance :param mountpoint: Unused :param encryption: Unused """ self._log_operation('detach_volume', instance) # Define the flow flow = tf_lf.Flow("detach_volume") # Get a volume adapter for this volume vol_drv = volume.build_volume_driver(self.adapter, instance, connection_info) # Add a task to detach the volume flow.add(tf_stg.DetachVolume(vol_drv)) # Run the flow tf_base.run(flow, instance=instance)
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)