Beispiel #1
0
    def _run_backup(self, context, backup, volume):
        backup_service = self.service.get_backup_driver(context)

        properties = utils.brick_get_connector_properties()
        backup_dic = self.volume_rpcapi.get_backup_device(context,
                                                          backup, volume)
        try:
            backup_device = backup_dic.get('backup_device')
            is_snapshot = backup_dic.get('is_snapshot')
            attach_info = self._attach_device(context, backup_device,
                                              properties, is_snapshot)
            try:
                device_path = attach_info['device']['path']
                if isinstance(device_path, six.string_types):
                    if backup_dic.get('secure_enabled', False):
                        with open(device_path) as device_file:
                            backup_service.backup(backup, device_file)
                    else:
                        with utils.temporary_chown(device_path):
                            with open(device_path) as device_file:
                                backup_service.backup(backup, device_file)
                # device_path is already file-like so no need to open it
                else:
                    backup_service.backup(backup, device_path)

            finally:
                self._detach_device(context, attach_info,
                                    backup_device, properties,
                                    is_snapshot)
        finally:
            backup = objects.Backup.get_by_id(context, backup.id)
            self._cleanup_temp_volumes_snapshots_when_backup_created(
                context, backup)
Beispiel #2
0
 def copy_sync_data(self, src_ldev, dest_ldev, size):
     src_vol = {'provider_location': six.text_type(src_ldev),
                'id': 'src_vol'}
     dest_vol = {'provider_location': six.text_type(dest_ldev),
                 'id': 'dest_vol'}
     properties = utils.brick_get_connector_properties()
     driver = self.generated_from
     src_info = None
     dest_info = None
     try:
         dest_info = driver._attach_volume(self.context, dest_vol,
                                           properties)
         src_info = driver._attach_volume(self.context, src_vol,
                                          properties)
         volume_utils.copy_volume(src_info['device']['path'],
                                  dest_info['device']['path'], size * 1024,
                                  self.configuration.volume_dd_blocksize)
     finally:
         if dest_info:
             driver._detach_volume(self.context, dest_info,
                                   dest_vol, properties)
         if src_info:
             driver._detach_volume(self.context, src_info,
                                   src_vol, properties)
     self.command.discard_zero_page(dest_ldev)
Beispiel #3
0
    def _backup_device(self, context, backup, backup_service, device):
        """Create a new backup from a volume."""

        LOG.debug('Creating a new backup for %s.', device['name'])
        use_multipath = self.configuration.use_multipath_for_image_xfer
        enforce_multipath = self.configuration.enforce_multipath_for_image_xfer
        properties = utils.brick_get_connector_properties(
            use_multipath, enforce_multipath)
        attach_info, device = self._attach_volume(context, device, properties)

        try:
            volume_path = attach_info['device']['path']

            # Secure network file systems will not chown files.
            if self.secure_file_operations_enabled():
                with fileutils.file_open(volume_path) as volume_file:
                    backup_info = backup_service.backup(backup, volume_file)
            else:
                with utils.temporary_chown(volume_path):
                    with fileutils.file_open(volume_path) as volume_file:
                        backup_info = backup_service.backup(
                            backup, volume_file)

        finally:
            self._detach_volume(context, attach_info, device, properties)
        return backup_info
Beispiel #4
0
    def _run_restore(self, context, backup, volume):
        backup_service = self.service.get_backup_driver(context)

        properties = utils.brick_get_connector_properties()
        secure_enabled = (self.volume_rpcapi.secure_file_operations_enabled(
            context, volume))
        attach_info = self._attach_device(context, volume, properties)

        # NOTE(geguileo): Not all I/O disk operations properly do greenthread
        # context switching and may end up blocking the greenthread, so we go
        # with native threads proxy-wrapping the device file object.
        try:
            device_path = attach_info['device']['path']
            if (isinstance(device_path, six.string_types)
                    and not os.path.isdir(device_path)):
                if secure_enabled:
                    with open(device_path, 'wb') as device_file:
                        backup_service.restore(backup, volume.id,
                                               tpool.Proxy(device_file))
                else:
                    with utils.temporary_chown(device_path):
                        with open(device_path, 'wb') as device_file:
                            backup_service.restore(backup, volume.id,
                                                   tpool.Proxy(device_file))
            # device_path is already file-like so no need to open it
            else:
                backup_service.restore(backup, volume.id,
                                       tpool.Proxy(device_path))
        finally:
            self._detach_device(context,
                                attach_info,
                                volume,
                                properties,
                                force=True)
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        LOG.info("ScaleIO copy_image_to_volume volume: "+str(volume) + " image service: " + str(image_service) + " image id: " + str(image_id))
        properties = utils.brick_get_connector_properties()
        sdc_ip = properties['ip']
        LOG.debug("SDC ip is: {0}".format(sdc_ip))
        
        cinder_version = version.version_info.version_string()
  #      cinder_version = str(version.version_info) 
        LOG.debug("Cinder version is %s " % cinder_version)
#       check if openstack version ia icehouse  
        if (cinder_version.startswith("2014")):
            LOG.info("Cinder version is Icehouse ")
            icehouse = 'True'
        else:
            LOG.info("Cinder version is Havana or older ")
            icehouse = 'False'
        
        try:
            if (icehouse == 'True'):
                image_utils.fetch_to_raw(context,
                                         image_service,
                                         image_id,
                                         self._attach_volume(volume, sdc_ip),
                                         BLOCK_SIZE,
                                         size=volume['size'])
            else:
                image_utils.fetch_to_raw(context,
                                         image_service,
                                         image_id,
                                         self._attach_volume(volume, sdc_ip))
                
        finally:
            self._detach_volume(volume, sdc_ip)
Beispiel #6
0
    def delete_snapshot(self, snapshot):
        """Delete a snapshot."""
        """Delete SDS snapshot,ensure source volume is attached """
        source_volume_id = snapshot['volume_id']
        if not source_volume_id:
            self._delete_snapshot(snapshot)
            return

        is_volume_attached = self._is_volume_attached(source_volume_id)
        if is_volume_attached:
            LOG.debug('Volume is attached')
            self._delete_snapshot(snapshot)
        else:
            LOG.debug('Volume is not attached')
            source_volume = {'name': 'volume-' + source_volume_id,
                             'id': source_volume_id}
            properties = utils.brick_get_connector_properties()
            source_volume_attach_info = self._attach_volume(
                None, source_volume, properties, False)
            try:
                self._delete_snapshot(snapshot)
            except Exception as ex:
                err_msg = (_LE('Delete snapshot failed: '
                           '%s.') % ex)
                LOG.error(err_msg)
            self._detach_volume(
                None, source_volume_attach_info, source_volume,
                properties, False, False)
Beispiel #7
0
    def _run_restore(self, context, backup, volume):
        backup_service = self.service.get_backup_driver(context)

        properties = utils.brick_get_connector_properties()
        secure_enabled = (
            self.volume_rpcapi.secure_file_operations_enabled(context,
                                                              volume))
        attach_info = self._attach_device(context, volume, properties)
        try:
            device_path = attach_info['device']['path']
            if (isinstance(device_path, six.string_types) and
                    not os.path.isdir(device_path)):
                if secure_enabled:
                    with open(device_path, 'wb') as device_file:
                        backup_service.restore(backup, volume.id, device_file)
                else:
                    with utils.temporary_chown(device_path):
                        with open(device_path, 'wb') as device_file:
                            backup_service.restore(backup, volume.id,
                                                   device_file)
            # device_path is already file-like so no need to open it
            else:
                backup_service.restore(backup, volume.id, device_path)
        finally:
            self._detach_device(context, attach_info, volume, properties,
                                force=True)
