Exemple #1
0
    def restore_backup(self, sg_client, backup, restore_volume, device):
        driver_data = jsonutils.loads(backup.driver_data)
        vol_id = driver_data['volume_id']
        vol_size = backup['size']
        backup_id = driver_data['backup_id']
        # backup_type: local, remote
        backup_type = backup['destination']
        # new volume id
        new_vol_id = restore_volume.id
        new_vol_size = restore_volume.size * GB_SIZE
        new_device = device

        try:
            res = self.backup_ctrl(sg_client).RestoreBackup(
                backup_id, backup_type, vol_id, vol_size, new_vol_id,
                new_vol_size, new_device)
        except Exception as exc:
            msg = (_LE('restore backup failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('restore backup failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #2
0
def get_admin_client():
    if CONF.sgs_client.sgs_ca_cert_file:
        verify = CONF.sgs_client.sgs_ca_cert_file
    else:
        verify = False

    try:
        session = utils.get_admin_session(
            auth_url=CONF.sgs_client.keystone_auth_url,
            username=CONF.sgs_client.sgs_admin_username,
            password=CONF.sgs_client.sgs_admin_password,
            project_name=CONF.sgs_client.sgs_admin_tenant_name,
            project_domain_name=CONF.sgs_client.sgs_admin_tenant_domain,
            user_domain_name=CONF.sgs_client.sgs_admin_tenant_domain,
            verify=verify,
            timeout=CONF.sgs_client.timeout)

        client = sc.Client(session=session,
                           version=CONF.sgs_client.sgs_version,
                           connect_retries=3,
                           region_name=CONF.sgs_client.region_name)
        return client
    except keystone_exception.Unauthorized:
        with excutils.save_and_reraise_exception():
            LOG.error(_LE('Token unauthorized failed for keystoneclient '
                          'constructed when get admin client'))
    except sgs_exception.Unauthorized:
        with excutils.save_and_reraise_exception():
            LOG.error(_LE('Token unauthorized failed for sgsClient '
                          'constructed'))
    except Exception:
        with excutils.save_and_reraise_exception():
            LOG.error(_LE('Failed to get sgs python client.'))
Exemple #3
0
    def disable_sg(self, sg_client, volume):
        try:
            res = self.volume_ctrl(sg_client).DisableSG(volume.id)
        except Exception as exc:
            msg = (_LE('disable sg failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('disable sg failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #4
0
    def detach_volume(self, sg_client, volume):
        try:
            res = self.volume_ctrl(sg_client).DetachVolume(volume.id)
        except Exception as exc:
            msg = (_LE('detach volume failed, err:%s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('detach volume failed, err_no:%s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #5
0
    def list_devices(self, sg_client):
        try:
            res = self.volume_ctrl(sg_client).ListDevices()
        except Exception as exc:
            msg = (_LE('list devices failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('list devices failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
        return res.devices
Exemple #6
0
    def create_volume_from_snapshot(self, sg_client, snapshot, new_volume_id,
                                    device):
        try:
            res = self.snap_ctrl(sg_client).CreateVolumeFromSnap(
                snapshot.volume_id, snapshot.id, new_volume_id, device)
        except Exception as exc:
            msg = (_LE('create volume from snapshot failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.header.status != 0:
            msg = (_LE('create volume from snapshot failed, '
                       'err_noe: %s'), res.header.status)
            raise exception.SGDriverError(reason=msg)
Exemple #7
0
    def terminate_connection(self, sg_client, volume, mode, device=None):
        mode = CLIENT_MODE_MAPPING.get(mode, common_pb2.ISCSI_MODE)
        try:
            res = self.volume_ctrl(sg_client).TerminateConnection(
                volume.id, mode, device)
        except Exception as exc:
            msg = (_LE('terminate connection failed, err:%s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('terminate connection failed, err_no:%s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #8
0
    def query_volume_from_snapshot(self, sg_client, new_volume_id):
        try:
            res = self.snap_ctrl(sg_client).QueryVolumeFromSnap(new_volume_id)
        except Exception as exc:
            msg = (_LE('query volume from snapshot failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.header.status != 0:
            msg = (_LE('query volume from snapshot failed, '
                       'err_noe: %s'), res.header.status)
            raise exception.SGDriverError(reason=msg)
        return {'id': new_volume_id,
                'status': VOLUME_STATUS_MAPPING[res.vol_status]}
Exemple #9
0
    def enable_sg(self, sg_client, volume, device):
        vol_size = volume.size * GB_SIZE
        try:
            res = self.volume_ctrl(sg_client).EnableSG(
                volume.id, vol_size, device)
        except Exception as exc:
            msg = (_LE('enable sg failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('enable sg failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #10
0
    def report_state(self):
        """Update the state of this service in the datastore."""
        if not self.manager.is_working():
            # NOTE(dulek): If manager reports a problem we're not sending
            # heartbeats - to indicate that service is actually down.
            LOG.error(_LE('Manager for service %(binary)s %(host)s is '
                          'reporting problems, not sending heartbeat. '
                          'Service will appear "down".'),
                      {'binary': self.binary,
                       'host': self.host})
            return

        ctxt = context.get_admin_context()
        state_catalog = {}
        try:
            try:
                service_ref = db.service_get(ctxt, self.service_id)
            except exception.NotFound:
                LOG.debug('The service database object disappeared, '
                          'recreating it.')
                self._create_service_ref(ctxt)
                service_ref = db.service_get(ctxt, self.service_id)

            state_catalog['report_count'] = service_ref['report_count'] + 1

            db.service_update(ctxt,
                              self.service_id, state_catalog)

            # TODO(termie): make this pattern be more elegant.
            if getattr(self, 'model_disconnected', False):
                self.model_disconnected = False
                LOG.error(_LE('Recovered model server connection!'))

        except db_exc.DBConnectionError:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('model server went away'))

        # NOTE(jsbryant) Other DB errors can happen in HA configurations.
        # such errors shouldn't kill this thread, so we handle them here.
        except db_exc.DBError:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('DBError encountered: '))

        except Exception:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('Exception encountered: '))
Exemple #11
0
    def delete_backup(self, sg_client, backup):
        vol_id = backup.volume_id
        backup_id = backup.id

        try:
            res = self.backup_ctrl(sg_client).DeleteBackup(backup_id, vol_id)
        except Exception as exc:
            msg = (_LE('delete backup failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('delete backup failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #12
0
    def reverse_replicate(self, sg_client, volume):
        vol_id = volume.id
        role = REPLICATE_ROLE_MAPPING[volume.replicate_mode]
        try:
            res = self.replicate_ctrl(sg_client).ReverseReplication(
                vol_id, role)
        except Exception as exc:
            msg = (_LE('reverse replicate failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('reverse replicate failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #13
0
    def __exit__(self, ex_type, ex_value, ex_traceback):
        if not ex_value:
            return True

        if isinstance(ex_value, exception.NotAuthorized):
            raise Fault(webob.exc.HTTPForbidden(explanation=ex_value.msg))
        elif isinstance(ex_value, exception.Invalid):
            raise Fault(
                exception.ConvertedException(code=ex_value.code,
                                             explanation=ex_value.msg))
        elif isinstance(ex_value, TypeError):
            exc_info = (ex_type, ex_value, ex_traceback)
            LOG.error(_LE('Exception handling resource: %s'),
                      ex_value,
                      exc_info=exc_info)
            raise Fault(webob.exc.HTTPBadRequest())
        elif isinstance(ex_value, Fault):
            LOG.info(_LI("Fault thrown: %s"), ex_value)
            raise ex_value
        elif isinstance(ex_value, webob.exc.HTTPException):
            LOG.info(_LI("HTTP exception thrown: %s"), ex_value)
            raise Fault(ex_value)

        # We didn't handle the exception
        return False
Exemple #14
0
    def get_method(self, request, action, content_type, body):
        """Look up the action-specific method and its extensions."""

        # Look up the method
        try:
            if not self.controller:
                meth = getattr(self, action)
            else:
                meth = getattr(self.controller, action)
        except AttributeError as e:
            with excutils.save_and_reraise_exception(e) as ctxt:
                if (not self.wsgi_actions or action
                        not in ['action', 'create', 'delete', 'update']):
                    LOG.exception(_LE('Get method error.'))
                else:
                    ctxt.reraise = False
        else:
            return meth, self.wsgi_extensions.get(action, [])

        if action == 'action':
            # OK, it's an action; figure out which action...
            mtype = _MEDIA_TYPE_MAP.get(content_type)
            action_name = self.action_peek[mtype](body)
            LOG.debug("Action body: %s", body)
        else:
            action_name = action

        # Look up the action method
        return (self.wsgi_actions[action_name],
                self.wsgi_action_extensions.get(action_name, []))
Exemple #15
0
    def _error(self, inner, req):
        LOG.exception(_LE("Caught error: %(type)s %(error)s"), {
            'type': type(inner),
            'error': inner
        })
        safe = getattr(inner, 'safe', False)
        headers = getattr(inner, 'headers', None)
        status = getattr(inner, 'code', 500)
        if status is None:
            status = 500

        msg_dict = dict(url=req.url, status=status)
        LOG.info(_LI("%(url)s returned with HTTP %(status)d"), msg_dict)
        outer = self.status_to_type(status)
        if headers:
            outer.headers = headers
        # NOTE(johannes): We leave the explanation empty here on
        # purpose. It could possibly have sensitive information
        # that should not be returned back to the user. See
        # bugs 868360 and 874472
        # NOTE(eglynn): However, it would be over-conservative and
        # inconsistent with the EC2 API to hide every exception,
        # including those that are safe to expose, see bug 1021373
        if safe:
            msg = (inner.msg if isinstance(inner, exception.SGServiceException)
                   else six.text_type(inner))
            params = {
                'exception': inner.__class__.__name__,
                'explanation': msg
            }
            outer.explanation = _('%(exception)s: %(explanation)s') % params
        return wsgi.Fault(outer)
Exemple #16
0
    def __init__(self, message=None, **kwargs):
        """Initiate the instance of SGServiceException

        There are two ways to initiate the instance.
        1. Specify the value of 'message' and leave the 'kwargs' None.
        2. Leave 'message' None, and specify the keyword arguments matched
           with the format of SGServiceException.message. Especially, can't
           use the 'message' as the key in the 'kwargs', otherwise, the
           first argument('message') will be set.

        Note: This class doesn't support to create instance of
            SGServiceException with another instance.
        """
        self.kwargs = kwargs

        if 'code' not in self.kwargs:
            try:
                self.kwargs['code'] = self.code
            except AttributeError:
                pass

        if not message:
            try:
                message = self.message % kwargs

            except Exception:
                exc_info = sys.exc_info()
                # kwargs doesn't match a variable in the message
                # log the issue and the kwargs
                LOG.exception(_LE('Exception in string format operation'))
                for name, value in kwargs.items():
                    LOG.error(_LE("%(name)s: %(value)s"), {
                        'name': name,
                        'value': value
                    })
                if CONF.fatal_exception_format_errors:
                    six.reraise(*exc_info)
                # at least get the core message out if something happened
                message = self.message
        elif isinstance(message, Exception):
            message = six.text_type(message)

        # NOTE(luisg): We put the actual message in 'msg' so that we can access
        # it, because if we try to access the message via 'message' it will be
        # overshadowed by the class' message attribute
        self.msg = message
        super(SGServiceException, self).__init__(message)
Exemple #17
0
    def failover_replicate(self, sg_client, volume, checkpoint_id,
                           snapshot_id):
        vol_id = volume.id
        role = REPLICATE_ROLE_MAPPING[volume.replicate_mode]
        try:
            res = self.replicate_ctrl(sg_client).FailoverReplication(
                vol_id, role, checkpoint_id=checkpoint_id,
                snapshot_id=snapshot_id)
        except Exception as exc:
            msg = (_LE('failover replicate failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('failover replicate failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #18
0
    def create_replicate(self, sg_client, volume):
        rep_uuid = volume.replication_id
        role = REPLICATE_ROLE_MAPPING[volume.replicate_mode]
        local_volume = volume.id
        peer_volumes = [volume.peer_volume]
        try:
            res = self.replicate_ctrl(sg_client).CreateReplication(
                rep_uuid, local_volume, role, peer_volumes)
        except Exception as exc:
            msg = (_LE('create replicate failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('create replicate failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #19
0
    def start(self):
        """Start serving a WSGI application.

        :returns: None
        :raises: sgservice.exception.InvalidInput

        """
        # The server socket object will be closed after server exits,
        # but the underlying file descriptor will remain open, and will
        # give bad file descriptor error. So duplicating the socket object,
        # to keep file descriptor usable.

        dup_socket = self._socket.dup()
        dup_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        # NOTE(praneshp): Call set_tcp_keepalive in oslo to set
        # tcp keepalive parameters. Sockets can hang around forever
        # without keepalive
        netutils.set_tcp_keepalive(dup_socket, CONF.tcp_keepalive,
                                   CONF.tcp_keepidle, CONF.tcp_keepalive_count,
                                   CONF.tcp_keepalive_interval)

        if self._use_ssl:
            try:
                ssl_kwargs = {
                    'server_side': True,
                    'certfile': CONF.ssl_cert_file,
                    'keyfile': CONF.ssl_key_file,
                    'cert_reqs': ssl.CERT_NONE,
                }

                if CONF.ssl_ca_file:
                    ssl_kwargs['ca_certs'] = CONF.ssl_ca_file
                    ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED

                dup_socket = ssl.wrap_socket(dup_socket, **ssl_kwargs)
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.error(
                        _LE("Failed to start %(name)s on %(_host)s: "
                            "%(_port)s with SSL "
                            "support."), self.__dict__)

        wsgi_kwargs = {
            'func': eventlet.wsgi.server,
            'sock': dup_socket,
            'site': self.app,
            'protocol': self._protocol,
            'custom_pool': self._pool,
            'log': self._logger,
            'socket_timeout': self.client_socket_timeout,
            'keepalive': CONF.wsgi_keep_alive
        }

        self._server = eventlet.spawn(**wsgi_kwargs)
Exemple #20
0
    def create_backup(self, sg_client, backup):
        # backup_mode: full, incremental
        backup_mode = backup.type
        # backup_type: local, remote
        backup_type = backup.destination
        vol_id = backup.volume_id
        vol_size = backup.size * GB_SIZE
        backup_id = backup.id

        try:
            res = self.backup_ctrl(sg_client).CreateBackup(
                backup_mode, backup_type, vol_id, vol_size, backup_id)
        except Exception as exc:
            msg = (_LE('create backup failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('create backup failed, err_no: %s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #21
0
    def rollback_snapshot(self, sg_client, snapshot):
        vol_id = snapshot.volume_id
        snap_id = snapshot.id
        snap_type = snapshot.destination
        if snapshot.checkpoint_id:
            checkpoint_uuid = snapshot.checkpoint_id
        else:
            checkpoint_uuid = None

        try:
            res = self.snap_ctrl(sg_client).RollbackSnapshot(
                snap_type, vol_id, snap_id, checkpoint_uuid)
        except Exception as exc:
            msg = (_LE('rollback snapshot failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.header.status != 0:
            msg = (_LE('rollback snapshot failed, err_no: %s'),
                   res.header.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
Exemple #22
0
    def get_backup(self, sg_client, backup):
        vol_id = backup.volume_id
        backup_id = backup.id

        try:
            res = self.backup_ctrl(sg_client).GetBackup(backup_id, vol_id)
        except Exception as exc:
            msg = (_LE('get backup failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            if res.status == common_pb2.sBackupNotExist:
                backup = {'id': backup.id,
                          'status': fields.BackupStatus.DELETED}
            else:
                msg = (_LE('get backup failed, err_no: %s'), res.status)
                LOG.error(msg)
                raise exception.SGDriverError(reason=msg)
        else:
            backup = {'id': backup.id,
                      'status': BACKUP_STATUS_MAPPING[res.backup_status]}
        return backup
Exemple #23
0
def get_project_context_client(context):
    try:
        url = utils.get_management_url(
            auth_url=CONF.nova_client.keystone_auth_url,
            tenant_name=CONF.nova_client.nova_admin_tenant_name,
            username=CONF.nova_client.nova_admin_username,
            password=CONF.nova_client.nova_admin_password,
            region_name=CONF.nova_client.region_name,
            service_type=CONF.nova_client.service_type,
            insecure=CONF.nova_client.nova_auth_insecure,
            cacert=CONF.nova_client.nova_ca_cert_file)
        management_url = url + '/' + context.project_id
        args = {
            'project_id': context.project_id,
            'auth_url': CONF.nova_client.keystone_auth_url,
            'service_type': CONF.nova_client.service_type,
            'region_name': CONF.nova_client.region_name,
            'username': context.user_id,
            'insecure': CONF.nova_client.nova_auth_insecure,
            'cacert': CONF.nova_client.nova_ca_cert_file,
            'timeout': CONF.nova_client.timeout,
            'auth_token': context.auth_token
        }
        client = nc.Client(CONF.nova_client.nova_version, **args)
        client.client.management_url = management_url
        return client
    except keystone_exception.Unauthorized:
        with excutils.save_and_reraise_exception():
            LOG.error(_LE('Token unauthorized failed for keystoneclient '
                          'constructed when get admin novaClient'))
    except nova_exception.Unauthorized:
        with excutils.save_and_reraise_exception():
            LOG.error(_LE('Token unauthorized failed for novaClient '
                          'constructed'))
    except Exception:
        with excutils.save_and_reraise_exception():
            LOG.error(_LE('Failed to get nova python client.'))
Exemple #24
0
    def get_snapshot(self, sg_client, snapshot):
        vol_id = snapshot.volume_id
        snap_id = snapshot.id

        try:
            res = self.snap_ctrl(sg_client).GetSnapshot(vol_id, snap_id)
        except Exception as exc:
            msg = (_LE('get snapshot failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.header.status != 0:
            if res.header.status == common_pb2.sSnapNotExist:
                snapshot = {'id': snapshot.id,
                            'status': fields.SnapshotStatus.DELETED}
            else:
                msg = (_LE('get snapshot failed, err_no: %s'),
                       res.header.status)
                LOG.error(msg)
                raise exception.SGDriverError(reason=msg)
        else:
            snapshot = {'id': snapshot.id,
                        'status': SNAPSHOT_STATUS_MAPPING[res.snap_status]}
        return snapshot
Exemple #25
0
    def initialize_connection(self, sg_client, volume, mode):
        mode = CLIENT_MODE_MAPPING.get(mode, common_pb2.ISCSI_MODE)
        try:
            res = self.volume_ctrl(sg_client).InitializeConnection(
                volume.id, mode)
        except Exception as exc:
            msg = (_LE('initialize connection failed, err:%s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            msg = (_LE('initialize connection failed, err_no:%s'), res.status)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)
        if mode == common_pb2.ISCSI_MODE:
            target_portal = "%s:3260" % sg_client.host
            target_iqn = res.connection_info['target_iqn']
            target_lun = int(res.connection_info['target_lun'])
            connection_info = {
                'target_portal': target_portal,
                'target_iqn': target_iqn,
                'target_lun': target_lun,
            }
            return connection_info
Exemple #26
0
    def get_volume(self, sg_client, volume):
        try:
            res = self.volume_ctrl(sg_client).GetVolume(volume.id)
        except Exception as exc:
            msg = (_LE('get volume  failed, err: %s'), exc)
            LOG.error(msg)
            raise exception.SGDriverError(reason=msg)

        if res.status != 0:
            volume = {'id': volume.id,
                      'status': fields.VolumeStatus.DELETED,
                      'replicate_status': fields.ReplicateStatus.DELETED}
            return volume

        status = VOLUME_STATUS_MAPPING[res.volume.vol_status]
        replicate_status = REPLICATE_STATUS_MAPPING[res.volume.rep_status]

        volume = {
            'id': volume.id,
            'status': status,
            'replicate_status': replicate_status,
            'replicate_mode': ROLE_REPLICATE_MAPPING.get(res.volume.role,
                                                         None)}
        return volume