Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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))
Beispiel #4
0
    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))
Beispiel #5
0
    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])
Beispiel #6
0
    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])
Beispiel #7
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)
Beispiel #8
0
    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
Beispiel #9
0
    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)