Beispiel #8
0
    def add_hostgroup_pair(self, pair_hostgroups):
        if self.configuration.hitachi_unit_name:
            return

        properties = utils.brick_get_connector_properties()
        if "wwpns" not in properties:
            msg = basic_lib.output_err(650, resource="HBA")
            raise exception.HBSDError(message=msg)
        hostgroups = []
        self._get_hostgroup_info(hostgroups, properties["wwpns"], login=False)
        host_grp_name = "%spair%02x" % (basic_lib.NAME_PREFIX, self.pair_hostnum)
        for hostgroup in hostgroups:
            gid = self._get_hgname_gid(hostgroup["port"], host_grp_name)

            # When 'gid' is 0, it should be true.
            # So, it cannot remove 'is not None'.
            if gid is not None:
                pair_hostgroups.append({"port": hostgroup["port"], "gid": gid, "initiator_wwn": None, "detected": True})
                break

        if not pair_hostgroups:
            for hostgroup in hostgroups:
                pair_port = hostgroup["port"]
                try:
                    self._fill_group(pair_hostgroups, pair_port, host_grp_name, None)
                except Exception:
                    if hostgroup is hostgroups[-1]:
                        raise
                else:
                    break
Beispiel #9
0
    def _run_backup(self, context, backup, volume):
        backup_service = self.service.get_backup_driver(context)

        properties = utils.brick_get_connector_properties()
        try:
            backup_device = self.volume_rpcapi.get_backup_device(
                context, backup, volume)
            attach_info = self._attach_device(context,
                                              backup_device.device_obj,
                                              properties,
                                              backup_device.is_snapshot)
            try:
                device_path = attach_info['device']['path']
                if isinstance(device_path, six.string_types):
                    if backup_device.secure_enabled:
                        with open(device_path) as device_file:
                            backup_service.backup(backup, device_file)
                    else:
                        with utils.temporary_chown(device_path):
                            with open(device_path) as device_file:
                                backup_service.backup(backup, device_file)
                # device_path is already file-like so no need to open it
                else:
                    backup_service.backup(backup, device_path)

            finally:
                self._detach_device(context, attach_info,
                                    backup_device.device_obj, properties,
                                    backup_device.is_snapshot)
        finally:
            backup = objects.Backup.get_by_id(context, backup.id)
            self._cleanup_temp_volumes_snapshots_when_backup_created(
                context, backup)
    def create_volume_from_snapshot(self, volume, snapshot):
        """Create volume from snapshot.

        - search for snapshot and retention_policy
        - create a view from snapshot and attach view
        - create a volume and attach volume
        - copy data from attached view to attached volume
        - detach volume and view and finally delete view
        """
        snap_name = self.get_snap_name(snapshot.id)
        view_name = self.get_view_name(volume.id)
        vol_name = self.get_volume_name(volume.id)
        cview = src_attach_info = dest_attach_info = None
        rpolicy = self.get_policy()
        properties = utils.brick_get_connector_properties()
        LOG.debug("Searching for snapshot: %s in K2.", snap_name)
        snap_rs = self.client.search("snapshots", short_name=snap_name)
        if hasattr(snap_rs, 'hits') and snap_rs.total != 0:
            snap = snap_rs.hits[0]
            LOG.debug("Creating a view: %(view)s from snapshot: %(snap)s",
                      {'view': view_name, 'snap': snap_name})
            try:
                cview = self.client.new("snapshots",
                                        short_name=view_name,
                                        source=snap, retention_policy=rpolicy,
                                        is_exposable=True).save()
            except Exception as ex:
                LOG.exception(_LE("Creating a view: %(view)s from snapshot: "
                                  "%(snap)s failed"), {"view": view_name,
                                                       "snap": snap_name})
                raise exception.KaminarioCinderDriverException(
                    reason=six.text_type(ex.message))

        else:
            msg = _("Snapshot: %s search failed in K2.") % snap_name
            LOG.error(msg)
            raise exception.KaminarioCinderDriverException(reason=msg)

        try:
            conn = self.initialize_connection(cview, properties)
            src_attach_info = self._connect_device(conn)
            self.create_volume(volume)
            conn = self.initialize_connection(volume, properties)
            dest_attach_info = self._connect_device(conn)
            vol_utils.copy_volume(src_attach_info['device']['path'],
                                  dest_attach_info['device']['path'],
                                  snapshot.volume.size * units.Ki,
                                  self.configuration.volume_dd_blocksize,
                                  sparse=True)
            self.terminate_connection(volume, properties)
            self.terminate_connection(cview, properties)
        except Exception as ex:
            self.terminate_connection(cview, properties)
            self.terminate_connection(volume, properties)
            cview.delete()
            self.delete_volume(volume)
            LOG.exception(_LE("Copy to volume: %(vol)s from view: %(view)s "
                              "failed"), {"vol": vol_name, "view": view_name})
            raise exception.KaminarioCinderDriverException(
                reason=six.text_type(ex.message))
Beispiel #11
0
    def _run_restore(self, context, backup, volume):
        backup_service = self.service.get_backup_driver(context)

        properties = utils.brick_get_connector_properties()
        secure_enabled = (
            self.volume_rpcapi.secure_file_operations_enabled(context,
                                                              volume))
        attach_info = self._attach_device(context, volume, properties)
        try:
            device_path = attach_info['device']['path']
            if (isinstance(device_path, six.string_types) and
                    not os.path.isdir(device_path)):
                if secure_enabled:
                    with open(device_path, 'wb') as device_file:
                        backup_service.restore(backup, volume.id, device_file)
                else:
                    with utils.temporary_chown(device_path):
                        with open(device_path, 'wb') as device_file:
                            backup_service.restore(backup, volume.id,
                                                   device_file)
            # device_path is already file-like so no need to open it
            else:
                backup_service.restore(backup, volume.id, device_path)
        finally:
            self._detach_device(context, attach_info, volume, properties)
Beispiel #12
0
 def copy_sync_data(self, src_ldev, dest_ldev, size):
     src_vol = {
         'provider_location': six.text_type(src_ldev),
         'id': 'src_vol'
     }
     dest_vol = {
         'provider_location': six.text_type(dest_ldev),
         'id': 'dest_vol'
     }
     properties = utils.brick_get_connector_properties()
     driver = self.generated_from
     src_info = None
     dest_info = None
     try:
         dest_info = driver._attach_volume(self.context, dest_vol,
                                           properties)
         src_info = driver._attach_volume(self.context, src_vol, properties)
         volume_utils.copy_volume(src_info['device']['path'],
                                  dest_info['device']['path'], size * 1024,
                                  self.configuration.volume_dd_blocksize)
     finally:
         if dest_info:
             driver._detach_volume(self.context, dest_info, dest_vol,
                                   properties)
         if src_info:
             driver._detach_volume(self.context, src_info, src_vol,
                                   properties)
     self.command.discard_zero_page(dest_ldev)
