def _connect_resource(self, lun_or_snap, connector, res_id): """Connects to LUN or snapshot, and makes sure disconnect finally. :param lun_or_snap: the LUN or snapshot to connect/disconnect. :param connector: the host connector information. :param res_id: the ID of the LUN or snapshot. :return: the connection information, in a dict with format like (same as the one returned by `_connect_device`): { 'conn': <info returned by `initialize_connection`>, 'device': <value returned by `connect_volume`>, 'connector': <host connector info> } """ init_conn_func = functools.partial(self._initialize_connection, lun_or_snap, connector, res_id) term_conn_func = functools.partial(self._terminate_connection, lun_or_snap, connector) with utils.assure_cleanup(init_conn_func, term_conn_func, False) as conn_info: conn_device_func = functools.partial(self._connect_device, conn_info) with utils.assure_cleanup(conn_device_func, self._disconnect_device, True) as attach_info: yield attach_info
def create_cloned_volume(self, volume, src_vref): """Creates cloned volume. 1. Take an internal snapshot of source volume, and attach it. 2. Create a new volume, and attach it. 3. Copy from attached snapshot of step 1 to the volume of step 2. 4. Delete the internal snapshot created in step 1. """ src_lun_id = self.get_lun_id(src_vref) if src_lun_id is None: raise exception.VolumeBackendAPIException( data=_("LUN ID of source volume: %s not found.") % src_vref.name) src_snap_name = 'snap_clone_%s' % volume.id create_snap_func = functools.partial(self.client.create_snap, src_lun_id, src_snap_name) with utils.assure_cleanup(create_snap_func, self.client.delete_snap, True) as src_snap: LOG.debug( 'Internal snapshot for clone is created, ' 'name: %(name)s, id: %(id)s.', { 'name': src_snap_name, 'id': src_snap.get_id() }) return self._create_volume_from_snap(volume, src_snap, size_in_m=utils.gib_to_mib( volume.size))
def create_cloned_volume(self, volume, src_vref): """Creates cloned volume. 1. Take an internal snapshot of source volume, and attach it. 2. Create a new volume, and attach it. 3. Copy from attached snapshot of step 1 to the volume of step 2. 4. Delete the internal snapshot created in step 1. """ src_lun_id = self.get_lun_id(src_vref) if src_lun_id is None: raise exception.VolumeBackendAPIException( data=_("LUN ID of source volume: %s not found.") % src_vref.name) src_snap_name = 'snap_clone_%s' % volume.id create_snap_func = functools.partial(self.client.create_snap, src_lun_id, src_snap_name) with utils.assure_cleanup(create_snap_func, self.client.delete_snap, True) as src_snap: LOG.debug('Internal snapshot for clone is created, ' 'name: %(name)s, id: %(id)s.', {'name': src_snap_name, 'id': src_snap.get_id()}) return self._create_volume_from_snap( volume, src_snap, size_in_m=utils.gib_to_mib(volume.size))
def test_assure_cleanup(self): data = [0] def _enter(): data[0] += 10 return data[0] def _exit(x): data[0] = x - 1 ctx = utils.assure_cleanup(_enter, _exit, True) with ctx as r: self.assertEqual(10, r) self.assertEqual(9, data[0])
def create_cloned_group(self, group, volumes, source_group, source_vols): src_group_snap_name = 'snap_clone_group_{}'.format(source_group.id) create_snap_func = functools.partial(self.client.create_cg_snap, source_group.id, src_group_snap_name) with utils.assure_cleanup(create_snap_func, self.client.delete_snap, True) as src_cg_snap: LOG.debug('Internal group snapshot for clone is created, ' 'name: %(name)s, id: %(id)s.', {'name': src_group_snap_name, 'id': src_cg_snap.get_id()}) source_vols = source_vols if source_vols else [] return self.copy_luns_in_group(group, volumes, src_cg_snap, source_vols)
def create_cloned_volume(self, volume, src_vref): """Creates cloned volume. 1. Take an internal snapshot of source volume, and attach it. 2. Thin clone from the snapshot to a new volume. Note: there are several cases the thin clone will downgrade to `dd`, 2.1 Source volume is attached (in-use). 2.2 Array OE version doesn't support thin clone. 2.3 The current LUN family reaches the thin clone limits. 3. Delete the internal snapshot created in step 1. """ src_lun_id = self.get_lun_id(src_vref) if src_lun_id is None: raise exception.VolumeBackendAPIException( data=_("LUN ID of source volume: %s not found.") % src_vref.name) src_lun = self.client.get_lun(lun_id=src_lun_id) src_snap_name = 'snap_clone_%s' % volume.id create_snap_func = functools.partial(self.client.create_snap, src_lun_id, src_snap_name) vol_params = VolumeParams(self, volume) with utils.assure_cleanup(create_snap_func, self.client.delete_snap, True) as src_snap: LOG.debug( 'Internal snapshot for clone is created, ' 'name: %(name)s, id: %(id)s.', { 'name': src_snap_name, 'id': src_snap.get_id() }) if src_vref.volume_attachment: lun = self._dd_copy(vol_params, src_snap, src_lun=src_lun) LOG.debug( 'Volume copied using dd because source volume: ' '%(name)s is attached: %(attach)s.', { 'name': src_vref.name, 'attach': src_vref.volume_attachment }) model_update = self.makeup_model(lun.get_id()) else: lun = self._thin_clone(vol_params, src_snap, src_lun=src_lun) model_update = self.makeup_model(lun.get_id(), is_snap_lun=True) if vol_params.is_replication_enabled: model_update = self.setup_replications(lun, model_update) return model_update
def create_cloned_volume(self, volume, src_vref): """Creates cloned volume. 1. Take an internal snapshot of source volume, and attach it. 2. Thin clone from the snapshot to a new volume. Note: there are several cases the thin clone will downgrade to `dd`, 2.1 Source volume is attached (in-use). 2.2 Array OE version doesn't support thin clone. 2.3 The current LUN family reaches the thin clone limits. 3. Delete the internal snapshot created in step 1. """ src_lun_id = self.get_lun_id(src_vref) if src_lun_id is None: raise exception.VolumeBackendAPIException( data=_( "LUN ID of source volume: %s not found.") % src_vref.name) src_lun = self.client.get_lun(lun_id=src_lun_id) src_snap_name = 'snap_clone_%s' % volume.id create_snap_func = functools.partial(self.client.create_snap, src_lun_id, src_snap_name) vol_params = VolumeParams(self, volume) with utils.assure_cleanup(create_snap_func, self.client.delete_snap, True) as src_snap: LOG.debug('Internal snapshot for clone is created, ' 'name: %(name)s, id: %(id)s.', {'name': src_snap_name, 'id': src_snap.get_id()}) if src_vref.volume_attachment: lun = self._dd_copy(vol_params, src_snap, src_lun=src_lun) LOG.debug('Volume copied using dd because source volume: ' '%(name)s is attached: %(attach)s.', {'name': src_vref.name, 'attach': src_vref.volume_attachment}) return self.makeup_model(lun) else: lun = self._thin_clone(vol_params, src_snap, src_lun=src_lun) return self.makeup_model(lun, is_snap_lun=True)