Beispiel #13
0
    def delete_snapshot(self, snapshot):
        """Delete a snapshot."""
        """Delete SDS snapshot,ensure source volume is attached """
        source_volume_id = snapshot['volume_id']
        if not source_volume_id:
            self._delete_snapshot(snapshot)
            return

        is_volume_attached = self._is_volume_attached(source_volume_id)
        if is_volume_attached:
            LOG.debug('Volume is attached')
            self._delete_snapshot(snapshot)
        else:
            LOG.debug('Volume is not attached')
            source_volume = {
                'name': 'volume-' + source_volume_id,
                'id': source_volume_id
            }
            properties = utils.brick_get_connector_properties()
            source_volume_attach_info = self._attach_volume(
                None, source_volume, properties, False)
            try:
                self._delete_snapshot(snapshot)
            except Exception as ex:
                err_msg = (_LE('Delete snapshot failed: ' '%s.') % ex)
                LOG.error(err_msg)
            self._detach_volume(None, source_volume_attach_info, source_volume,
                                properties, False, False)
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        LOG.info("ScaleIO copy_image_to_volume volume: " + str(volume) +
                 " image service: " + str(image_service) + " image id: " +
                 str(image_id))
        properties = utils.brick_get_connector_properties()
        sdc_ip = properties['ip']
        LOG.debug("SDC ip is: {0}".format(sdc_ip))

        cinder_version = version.version_info.version_string()
        #      cinder_version = str(version.version_info)
        LOG.debug("Cinder version is %s " % cinder_version)
        #       check if openstack version ia icehouse
        if (cinder_version.startswith("2014")):
            LOG.info("Cinder version is Icehouse ")
            icehouse = 'True'
        else:
            LOG.info("Cinder version is Havana or older ")
            icehouse = 'False'

        try:
            if (icehouse == 'True'):
                image_utils.fetch_to_raw(context,
                                         image_service,
                                         image_id,
                                         self._attach_volume(volume, sdc_ip),
                                         BLOCK_SIZE,
                                         size=volume['size'])
            else:
                image_utils.fetch_to_raw(context, image_service, image_id,
                                         self._attach_volume(volume, sdc_ip))

        finally:
            self._detach_volume(volume, sdc_ip)
    def create_volume_from_snapshot(self, volume, snapshot):
        """Create volume from snapshot.

        - search for snapshot and retention_policy
        - create a view from snapshot and attach view
        - create a volume and attach volume
        - copy data from attached view to attached volume
        - detach volume and view and finally delete view
        """
        snap_name = self.get_snap_name(snapshot.id)
        view_name = self.get_view_name(volume.id)
        vol_name = self.get_volume_name(volume.id)
        cview = src_attach_info = dest_attach_info = None
        rpolicy = self.get_policy()
        properties = utils.brick_get_connector_properties()
        LOG.debug("Searching for snapshot: %s in K2.", snap_name)
        snap_rs = self.client.search("snapshots", short_name=snap_name)
        if hasattr(snap_rs, 'hits') and snap_rs.total != 0:
            snap = snap_rs.hits[0]
            LOG.debug("Creating a view: %(view)s from snapshot: %(snap)s",
                      {'view': view_name, 'snap': snap_name})
            try:
                cview = self.client.new("snapshots",
                                        short_name=view_name,
                                        source=snap, retention_policy=rpolicy,
                                        is_exposable=True).save()
            except Exception as ex:
                LOG.exception(_LE("Creating a view: %(view)s from snapshot: "
                                  "%(snap)s failed"), {"view": view_name,
                                                       "snap": snap_name})
                raise exception.KaminarioCinderDriverException(
                    reason=six.text_type(ex.message))

        else:
            msg = _("Snapshot: %s search failed in K2.") % snap_name
            LOG.error(msg)
            raise exception.KaminarioCinderDriverException(reason=msg)

        try:
            conn = self.initialize_connection(cview, properties)
            src_attach_info = self._connect_device(conn)
            self.create_volume(volume)
            conn = self.initialize_connection(volume, properties)
            dest_attach_info = self._connect_device(conn)
            vol_utils.copy_volume(src_attach_info['device']['path'],
                                  dest_attach_info['device']['path'],
                                  snapshot.volume.size * units.Ki,
                                  self.configuration.volume_dd_blocksize,
                                  sparse=True)
            self.terminate_connection(volume, properties)
            self.terminate_connection(cview, properties)
        except Exception as ex:
            self.terminate_connection(cview, properties)
            self.terminate_connection(volume, properties)
            cview.delete()
            self.delete_volume(volume)
            LOG.exception(_LE("Copy to volume: %(vol)s from view: %(view)s "
                              "failed"), {"vol": vol_name, "view": view_name})
            raise exception.KaminarioCinderDriverException(
                reason=six.text_type(ex.message))
Beispiel #16
0
 def _device_connect_context(self, volume):
     connector = utils.brick_get_connector_properties()
     connection = self.initialize_connection(volume, connector)
     try:
         yield self._connect_device(connection)
     finally:
         self.terminate_connection(volume, connector)
 def add_hostgroup(self):
     properties = utils.brick_get_connector_properties()
     if "initiator" not in properties:
         raise exception.HBSDError(message=basic_lib.output_err(650, resource="HBA"))
     LOG.debug("initiator: %s", properties["initiator"])
     hostgroups = []
     security_ports = self._get_hostgroup_info_iscsi(hostgroups, properties["initiator"])
     self.add_hostgroup_master(hostgroups, properties["initiator"], properties["ip"], security_ports)
 def test_brick_get_connector_properties(self, mock_helper, mock_get,
                                         mock_conf):
     mock_conf.my_ip = '1.2.3.4'
     output = utils.brick_get_connector_properties()
     mock_helper.assert_called_once_with()
     mock_get.assert_called_once_with(mock_helper.return_value, '1.2.3.4',
                                      False, False)
     self.assertEqual(mock_get.return_value, output)
Beispiel #19
0
 def test_brick_get_connector_properties(self, mock_helper, mock_get,
                                         mock_conf):
     mock_conf.my_ip = '1.2.3.4'
     output = utils.brick_get_connector_properties()
     mock_helper.assert_called_once_with()
     mock_get.assert_called_once_with(mock_helper.return_value, '1.2.3.4',
                                      False, False)
     self.assertEqual(mock_get.return_value, output)
Beispiel #20
0
    def copy_volume_data(self, context, src_vol, dest_vol, remote=None):
        """Copy data from src_vol to dest_vol."""
        LOG.debug(_('copy_data_between_volumes %(src)s -> %(dest)s.')
                  % {'src': src_vol['name'], 'dest': dest_vol['name']})

        properties = utils.brick_get_connector_properties()
        dest_remote = True if remote in ['dest', 'both'] else False
        dest_orig_status = dest_vol['status']
        try:
            dest_attach_info = self._attach_volume(context,
                                                   dest_vol,
                                                   properties,
                                                   remote=dest_remote)
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to attach volume %(vol)s")
                LOG.error(msg % {'vol': dest_vol['id']})
                self.db.volume_update(context, dest_vol['id'],
                                      {'status': dest_orig_status})

        src_remote = True if remote in ['src', 'both'] else False
        src_orig_status = src_vol['status']
        try:
            src_attach_info = self._attach_volume(context,
                                                  src_vol,
                                                  properties,
                                                  remote=src_remote)
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to attach volume %(vol)s")
                LOG.error(msg % {'vol': src_vol['id']})
                self.db.volume_update(context, src_vol['id'],
                                      {'status': src_orig_status})
                self._copy_volume_data_cleanup(context, dest_vol, properties,
                                               dest_attach_info, dest_remote,
                                               force=True)

        try:
            size_in_mb = int(src_vol['size']) * 1024    # vol size is in GB
            volume_utils.copy_volume(
                src_attach_info['device']['path'],
                dest_attach_info['device']['path'],
                size_in_mb,
                self.configuration.volume_dd_blocksize)
            copy_error = False
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to copy volume %(src)s to %(dest)d")
                LOG.error(msg % {'src': src_vol['id'], 'dest': dest_vol['id']})
                copy_error = True
        finally:
            self._copy_volume_data_cleanup(context, dest_vol, properties,
                                           dest_attach_info, dest_remote,
                                           force=copy_error)
            self._copy_volume_data_cleanup(context, src_vol, properties,
                                           src_attach_info, src_remote,
                                           force=copy_error)
Beispiel #21
0
    def copy_volume_data(self, context, src_vol, dest_vol, remote=None):
        """Copy data from src_vol to dest_vol."""
        LOG.debug(_('copy_data_between_volumes %(src)s -> %(dest)s.')
                  % {'src': src_vol['name'], 'dest': dest_vol['name']})

        properties = utils.brick_get_connector_properties()
        dest_remote = True if remote in ['dest', 'both'] else False
        dest_orig_status = dest_vol['status']
        try:
            dest_attach_info = self._attach_volume(context,
                                                   dest_vol,
                                                   properties,
                                                   remote=dest_remote)
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to attach volume %(vol)s")
                LOG.error(msg % {'vol': dest_vol['id']})
                self.db.volume_update(context, dest_vol['id'],
                                      {'status': dest_orig_status})

        src_remote = True if remote in ['src', 'both'] else False
        src_orig_status = src_vol['status']
        try:
            src_attach_info = self._attach_volume(context,
                                                  src_vol,
                                                  properties,
                                                  remote=src_remote)
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to attach volume %(vol)s")
                LOG.error(msg % {'vol': src_vol['id']})
                self.db.volume_update(context, src_vol['id'],
                                      {'status': src_orig_status})
                self._detach_volume(context, dest_attach_info, dest_vol,
                                    properties, force=True, remote=dest_remote)

        try:
            size_in_mb = int(src_vol['size']) * 1024    # vol size is in GB
            volume_utils.copy_volume(
                src_attach_info['device']['path'],
                dest_attach_info['device']['path'],
                size_in_mb,
                self.configuration.volume_dd_blocksize)
            copy_error = False
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to copy volume %(src)s to %(dest)d")
                LOG.error(msg % {'src': src_vol['id'], 'dest': dest_vol['id']})
                copy_error = True
        finally:
            self._detach_volume(context, dest_attach_info, dest_vol,
                                properties, force=copy_error,
                                remote=dest_remote)
            self._detach_volume(context, src_attach_info, src_vol,
                                properties, force=copy_error,
                                remote=src_remote)
Beispiel #22
0
 def _connection_context(self, volume):
     use_multipath = self.configuration.use_multipath_for_image_xfer
     enforce_multipath = self.configuration.enforce_multipath_for_image_xfer
     connector = utils.brick_get_connector_properties(
         use_multipath, enforce_multipath)
     connection = self.initialize_connection(volume, connector)
     try:
         yield connection
     finally:
         self.terminate_connection(volume, connector)
Beispiel #23
0
 def _connection_context(self, volume):
     use_multipath = self.configuration.use_multipath_for_image_xfer
     enforce_multipath = self.configuration.enforce_multipath_for_image_xfer
     connector = utils.brick_get_connector_properties(use_multipath,
                                                      enforce_multipath)
     connection = self.initialize_connection(volume, connector)
     try:
         yield connection
     finally:
         self.terminate_connection(volume, connector)
Beispiel #24
0
 def add_hostgroup(self):
     properties = utils.brick_get_connector_properties()
     if 'initiator' not in properties:
         raise exception.HBSDError(
             message=basic_lib.output_err(650, resource='HBA'))
     LOG.debug("initiator: %s", properties['initiator'])
     hostgroups = []
     security_ports = self._get_hostgroup_info_iscsi(
         hostgroups, properties['initiator'])
     self.add_hostgroup_master(hostgroups, properties['initiator'],
                               properties['ip'], security_ports)
Beispiel #25
0
    def _copy_vdisk_data(self, src_vdisk_name, src_vdisk_id, dest_vdisk_name, dest_vdisk_id):
        """Copy data from src vdisk to dest vdisk.

        To be able to copy data between vdisks, we must ensure that both
        vdisks have been mapped to host. If vdisk has not been mapped,
        it must be mapped firstly. When data copy completed, vdisk
        should be restored to previous mapped or non-mapped status.
        """

        LOG.debug("enter: _copy_vdisk_data: %(src)s -> %(dest)s.", {"src": src_vdisk_name, "dest": dest_vdisk_name})

        connector = utils.brick_get_connector_properties()
        (src_map, src_lun_id) = self._is_vdisk_map(src_vdisk_name, connector)
        (dest_map, dest_lun_id) = self._is_vdisk_map(dest_vdisk_name, connector)

        src_map_device = None
        src_properties = None
        dest_map_device = None
        dest_properties = None

        try:
            if not src_map:
                src_lun_id = self._map_vdisk_to_host(src_vdisk_name, connector)
            if not dest_map:
                dest_lun_id = self._map_vdisk_to_host(dest_vdisk_name, connector)
            src_properties = self._get_vdisk_map_properties(
                connector, src_lun_id, src_vdisk_name, src_vdisk_id, self._get_vdisk_params(None)
            )
            src_map_device = self._scan_device(src_properties)

            dest_properties = self._get_vdisk_map_properties(
                connector, dest_lun_id, dest_vdisk_name, dest_vdisk_id, self._get_vdisk_params(None)
            )
            dest_map_device = self._scan_device(dest_properties)

            src_vdisk_attr = self._get_vdisk_attributes(src_vdisk_name)

            # vdisk capacity is bytes, translate into MB
            size_in_mb = int(src_vdisk_attr["capacity"]) / units.Mi
            volume_utils.copy_volume(
                src_map_device["path"], dest_map_device["path"], size_in_mb, self.configuration.volume_dd_blocksize
            )
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Failed to copy %(src)s to %(dest)s."), {"src": src_vdisk_name, "dest": dest_vdisk_name})
        finally:
            if not dest_map:
                self._unmap_vdisk_from_host(dest_vdisk_name, connector)
                self._remove_device(dest_properties, dest_map_device)
            if not src_map:
                self._unmap_vdisk_from_host(src_vdisk_name, connector)
                self._remove_device(src_properties, src_map_device)

        LOG.debug("leave: _copy_vdisk_data: %(src)s -> %(dest)s.", {"src": src_vdisk_name, "dest": dest_vdisk_name})
Beispiel #26
0
    def init_cinder_hosts(self, **kwargs):
        targets = kwargs.pop('targets', {'info': {}, 'list': []})
        connector = cinder_utils.brick_get_connector_properties()
        target_ports = self.storage_info['ports']

        if (self.find_targets_from_storage(
                targets, connector, target_ports) and
                self.conf.hpexp_group_request):
            self.create_mapping_targets(targets, connector)

        utils.require_target_existed(targets)
Beispiel #27
0
    def copy_volume_to_image(self, context, volume, image_service, image_meta):
        """Copy the volume to the specified image."""
        LOG.debug(("copy_volume_to_image %s.") % volume["name"])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            image_utils.upload_volume(context, image_service, image_meta, attach_info["device"]["path"])
        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #28
0
    def _run_backup(self, context, backup, volume):
        # Save a copy of the encryption key ID in case the volume is deleted.
        if (volume.encryption_key_id is not None
                and backup.encryption_key_id is None):
            backup.encryption_key_id = volume_utils.clone_encryption_key(
                context, key_manager.API(CONF), volume.encryption_key_id)
            backup.save()

        backup_service = self.service(context)

        properties = utils.brick_get_connector_properties()

        # NOTE(geguileo): Not all I/O disk operations properly do greenthread
        # context switching and may end up blocking the greenthread, so we go
        # with native threads proxy-wrapping the device file object.
        try:
            backup_device = self.volume_rpcapi.get_backup_device(
                context, backup, volume)
            attach_info = self._attach_device(context,
                                              backup_device.device_obj,
                                              properties,
                                              backup_device.is_snapshot)
            try:
                device_path = attach_info['device']['path']
                if (isinstance(device_path, str)
                        and not os.path.isdir(device_path)):
                    if backup_device.secure_enabled:
                        with open(device_path, 'rb') as device_file:
                            updates = backup_service.backup(
                                backup, tpool.Proxy(device_file))
                    else:
                        with utils.temporary_chown(device_path):
                            with open(device_path, 'rb') as device_file:
                                updates = backup_service.backup(
                                    backup, tpool.Proxy(device_file))
                # device_path is already file-like so no need to open it
                else:
                    updates = backup_service.backup(backup,
                                                    tpool.Proxy(device_path))

            finally:
                self._detach_device(context,
                                    attach_info,
                                    backup_device.device_obj,
                                    properties,
                                    backup_device.is_snapshot,
                                    force=True,
                                    ignore_errors=True)
        finally:
            with backup.as_read_deleted():
                backup.refresh()
            self._cleanup_temp_volumes_snapshots_when_backup_created(
                context, backup)
        return updates
 def add_hostgroup(self):
     properties = utils.brick_get_connector_properties()
     if 'initiator' not in properties:
         msg = basic_lib.output_err(650, resource='HBA')
         raise exception.HBSDError(message=msg)
     LOG.debug("initiator: %s" % properties['initiator'])
     hostgroups = []
     security_ports = self._get_hostgroup_info_iscsi(
         hostgroups, properties['initiator'])
     self.add_hostgroup_master(hostgroups, properties['initiator'],
                               properties['ip'], security_ports)
Beispiel #30
0
    def add_hostgroup(self):
        properties = utils.brick_get_connector_properties()
        if "wwpns" not in properties:
            msg = basic_lib.output_err(650, resource="HBA")
            raise exception.HBSDError(message=msg)
        LOG.debug("wwpns: %s" % properties["wwpns"])

        hostgroups = []
        security_ports = self._get_hostgroup_info(hostgroups, properties["wwpns"], login=False)
        self.add_hostgroup_master(hostgroups, properties["wwpns"], properties["ip"], security_ports)
        self.add_hostgroup_pair(self.pair_hostgroups)
Beispiel #31
0
    def copy_volume_to_image(self, context, volume, image_service, image_meta):
        """Copy the volume to the specified image."""
        LOG.debug(_('copy_volume_to_image %s.') % volume['name'])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            image_utils.upload_volume(context, image_service, image_meta,
                                      attach_info['device']['path'])
        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #32
0
    def add_hostgroup(self):
        properties = utils.brick_get_connector_properties()
        if 'wwpns' not in properties:
            msg = basic_lib.output_err(650, resource='HBA')
            raise exception.HBSDError(message=msg)
        LOG.debug("wwpns: %s" % properties['wwpns'])

        hostgroups = []
        security_ports = self._get_hostgroup_info(
            hostgroups, properties['wwpns'], login=False)
        self.add_hostgroup_master(hostgroups, properties['wwpns'],
                                  properties['ip'], security_ports)
        self.add_hostgroup_pair(self.pair_hostgroups)
 def copy_volume_to_image(self, context, volume, image_service, image_meta):
     """Copy the volume to the specified image."""
     LOG.info("ScaleIO copy_volume_to_image volume: " + str(volume) +
              " image service: " + str(image_service) + " image meta: " +
              str(image_meta))
     properties = utils.brick_get_connector_properties()
     sdc_ip = properties['ip']
     LOG.debug("SDC ip is: {0}".format(sdc_ip))
     try:
         image_utils.upload_volume(context, image_service, image_meta,
                                   self._attach_volume(volume, sdc_ip))
     finally:
         self._detach_volume(volume, sdc_ip)
 def copy_volume_to_image(self, context, volume, image_service, image_meta):
     """Copy the volume to the specified image."""
     LOG.info("ScaleIO copy_volume_to_image volume: "+str(volume) + " image service: " + str(image_service) + " image meta: " + str(image_meta))
     properties = utils.brick_get_connector_properties()
     sdc_ip = properties['ip']
     LOG.debug("SDC ip is: {0}".format(sdc_ip))
     try:
         image_utils.upload_volume(context,
                               image_service,
                               image_meta,
                               self._attach_volume (volume, sdc_ip))
     finally:
         self._detach_volume(volume, sdc_ip)
Beispiel #35
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        LOG.debug(_('copy_image_to_volume %s.') % volume['name'])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            image_utils.fetch_to_raw(context, image_service, image_id,
                                     attach_info['device']['path'])
        finally:
            self._detach_volume(attach_info)
            self.terminate_connection(volume, properties)
Beispiel #36
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        LOG.debug(_("copy_image_to_volume %s.") % volume["name"])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            image_utils.fetch_to_raw(
                context, image_service, image_id, attach_info["device"]["path"], size=volume["size"]
            )
        finally:
            self._detach_volume(attach_info)
            self.terminate_connection(volume, properties)
Beispiel #37
0
    def init_cinder_hosts(self, **kwargs):
        """Initialize server-storage connection."""
        targets = kwargs.pop('targets', {'info': {}, 'list': [], 'iqns': {}})
        connector = cinder_utils.brick_get_connector_properties(
            multipath=self.conf.use_multipath_for_image_xfer,
            enforce_multipath=self.conf.enforce_multipath_for_image_xfer)
        target_ports = self.storage_info['ports']

        if target_ports:
            if (self.find_targets_from_storage(targets, connector,
                                               target_ports)
                    and self.conf.vsp_group_request):
                self.create_mapping_targets(targets, connector)

            utils.require_target_existed(targets)
Beispiel #38
0
    def copy_volume_to_image(self, context, volume, image_service, image_meta):
        """Copy the volume to the specified image."""
        LOG.debug(_('copy_volume_to_image %s.') % volume['name'])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            image_utils.upload_volume(context,
                                      image_service,
                                      image_meta,
                                      attach_info['device']['path'])
        finally:
            self._detach_volume(attach_info)
            self.terminate_connection(volume, properties)
Beispiel #39
0
    def init_cinder_hosts(self, **kwargs):
        """Initialize server-storage connection."""
        targets = kwargs.pop('targets', {'info': {}, 'list': [], 'iqns': {}})
        connector = cinder_utils.brick_get_connector_properties(
            multipath=self.conf.use_multipath_for_image_xfer,
            enforce_multipath=self.conf.enforce_multipath_for_image_xfer)
        target_ports = self.storage_info['ports']

        if target_ports:
            if (self.find_targets_from_storage(
                    targets, connector, target_ports) and
                    self.conf.vsp_group_request):
                self.create_mapping_targets(targets, connector)

            utils.require_target_existed(targets)
Beispiel #40
0
    def _dd_copy(self, vol_params, src_snap, src_lun=None):
        """Creates a volume via copying a Unity snapshot.

        It attaches the `volume` and `snap`, then use `dd` to copy the
        data from the Unity snapshot to the `volume`.
        """
        dest_lun = self.client.create_lun(
            name=vol_params.name,
            size=vol_params.size,
            pool=vol_params.pool,
            description=vol_params.description,
            io_limit_policy=vol_params.io_limit_policy,
            is_thin=False if vol_params.is_thick else None,
            is_compressed=vol_params.is_compressed)
        src_id = src_snap.get_id()
        try:
            conn_props = cinder_utils.brick_get_connector_properties()

            with self._connect_resource(dest_lun, conn_props,
                                        vol_params.volume_id) as dest_info, \
                    self._connect_resource(src_snap, conn_props,
                                           src_id) as src_info:
                if src_lun is None:
                    # If size is not specified, need to get the size from LUN
                    # of snapshot.
                    lun = self.client.get_lun(
                        lun_id=src_snap.storage_resource.get_id())
                    size_in_m = utils.byte_to_mib(lun.size_total)
                else:
                    size_in_m = utils.byte_to_mib(src_lun.size_total)
                vol_utils.copy_volume(
                    src_info['device']['path'],
                    dest_info['device']['path'],
                    size_in_m,
                    self.driver.configuration.volume_dd_blocksize,
                    sparse=True)
        except Exception:
            with excutils.save_and_reraise_exception():
                utils.ignore_exception(self.client.delete_lun,
                                       dest_lun.get_id())
                LOG.error(
                    'Failed to create cloned volume: %(vol_id)s, '
                    'from source unity snapshot: %(snap_name)s.', {
                        'vol_id': vol_params.volume_id,
                        'snap_name': src_snap.name
                    })

        return dest_lun
Beispiel #41
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        LOG.debug(_('copy_image_to_volume %s.') % volume['name'])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            image_utils.fetch_to_raw(context,
                                     image_service,
                                     image_id,
                                     attach_info['device']['path'],
                                     self.configuration.volume_dd_blocksize,
                                     size=volume['size'])
        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #42
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        LOG.debug(_('copy_image_to_volume %s.') % volume['name'])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            image_utils.fetch_to_raw(context,
                                     image_service,
                                     image_id,
                                     attach_info['device']['path'],
                                     self.configuration.volume_dd_blocksize,
                                     size=volume['size'])
        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #43
0
 def _copy_with_dd(self, src_ldev, dest_ldev, size):
     src_info = None
     dest_info = None
     properties = cinder_utils.brick_get_connector_properties()
     try:
         dest_info = self._attach_ldev(dest_ldev, properties)
         src_info = self._attach_ldev(src_ldev, properties)
         volume_utils.copy_volume(
             src_info['device']['path'], dest_info['device']['path'],
             size * units.Ki, self.conf.volume_dd_blocksize)
     finally:
         if src_info:
             self._detach_ldev(src_info, src_ldev, properties)
         if dest_info:
             self._detach_ldev(dest_info, dest_ldev, properties)
     self.discard_zero_page({'provider_location': six.text_type(dest_ldev)})
Beispiel #44
0
    def copy_volume_data(self, context, src_vol, dest_vol, remote=None):
        """Copy data from src_vol to dest_vol."""
        LOG.debug(
            _("copy_data_between_volumes %(src)s -> %(dest)s.") % {"src": src_vol["name"], "dest": dest_vol["name"]}
        )

        properties = utils.brick_get_connector_properties()
        dest_remote = True if remote in ["dest", "both"] else False
        dest_orig_status = dest_vol["status"]
        try:
            dest_attach_info = self._attach_volume(context, dest_vol, properties, remote=dest_remote)
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to attach volume %(vol)s")
                LOG.error(msg % {"vol": dest_vol["id"]})
                self.db.volume_update(context, dest_vol["id"], {"status": dest_orig_status})

        src_remote = True if remote in ["src", "both"] else False
        src_orig_status = src_vol["status"]
        try:
            src_attach_info = self._attach_volume(context, src_vol, properties, remote=src_remote)
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to attach volume %(vol)s")
                LOG.error(msg % {"vol": src_vol["id"]})
                self.db.volume_update(context, src_vol["id"], {"status": src_orig_status})
                self._copy_volume_data_cleanup(context, dest_vol, properties, dest_attach_info, dest_remote, force=True)

        try:
            size_in_mb = int(src_vol["size"]) * 1024  # vol size is in GB
            volume_utils.copy_volume(
                src_attach_info["device"]["path"],
                dest_attach_info["device"]["path"],
                size_in_mb,
                self.configuration.volume_dd_blocksize,
            )
            copy_error = False
        except Exception:
            with excutils.save_and_reraise_exception():
                msg = _("Failed to copy volume %(src)s to %(dest)d")
                LOG.error(msg % {"src": src_vol["id"], "dest": dest_vol["id"]})
                copy_error = True
        finally:
            self._copy_volume_data_cleanup(
                context, dest_vol, properties, dest_attach_info, dest_remote, force=copy_error
            )
            self._copy_volume_data_cleanup(context, src_vol, properties, src_attach_info, src_remote, force=copy_error)
Beispiel #45
0
 def copy_volume_to_image(self, context, volume, image_service, image_meta):
     """Copy the volume to the specified image."""
     LOG.info(
         _LI("ScaleIO copy_volume_to_image volume: %(vol)s image service: "
             "%(service)s image meta: %(meta)s."), {
                 'vol': volume,
                 'service': six.text_type(image_service),
                 'meta': six.text_type(image_meta)
             })
     properties = utils.brick_get_connector_properties()
     sdc_ip = properties['ip']
     LOG.debug("SDC ip is: {0}".format(sdc_ip))
     try:
         image_utils.upload_volume(context, image_service, image_meta,
                                   self._sio_attach_volume(volume, sdc_ip))
     finally:
         self._sio_detach_volume(volume, sdc_ip)
Beispiel #46
0
    def _run_backup(self, context, backup, volume):
        backup_service = self.service.get_backup_driver(context)

        properties = utils.brick_get_connector_properties()

        # NOTE(geguileo): Not all I/O disk operations properly do greenthread
        # context switching and may end up blocking the greenthread, so we go
        # with native threads proxy-wrapping the device file object.
        try:
            backup_device = self.volume_rpcapi.get_backup_device(
                context, backup, volume)
            attach_info = self._attach_device(context,
                                              backup_device.device_obj,
                                              properties,
                                              backup_device.is_snapshot)
            try:
                device_path = attach_info['device']['path']
                if (isinstance(device_path, six.string_types)
                        and not os.path.isdir(device_path)):
                    if backup_device.secure_enabled:
                        with open(device_path) as device_file:
                            updates = backup_service.backup(
                                backup, tpool.Proxy(device_file))
                    else:
                        with utils.temporary_chown(device_path):
                            with open(device_path) as device_file:
                                updates = backup_service.backup(
                                    backup, tpool.Proxy(device_file))
                # device_path is already file-like so no need to open it
                else:
                    updates = backup_service.backup(backup,
                                                    tpool.Proxy(device_path))

            finally:
                self._detach_device(context,
                                    attach_info,
                                    backup_device.device_obj,
                                    properties,
                                    backup_device.is_snapshot,
                                    force=True,
                                    ignore_errors=True)
        finally:
            backup = objects.Backup.get_by_id(context, backup.id)
            self._cleanup_temp_volumes_snapshots_when_backup_created(
                context, backup)
        return updates
Beispiel #47
0
    def backup_volume(self, context, backup, backup_service):
        """Create a new backup from an existing volume."""
        volume = self.db.volume_get(context, backup['volume_id'])

        LOG.debug(_('Creating a new backup for volume %s.') % volume['name'])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            volume_path = attach_info['device']['path']
            with utils.temporary_chown(volume_path):
                with fileutils.file_open(volume_path) as volume_file:
                    backup_service.backup(backup, volume_file)

        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #48
0
    def backup_volume(self, context, backup, backup_service):
        """Create a new backup from an existing volume."""
        volume = self.db.volume_get(context, backup["volume_id"])

        LOG.debug(("Creating a new backup for volume %s.") % volume["name"])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            volume_path = attach_info["device"]["path"]
            with utils.temporary_chown(volume_path):
                with fileutils.file_open(volume_path) as volume_file:
                    backup_service.backup(backup, volume_file)

        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #49
0
    def restore_backup(self, context, backup, volume, backup_service):
        """Restore an existing backup to a new or existing volume."""
        LOG.debug(_('Restoring backup %(backup)s to '
                    'volume %(volume)s.') %
                  {'backup': backup['id'],
                   'volume': volume['name']})

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            volume_path = attach_info['device']['path']
            with utils.temporary_chown(volume_path):
                with fileutils.file_open(volume_path, 'wb') as volume_file:
                    backup_service.restore(backup, volume['id'], volume_file)

        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #50
0
 def copy_image_to_volume(self, context, volume, image_service, image_id):
     """Fetch the image from image_service and write it to the volume."""
     LOG.debug(_('ProvizoDriver.copy_image_to_volume %s') % volume['id'])
     connector = utils.brick_get_connector_properties()
     init_conn = self.initialize_connection(volume, connector)
     if init_conn['driver_volume_type'] == 'iscsi':
         return super(ProvizoDriver, self).copy_image_to_volume(context,
                 volume, image_service, image_id)
     try:
         if init_conn['driver_volume_type'] == 'orkestra_local':
             soma_id = init_conn['data']['soma_id']
             volume_path = self._get_device_path(soma_id)
             image_utils.fetch_to_raw(context, image_service, image_id,
                     volume_path)
         else:
             raise NotImplementedError(init_conn['driver_volume_type'])
     finally:
         self.terminate_connection(volume, connector)
Beispiel #51
0
    def restore_backup(self, context, backup, volume, backup_service):
        """Restore an existing backup to a new or existing volume."""
        LOG.debug(_('Restoring backup %(backup)s to '
                    'volume %(volume)s.') %
                  {'backup': backup['id'],
                   'volume': volume['name']})

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            volume_path = attach_info['device']['path']
            with utils.temporary_chown(volume_path):
                with fileutils.file_open(volume_path, 'wb') as volume_file:
                    backup_service.restore(backup, volume['id'], volume_file)

        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #52
0
 def copy_volume_to_image(self, context, volume, image_service, image_meta):
     """Copy the volume to the specified image."""
     LOG.info(_LI(
         "ScaleIO copy_volume_to_image volume: %(vol)s image service: "
         "%(service)s image meta: %(meta)s."),
         {'vol': volume,
          'service': six.text_type(image_service),
          'meta': six.text_type(image_meta)})
     properties = utils.brick_get_connector_properties()
     sdc_ip = properties['ip']
     LOG.debug("SDC ip is: {0}".format(sdc_ip))
     try:
         image_utils.upload_volume(context,
                                   image_service,
                                   image_meta,
                                   self._sio_attach_volume(volume, sdc_ip))
     finally:
         self._sio_detach_volume(volume, sdc_ip)
Beispiel #53
0
    def restore_backup(self, context, backup, volume, backup_service):
        """Restore an existing backup to a new or existing volume."""
        LOG.debug(
            ("Restoring backup %(backup)s to " "volume %(volume)s.")
            % {"backup": backup["id"], "volume": volume["name"]}
        )

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            volume_path = attach_info["device"]["path"]
            with utils.temporary_chown(volume_path):
                with fileutils.file_open(volume_path, "wb") as volume_file:
                    backup_service.restore(backup, volume["id"], volume_file)

        finally:
            self._detach_volume(context, attach_info, volume, properties)
Beispiel #54
0
    def create_cloned_volume(self, volume, src_vref):
        """Create a clone from source volume.

        - attach source volume
        - create and attach new volume
        - copy data from attached source volume to attached new volume
        - detach both volumes
        """
        clone_name = self.get_volume_name(volume.id)
        src_name = self.get_volume_name(src_vref.id)
        src_vol = self.client.search("volumes", name=src_name)
        src_map = self.client.search("mappings", volume=src_vol)
        src_attach_info = dest_attach_info = None
        if src_map.total != 0:
            msg = _("K2 driver does not support clone of a attached volume. "
                    "To get this done, create a snapshot from the attached "
                    "volume and then create a volume from the snapshot.")
            LOG.error(msg)
            raise exception.KaminarioCinderDriverException(reason=msg)
        try:
            properties = utils.brick_get_connector_properties()
            conn = self.initialize_connection(src_vref, properties)
            src_attach_info = self._connect_device(conn)
            self.create_volume(volume)
            conn = self.initialize_connection(volume, properties)
            dest_attach_info = self._connect_device(conn)
            vol_utils.copy_volume(src_attach_info['device']['path'],
                                  dest_attach_info['device']['path'],
                                  src_vref.size * units.Ki,
                                  self.configuration.volume_dd_blocksize,
                                  sparse=True)
            self._kaminario_disconnect_volume(src_attach_info,
                                              dest_attach_info)
            self.terminate_connection(volume, properties)
            self.terminate_connection(src_vref, properties)
        except Exception as ex:
            self._kaminario_disconnect_volume(src_attach_info,
                                              dest_attach_info)
            self.terminate_connection(src_vref, properties)
            self.terminate_connection(volume, properties)
            self.delete_volume(volume)
            LOG.exception("Create a clone: %s failed.", clone_name)
            raise exception.KaminarioCinderDriverException(reason=ex)
Beispiel #55
0
 def _copy_with_dd(self, src_ldev, dest_ldev, size):
     """Copy the content of a volume by dd command."""
     src_info = None
     dest_info = None
     properties = cinder_utils.brick_get_connector_properties(
         multipath=self.conf.use_multipath_for_image_xfer,
         enforce_multipath=self.conf.enforce_multipath_for_image_xfer)
     try:
         dest_info = self._attach_ldev(dest_ldev, properties)
         src_info = self._attach_ldev(src_ldev, properties)
         volume_utils.copy_volume(
             src_info['device']['path'], dest_info['device']['path'],
             size * units.Ki, self.conf.volume_dd_blocksize)
     finally:
         if src_info:
             self._detach_ldev(src_info, src_ldev, properties)
         if dest_info:
             self._detach_ldev(dest_info, dest_ldev, properties)
     self.discard_zero_page({'provider_location': six.text_type(dest_ldev)})
Beispiel #56
0
    def backup_volume(self, context, backup, backup_service):
        """Create a new backup from an existing volume."""
        volume = self.db.volume_get(context, backup['volume_id'])

        LOG.debug(_('Creating a new backup for volume %s.') %
                  volume['name'])

        properties = utils.brick_get_connector_properties()
        attach_info = self._attach_volume(context, volume, properties)

        try:
            volume_path = attach_info['device']['path']
            with utils.temporary_chown(volume_path):
                with fileutils.file_open(volume_path) as volume_file:
                    backup_service.backup(backup, volume_file)

        finally:
            self._detach_volume(attach_info)
            self.terminate_connection(volume, properties)
    def create_cloned_volume(self, volume, src_vref):
        """Create a clone from source volume.

        - attach source volume
        - create and attach new volume
        - copy data from attached source volume to attached new volume
        - detach both volumes
        """
        clone_name = self.get_volume_name(volume.id)
        src_name = self.get_volume_name(src_vref.id)
        src_vol = self.client.search("volumes", name=src_name)
        src_map = self.client.search("mappings", volume=src_vol)
        src_attach_info = dest_attach_info = None
        if src_map.total != 0:
            msg = _("K2 driver does not support clone of an attached volume. "
                    "To get this done, create a snapshot from the attached "
                    "volume and then create a volume from the snapshot.")
            LOG.error(msg)
            raise exception.KaminarioCinderDriverException(reason=msg)
        try:
            properties = utils.brick_get_connector_properties()
            conn = self.initialize_connection(src_vref, properties)
            src_attach_info = self._connect_device(conn)
            self.create_volume(volume)
            conn = self.initialize_connection(volume, properties)
            dest_attach_info = self._connect_device(conn)
            vol_utils.copy_volume(src_attach_info['device']['path'],
                                  dest_attach_info['device']['path'],
                                  src_vref.size * units.Ki,
                                  self.configuration.volume_dd_blocksize,
                                  sparse=True)
            self._kaminario_disconnect_volume(src_attach_info,
                                              dest_attach_info)
            self.terminate_connection(volume, properties)
            self.terminate_connection(src_vref, properties)
        except Exception as ex:
            self._kaminario_disconnect_volume(src_attach_info,
                                              dest_attach_info)
            self.terminate_connection(src_vref, properties)
            self.terminate_connection(volume, properties)
            self.delete_volume(volume)
            LOG.exception("Create a clone: %s failed.", clone_name)
            raise exception.KaminarioCinderDriverException(reason=ex)
Beispiel #58
0
    def _create_volume_from_snap(self, volume, snap, size_in_m=None):
        """Creates a volume from a Unity snapshot.

        It attaches the `volume` and `snap`, then use `dd` to copy the
        data from the Unity snapshot to the `volume`.
        """
        model_update = self.create_volume(volume)
        # Update `provider_location` and `provider_id` of `volume` explicitly.
        volume.update(model_update)
        src_id = snap.get_id()
        dest_lun = self.client.get_lun(lun_id=self.get_lun_id(volume))
        try:
            conn_props = cinder_utils.brick_get_connector_properties()

            with self._connect_resource(dest_lun, conn_props,
                                        volume.id) as dest_info, \
                    self._connect_resource(snap, conn_props,
                                           src_id) as src_info:
                if size_in_m is None:
                    # If size is not specified, need to get the size from LUN
                    # of snapshot.
                    lun = self.client.get_lun(
                        lun_id=snap.storage_resource.get_id())
                    size_in_m = utils.byte_to_mib(lun.size_total)
                vol_utils.copy_volume(
                    src_info['device']['path'],
                    dest_info['device']['path'],
                    size_in_m,
                    self.driver.configuration.volume_dd_blocksize,
                    sparse=True)
        except Exception:
            with excutils.save_and_reraise_exception():
                utils.ignore_exception(self.delete_volume, volume)
                LOG.error(
                    'Failed to create cloned volume: %(vol_id)s, '
                    'from source unity snapshot: %(snap_name)s.', {
                        'vol_id': volume.id,
                        'snap_name': snap.name
                    })

        return model_update
Beispiel #59
0
    def test_brick_get_connector_properties(self):

        self.mox.StubOutWithMock(socket, 'gethostname')
        socket.gethostname().AndReturn('fakehost')

        self.mox.StubOutWithMock(connector.ISCSIConnector, 'get_initiator')
        connector.ISCSIConnector.get_initiator().AndReturn('fakeinitiator')

        self.mox.StubOutWithMock(linuxfc.LinuxFibreChannel, 'get_fc_wwpns')
        linuxfc.LinuxFibreChannel.get_fc_wwpns().AndReturn(None)

        self.mox.StubOutWithMock(linuxfc.LinuxFibreChannel, 'get_fc_wwnns')
        linuxfc.LinuxFibreChannel.get_fc_wwnns().AndReturn(None)

        props = {'initiator': 'fakeinitiator',
                 'host': 'fakehost',
                 'ip': CONF.my_ip,
                 }

        self.mox.ReplayAll()
        props_actual = utils.brick_get_connector_properties()
        self.assertEqual(props, props_actual)
        self.mox.VerifyAll()
Beispiel #60
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        LOG.info(
            _LI("ScaleIO copy_image_to_volume volume: %(vol)s image service: "
                "%(service)s image id: %(id)s."), {
                    'vol': volume,
                    'service': six.text_type(image_service),
                    'id': six.text_type(image_id)
                })
        properties = utils.brick_get_connector_properties()
        sdc_ip = properties['ip']
        LOG.debug("SDC ip is: %s", sdc_ip)

        try:
            image_utils.fetch_to_raw(context,
                                     image_service,
                                     image_id,
                                     self._sio_attach_volume(volume, sdc_ip),
                                     BLOCK_SIZE,
                                     size=volume['size'])

        finally:
            self._sio_detach_volume(volume, sdc_ip)