예제 #1
0
 def check_param(self):
     """Check parameter values and consistency among them."""
     utils.check_opt_value(self.conf, _INHERITED_VOLUME_OPTS)
     utils.check_opts(self.conf, COMMON_VOLUME_OPTS)
     utils.check_opts(self.conf, self.driver_info['volume_opts'])
     if self.conf.hitachi_ldev_range:
         self.storage_info['ldev_range'] = self._range2list(
             'hitachi_ldev_range')
     if (not self.conf.hitachi_target_ports
             and not self.conf.hitachi_compute_target_ports):
         msg = utils.output_log(MSG.INVALID_PARAMETER,
                                param='hitachi_target_ports or '
                                'hitachi_compute_target_ports')
         raise utils.HBSDError(msg)
     if (self.conf.hitachi_group_delete
             and not self.conf.hitachi_group_create):
         msg = utils.output_log(MSG.INVALID_PARAMETER,
                                param='hitachi_group_delete or '
                                'hitachi_group_create')
         raise utils.HBSDError(msg)
     for opt in _REQUIRED_COMMON_OPTS:
         if not self.conf.safe_get(opt):
             msg = utils.output_log(MSG.INVALID_PARAMETER, param=opt)
             raise utils.HBSDError(msg)
     if self.storage_info['protocol'] == 'iSCSI':
         self.check_param_iscsi()
예제 #2
0
    def check_pool_id(self):
        """Check the pool id of hitachi_pool and hitachi_snap_pool."""
        pool = self.conf.hitachi_pool
        if pool is not None:
            if pool.isdigit():
                self.storage_info['pool_id'] = int(pool)
            else:
                self.storage_info['pool_id'] = self._get_pool_id(pool)
        if self.storage_info['pool_id'] is None:
            msg = utils.output_log(MSG.POOL_NOT_FOUND,
                                   pool=self.conf.hitachi_pool)
            raise utils.HBSDError(msg)

        snap_pool = self.conf.hitachi_snap_pool
        if snap_pool is not None:
            if snap_pool.isdigit():
                self.storage_info['snap_pool_id'] = int(snap_pool)
            else:
                self.storage_info['snap_pool_id'] = (
                    self._get_pool_id(snap_pool))
                if self.storage_info['snap_pool_id'] is None:
                    msg = utils.output_log(MSG.POOL_NOT_FOUND,
                                           pool=self.conf.hitachi_snap_pool)
                    raise utils.HBSDError(msg)
        else:
            self.storage_info['snap_pool_id'] = self.storage_info['pool_id']
예제 #3
0
 def check_param_iscsi(self):
     """Check iSCSI-related parameter values and consistency among them."""
     if self.conf.use_chap_auth:
         if not self.conf.chap_username:
             msg = utils.output_log(MSG.INVALID_PARAMETER,
                                    param='chap_username')
             raise utils.HBSDError(msg)
         if not self.conf.chap_password:
             msg = utils.output_log(MSG.INVALID_PARAMETER,
                                    param='chap_password')
             raise utils.HBSDError(msg)
예제 #4
0
 def extend_volume(self, volume, new_size):
     """Extend the specified volume to the specified size."""
     ldev = utils.get_ldev(volume)
     if ldev is None:
         msg = utils.output_log(MSG.INVALID_LDEV_FOR_EXTENSION,
                                volume_id=volume['id'])
         raise utils.HBSDError(msg)
     if self.check_pair_svol(ldev):
         msg = utils.output_log(MSG.INVALID_VOLUME_TYPE_FOR_EXTEND,
                                volume_id=volume['id'])
         raise utils.HBSDError(msg)
     self.delete_pair(ldev)
     self.extend_ldev(ldev, volume['size'], new_size)
예제 #5
0
파일: hbsd_rest.py 프로젝트: crowdy/cinder
 def _create_clone_pair(self, pvol, svol):
     """Create a clone copy pair on the storage."""
     snapshot_name = '%(prefix)s%(svol)s' % {
         'prefix': CLONE_NAME,
         'svol': svol % _SNAP_HASH_SIZE,
     }
     try:
         body = {"snapshotGroupName": snapshot_name,
                 "snapshotPoolId": self.storage_info['snap_pool_id'],
                 "pvolLdevId": pvol,
                 "svolLdevId": svol,
                 "isClone": True,
                 "clonesAutomation": True,
                 "copySpeed": 'medium',
                 "isDataReductionForceCopy": True}
         self.client.add_snapshot(body)
     except utils.HBSDError as ex:
         if (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
                 rest_api.INVALID_SNAPSHOT_POOL and
                 not self.conf.hitachi_snap_pool):
             msg = utils.output_log(
                 MSG.INVALID_PARAMETER, param='hitachi_snap_pool')
             raise utils.HBSDError(msg)
         else:
             raise
     try:
         self._wait_copy_pair_status(svol, set([PSUS, SMPP, SMPL]))
     except Exception:
         with excutils.save_and_reraise_exception():
             try:
                 self._delete_pair_from_storage(pvol, svol)
             except utils.HBSDError:
                 utils.output_log(
                     MSG.DELETE_PAIR_FAILED, pvol=pvol, svol=svol)
예제 #6
0
 def get_hba_ids_from_connector(self, connector):
     """Return the HBA ID stored in the connector."""
     if self.driver_info['hba_id'] in connector:
         return connector[self.driver_info['hba_id']]
     msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                            resource=self.driver_info['hba_id_type'])
     raise utils.HBSDError(msg)
예제 #7
0
 def _range2list(self, param):
     """Analyze a 'xxx-xxx' string and return a list of two integers."""
     values = [_str2int(value) for value in
               self.conf.safe_get(param).split('-')]
     if len(values) != 2 or None in values or values[0] > values[1]:
         msg = utils.output_log(MSG.INVALID_PARAMETER, param=param)
         raise utils.HBSDError(msg)
     return values
예제 #8
0
 def check_ports_info(self):
     """Check if available storage ports exist."""
     if (self.conf.hitachi_target_ports and
             not self.storage_info['controller_ports']):
         msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                                resource="Target ports")
         raise utils.HBSDError(msg)
     if (self.conf.hitachi_compute_target_ports and
             not self.storage_info['compute_ports']):
         msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                                resource="Compute target ports")
         raise utils.HBSDError(msg)
     utils.output_log(MSG.SET_CONFIG_VALUE, object='target port list',
                      value=self.storage_info['controller_ports'])
     utils.output_log(MSG.SET_CONFIG_VALUE,
                      object='compute target port list',
                      value=self.storage_info['compute_ports'])
예제 #9
0
파일: hbsd_rest.py 프로젝트: crowdy/cinder
 def update_group(self, group, add_volumes=None):
     if add_volumes and volume_utils.is_group_a_cg_snapshot_type(group):
         for volume in add_volumes:
             ldev = utils.get_ldev(volume)
             if ldev is None:
                 msg = utils.output_log(MSG.LDEV_NOT_EXIST_FOR_ADD_GROUP,
                                        volume_id=volume.id,
                                        group='consistency group',
                                        group_id=group.id)
                 raise utils.HBSDError(msg)
     return None, None, None
예제 #10
0
파일: hbsd_rest.py 프로젝트: crowdy/cinder
    def create_group_from_src(
            self, context, group, volumes, snapshots=None, source_vols=None):
        volumes_model_update = []
        new_ldevs = []
        events = []

        def _create_group_volume_from_src(context, volume, src, from_snapshot):
            volume_model_update = {'id': volume.id}
            try:
                ldev = utils.get_ldev(src)
                if ldev is None:
                    msg = utils.output_log(
                        MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                        type='snapshot' if from_snapshot else 'volume',
                        id=src.id)
                    raise utils.HBSDError(msg)
                volume_model_update.update(
                    self.create_volume_from_snapshot(volume, src) if
                    from_snapshot else self.create_cloned_volume(volume,
                                                                 src))
            except Exception as exc:
                volume_model_update['msg'] = utils.get_exception_msg(exc)
            raise loopingcall.LoopingCallDone(volume_model_update)

        try:
            from_snapshot = True if snapshots else False
            for volume, src in zip(volumes,
                                   snapshots if snapshots else source_vols):
                loop = loopingcall.FixedIntervalLoopingCall(
                    _create_group_volume_from_src, context, volume, src,
                    from_snapshot)
                event = loop.start(interval=0)
                events.append(event)
            is_success = True
            for e in events:
                volume_model_update = e.wait()
                if 'msg' in volume_model_update:
                    is_success = False
                    msg = volume_model_update['msg']
                else:
                    volumes_model_update.append(volume_model_update)
                ldev = utils.get_ldev(volume_model_update)
                if ldev is not None:
                    new_ldevs.append(ldev)
            if not is_success:
                raise utils.HBSDError(msg)
        except Exception:
            with excutils.save_and_reraise_exception():
                for new_ldev in new_ldevs:
                    try:
                        self.delete_ldev(new_ldev)
                    except utils.HBSDError:
                        utils.output_log(MSG.DELETE_LDEV_FAILED, ldev=new_ldev)
        return None, volumes_model_update
예제 #11
0
 def check_param(self):
     """Check parameter values and consistency among them."""
     super(HBSDREST, self).check_param()
     utils.check_opts(self.conf, REST_VOLUME_OPTS)
     utils.check_opts(self.conf, san.san_opts)
     LOG.debug('Setting ldev_range: %s', self.storage_info['ldev_range'])
     for opt in _REQUIRED_REST_OPTS:
         if not self.conf.safe_get(opt):
             msg = utils.output_log(MSG.INVALID_PARAMETER, param=opt)
             raise utils.HBSDError(msg)
     if not self.conf.safe_get('san_api_port'):
         self.conf.san_api_port = _REST_DEFAULT_PORT
예제 #12
0
 def create_snapshot(self, snapshot):
     """Create a snapshot from a volume and return its properties."""
     src_vref = snapshot.volume
     ldev = utils.get_ldev(src_vref)
     if ldev is None:
         msg = utils.output_log(MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                                type='volume',
                                id=src_vref['id'])
         raise utils.HBSDError(msg)
     size = snapshot['volume_size']
     new_ldev = self._copy_on_storage(ldev, size, True)
     return {
         'provider_location': str(new_ldev),
     }
예제 #13
0
파일: hbsd_rest.py 프로젝트: crowdy/cinder
 def _create_cgsnapshot_volume(snapshot):
     pair = {'snapshot': snapshot}
     try:
         pair['pvol'] = utils.get_ldev(snapshot.volume)
         if pair['pvol'] is None:
             msg = utils.output_log(
                 MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                 type='volume', id=snapshot.volume_id)
             raise utils.HBSDError(msg)
         size = snapshot.volume_size
         pair['svol'] = self.create_ldev(size)
     except Exception as exc:
         pair['msg'] = utils.get_exception_msg(exc)
     raise loopingcall.LoopingCallDone(pair)
예제 #14
0
 def set_hba_ids(self, port, gid, hba_ids):
     """Connect all specified HBAs with the specified port."""
     registered_wwns = []
     for wwn in hba_ids:
         try:
             self.client.add_hba_wwn(port, gid, wwn, no_log=True)
             registered_wwns.append(wwn)
         except utils.HBSDError:
             utils.output_log(MSG.ADD_HBA_WWN_FAILED, port=port, gid=gid,
                              wwn=wwn)
     if not registered_wwns:
         msg = utils.output_log(MSG.NO_HBA_WWN_ADDED_TO_HOST_GRP, port=port,
                                gid=gid)
         raise utils.HBSDError(msg)
예제 #15
0
파일: hbsd_rest.py 프로젝트: crowdy/cinder
 def _create_ctg_snap_pair(self, pairs):
     snapshotgroup_name = self._create_ctg_snapshot_group_name(
         pairs[0]['pvol'])
     try:
         for pair in pairs:
             try:
                 body = {"snapshotGroupName": snapshotgroup_name,
                         "snapshotPoolId":
                             self.storage_info['snap_pool_id'],
                         "pvolLdevId": pair['pvol'],
                         "svolLdevId": pair['svol'],
                         "isConsistencyGroup": True,
                         "canCascade": True,
                         "isDataReductionForceCopy": True}
                 self.client.add_snapshot(body)
             except utils.HBSDError as ex:
                 if ((utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
                      _MAX_CTG_COUNT_EXCEEDED_ADD_SNAPSHOT) or
                     (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
                      _MAX_PAIR_COUNT_IN_CTG_EXCEEDED_ADD_SNAPSHOT)):
                     msg = utils.output_log(MSG.FAILED_CREATE_CTG_SNAPSHOT)
                     raise utils.HBSDError(msg)
                 elif (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
                         rest_api.INVALID_SNAPSHOT_POOL and
                         not self.conf.hitachi_snap_pool):
                     msg = utils.output_log(
                         MSG.INVALID_PARAMETER, param='hitachi_snap_pool')
                     raise utils.HBSDError(msg)
                 raise
             self._wait_copy_pair_status(pair['svol'], PAIR)
         self.client.split_snapshotgroup(snapshotgroup_name)
         for pair in pairs:
             self._wait_copy_pair_status(pair['svol'], PSUS)
     except Exception:
         with excutils.save_and_reraise_exception():
             self._delete_pairs_from_storage(pairs)
예제 #16
0
    def get_pool_info(self):
        """Return the total and free capacity of the storage pool."""
        result = self.client.get_pool(
            self.storage_info['pool_id'],
            ignore_message_id=[rest_api.MSGID_SPECIFIED_OBJECT_DOES_NOT_EXIST])

        if 'errorSource' in result:
            msg = utils.output_log(MSG.POOL_NOT_FOUND,
                                   pool=self.storage_info['pool_id'])
            raise utils.HBSDError(msg)

        tp_cap = result['totalPoolCapacity'] / units.Ki
        ta_cap = result['availableVolumeCapacity'] / units.Ki
        tl_cap = result['totalLocatedCapacity'] / units.Ki

        return tp_cap, ta_cap, tl_cap
예제 #17
0
    def _wait_copy_pair_deleting(self, ldev):
        """Wait until the LDEV is no longer in a copy pair."""
        def _wait_for_copy_pair_smpl(start_time, ldev):
            """Raise True if the LDEV is no longer in a copy pair."""
            ldev_info = self.get_ldev_info(['status', 'attributes'], ldev)
            if (ldev_info['status'] != NORMAL_STS
                    or PAIR_ATTR not in ldev_info['attributes']):
                raise loopingcall.LoopingCallDone()
            if utils.timed_out(start_time, utils.DEFAULT_PROCESS_WAITTIME):
                raise loopingcall.LoopingCallDone(False)

        loop = loopingcall.FixedIntervalLoopingCall(_wait_for_copy_pair_smpl,
                                                    timeutils.utcnow(), ldev)
        if not loop.start(interval=10).wait():
            msg = utils.output_log(MSG.PAIR_STATUS_WAIT_TIMEOUT, svol=ldev)
            raise utils.HBSDError(msg)
예제 #18
0
 def _copy_on_storage(self, pvol, size, is_snapshot=False):
     """Create a copy of the specified LDEV on the storage."""
     ldev_info = self.get_ldev_info(['status', 'attributes'], pvol)
     if ldev_info['status'] != 'NML':
         msg = utils.output_log(MSG.INVALID_LDEV_STATUS_FOR_COPY, ldev=pvol)
         raise utils.HBSDError(msg)
     svol = self.create_ldev(size)
     try:
         self.create_pair_on_storage(pvol, svol, is_snapshot)
     except Exception:
         with excutils.save_and_reraise_exception():
             try:
                 self.delete_ldev(svol)
             except utils.HBSDError:
                 utils.output_log(MSG.DELETE_LDEV_FAILED, ldev=svol)
     return svol
예제 #19
0
    def create_volume_from_src(self, volume, src, src_type):
        """Create a volume from a volume or snapshot and return its properties.

        """
        ldev = utils.get_ldev(src)
        if ldev is None:
            msg = utils.output_log(
                MSG.INVALID_LDEV_FOR_VOLUME_COPY, type=src_type, id=src['id'])
            raise utils.HBSDError(msg)

        size = volume['size']
        new_ldev = self._copy_on_storage(ldev, size)
        self.modify_ldev_name(new_ldev, volume['id'].replace("-", ""))

        return {
            'provider_location': str(new_ldev),
        }
예제 #20
0
파일: hbsd_rest.py 프로젝트: crowdy/cinder
 def _create_group_volume_from_src(context, volume, src, from_snapshot):
     volume_model_update = {'id': volume.id}
     try:
         ldev = utils.get_ldev(src)
         if ldev is None:
             msg = utils.output_log(
                 MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                 type='snapshot' if from_snapshot else 'volume',
                 id=src.id)
             raise utils.HBSDError(msg)
         volume_model_update.update(
             self.create_volume_from_snapshot(volume, src) if
             from_snapshot else self.create_cloned_volume(volume,
                                                          src))
     except Exception as exc:
         volume_model_update['msg'] = utils.get_exception_msg(exc)
     raise loopingcall.LoopingCallDone(volume_model_update)
예제 #21
0
    def initialize_connection(self, volume, connector):
        """Initialize connection between the server and the volume."""
        targets = {
            'info': {},
            'list': [],
            'lun': {},
            'iqns': {},
            'target_map': {},
        }
        ldev = utils.get_ldev(volume)
        if ldev is None:
            msg = utils.output_log(MSG.INVALID_LDEV_FOR_CONNECTION,
                                   volume_id=volume['id'])
            raise utils.HBSDError(msg)

        target_lun = self.attach_ldev(volume, ldev, connector, targets)

        return {
            'driver_volume_type': self.driver_info['volume_type'],
            'data': self.get_properties(targets, target_lun, connector),
        }
예제 #22
0
    def _wait_copy_pair_status(self,
                               ldev,
                               status,
                               interval=3,
                               timeout=utils.DEFAULT_PROCESS_WAITTIME):
        """Wait until the S-VOL status changes to the specified status."""
        def _wait_for_copy_pair_status(start_time, ldev, status, timeout):
            """Raise True if the S-VOL is in the specified status."""
            if not isinstance(status, set):
                status = set([status])
            if self._get_copy_pair_status(ldev) in status:
                raise loopingcall.LoopingCallDone()
            if utils.timed_out(start_time, timeout):
                raise loopingcall.LoopingCallDone(False)

        loop = loopingcall.FixedIntervalLoopingCall(_wait_for_copy_pair_status,
                                                    timeutils.utcnow(), ldev,
                                                    status, timeout)
        if not loop.start(interval=interval).wait():
            msg = utils.output_log(MSG.PAIR_STATUS_WAIT_TIMEOUT, svol=ldev)
            raise utils.HBSDError(msg)
예제 #23
0
    def get_properties_iscsi(self, targets, multipath):
        """Return iSCSI-specific server-LDEV connection info."""
        if not multipath:
            target_list = targets['list'][:1]
        else:
            target_list = targets['list'][:]

        for target in target_list:
            if target not in targets['iqns']:
                port, gid = target
                target_info = self.client.get_host_grp(port, gid)
                iqn = target_info.get('iscsiName') if target_info else None
                if not iqn:
                    msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                                           resource='Target IQN')
                    raise utils.HBSDError(msg)
                targets['iqns'][target] = iqn
                LOG.debug(
                    'Found target iqn of host group. (port: %(port)s, '
                    'gid: %(gid)s, target iqn: %(iqn)s)',
                    {'port': port, 'gid': gid, 'iqn': iqn})
        return super(HBSDRESTISCSI, self).get_properties_iscsi(
            targets, multipath)
예제 #24
0
파일: hbsd_rest.py 프로젝트: crowdy/cinder
    def _create_cgsnapshot(self, context, cgsnapshot, snapshots):
        pairs = []
        events = []
        snapshots_model_update = []

        def _create_cgsnapshot_volume(snapshot):
            pair = {'snapshot': snapshot}
            try:
                pair['pvol'] = utils.get_ldev(snapshot.volume)
                if pair['pvol'] is None:
                    msg = utils.output_log(
                        MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                        type='volume', id=snapshot.volume_id)
                    raise utils.HBSDError(msg)
                size = snapshot.volume_size
                pair['svol'] = self.create_ldev(size)
            except Exception as exc:
                pair['msg'] = utils.get_exception_msg(exc)
            raise loopingcall.LoopingCallDone(pair)

        try:
            for snapshot in snapshots:
                ldev = utils.get_ldev(snapshot.volume)
                if ldev is None:
                    msg = utils.output_log(
                        MSG.INVALID_LDEV_FOR_VOLUME_COPY, type='volume',
                        id=snapshot.volume_id)
                    raise utils.HBSDError(msg)
            for snapshot in snapshots:
                loop = loopingcall.FixedIntervalLoopingCall(
                    _create_cgsnapshot_volume, snapshot)
                event = loop.start(interval=0)
                events.append(event)
            is_success = True
            for e in events:
                pair = e.wait()
                if 'msg' in pair:
                    is_success = False
                    msg = pair['msg']
                pairs.append(pair)
            if not is_success:
                raise utils.HBSDError(msg)
            self._create_ctg_snap_pair(pairs)
        except Exception:
            for pair in pairs:
                if 'svol' in pair and pair['svol'] is not None:
                    try:
                        self.delete_ldev(pair['svol'])
                    except utils.HBSDError:
                        utils.output_log(
                            MSG.DELETE_LDEV_FAILED, ldev=pair['svol'])
            model_update = {'status': fields.GroupSnapshotStatus.ERROR}
            for snapshot in snapshots:
                snapshot_model_update = {'id': snapshot.id,
                                         'status': fields.SnapshotStatus.ERROR}
                snapshots_model_update.append(snapshot_model_update)
            return model_update, snapshots_model_update
        for pair in pairs:
            snapshot_model_update = {
                'id': pair['snapshot'].id,
                'status': fields.SnapshotStatus.AVAILABLE,
                'provider_location': str(pair['svol'])}
            snapshots_model_update.append(snapshot_model_update)
        return None, snapshots_model_update
예제 #25
0
    def _request(self, method, url, params=None, body=None,
                 async_=False, **kwargs):
        """Transmit the request to REST API server."""
        kwargs.setdefault('ignore_error', [])
        kwargs['no_retry_error'] = (kwargs['ignore_error'] +
                                    REST_NO_RETRY_ERRORS)
        kwargs.setdefault('no_retry', False)
        kwargs.setdefault('do_raise', True)
        kwargs.setdefault('ignore_message_id', [])
        kwargs.setdefault('no_relogin', False)
        kwargs.setdefault('ignore_return_code', [])
        kwargs.setdefault('ignore_all_errors', False)
        kwargs.setdefault('timeout_message', None)
        kwargs.setdefault('no_log', False)
        kwargs.setdefault('timeout', _EXEC_MAX_WAITTIME)

        headers = dict(self.headers)
        if async_:
            read_timeout = (_JOB_API_RESPONSE_TIMEOUT +
                            _RESPONSE_TIMEOUT_TOLERANCE)
            headers.update({
                "Response-Max-Wait": str(_JOB_API_RESPONSE_TIMEOUT),
                "Response-Job-Status": "Completed;"})
        else:
            read_timeout = _GET_API_RESPONSE_TIMEOUT

        auth_data = kwargs.get('auth', self.get_my_session())

        timeout = (self.connect_timeout, read_timeout)

        interval = kwargs.get('interval', _EXEC_RETRY_INTERVAL)
        retry = True
        start_time = timeutils.utcnow()
        watch = timeutils.StopWatch()

        while retry:
            watch.restart()
            try:
                with requests.Session() as session:
                    if self.tcp_keepalive:
                        session.mount(_HTTPS, TCPKeepAliveAdapter())
                    rsp = session.request(method, url,
                                          params=params,
                                          json=body,
                                          headers=headers,
                                          auth=auth_data,
                                          timeout=timeout,
                                          verify=self.verify)

            except Exception as e:
                msg = utils.output_log(
                    MSG.REST_SERVER_CONNECT_FAILED,
                    exception=type(e), message=e,
                    method=method, url=url, params=params, body=body)
                raise utils.HBSDError(msg)

            response = ResponseData(rsp)
            if (response['status_code'] == httpclient.INTERNAL_SERVER_ERROR and
                    kwargs['timeout'] < _REST_SERVER_RESTART_TIMEOUT):
                kwargs['timeout'] = _REST_SERVER_RESTART_TIMEOUT
            if (response['status_code'] == httpclient.SERVICE_UNAVAILABLE and
                    kwargs['timeout'] < _REST_SERVER_ERROR_TIMEOUT):
                kwargs['timeout'] = _REST_SERVER_ERROR_TIMEOUT
            retry, rsp_data, errobj = self._check_rest_api_response(
                response, start_time,
                method=method, url=url, params=params, body=body, **kwargs)
            if retry:
                watch.stop()
                idle = max(interval - watch.elapsed(), 0)
                greenthread.sleep(idle)
                if not kwargs['no_relogin'] and response.is_auth_fail():
                    auth_data = self.get_my_session()

        return rsp_data, errobj
예제 #26
0
    def _check_rest_api_response(
            self, response, start_time, method=None,
            url=None, params=None, body=None, **kwargs):
        """Check the response from REST API server."""
        rsp_body = response['rsp_body']
        errobj = response['errobj']
        if response.is_locked():
            if (kwargs['no_retry'] or
                    utils.timed_out(start_time, _LOCK_WAITTIME)):
                msg = utils.output_log(MSG.REST_API_FAILED,
                                       no_log=kwargs['no_log'],
                                       method=method, url=url,
                                       params=params, body=body,
                                       **response.get_errobj())
                if kwargs['do_raise']:
                    raise utils.HBSDError(msg, errobj=errobj)
                return False, rsp_body, errobj
            else:
                LOG.debug("The resource group to which the operation object ",
                          "belongs is being locked by other software.")
                return True, rsp_body, errobj

        if response.is_success(kwargs['ignore_error'],
                               kwargs['ignore_message_id'],
                               kwargs['ignore_return_code'],
                               kwargs['ignore_all_errors']):
            return False, rsp_body, errobj

        if (kwargs['no_retry'] and
                response['status_code'] != httpclient.INTERNAL_SERVER_ERROR or
                response.is_no_retry_error(kwargs['no_retry_error'])):
            retry = False
        elif response.is_auth_fail():
            retry = self.relogin(kwargs['no_relogin'])
        else:
            retry = True

        if retry and response.is_rest_server_busy():
            if utils.timed_out(start_time, _REST_SERVER_BUSY_TIMEOUT):
                retry = False
        elif retry and utils.timed_out(start_time, kwargs['timeout']):
            if kwargs['timeout_message']:
                utils.output_log(kwargs['timeout_message'][0],
                                 **kwargs['timeout_message'][1])
            if response.is_json():
                msg = utils.output_log(MSG.REST_API_TIMEOUT,
                                       no_log=kwargs['no_log'],
                                       method=method, url=url,
                                       params=params, body=body,
                                       **response.get_job_result())
                if errobj:
                    msg = utils.output_log(MSG.REST_API_FAILED,
                                           no_log=kwargs['no_log'],
                                           method=method, url=url,
                                           params=params, body=body,
                                           **response.get_errobj())
            else:
                msg = utils.output_log(MSG.REST_API_HTTP_ERROR,
                                       no_log=kwargs['no_log'],
                                       status_code=response['status_code'],
                                       response_body=rsp_body,
                                       method=method, url=url,
                                       params=params, body=body)
            if kwargs['do_raise']:
                raise utils.HBSDError(msg, errobj=errobj)
            return False, rsp_body, errobj

        if errobj:
            LOG.debug('ERROR %s', errobj)
        else:
            LOG.debug('ERROR %s', ' '.join(str(rsp_body).splitlines()))

        if not retry:
            if response.is_json():
                msg = utils.output_log(MSG.REST_API_FAILED,
                                       no_log=kwargs['no_log'],
                                       method=method, url=url,
                                       params=params, body=body,
                                       **response.get_errobj())
            else:
                msg = utils.output_log(MSG.REST_API_HTTP_ERROR,
                                       no_log=kwargs['no_log'],
                                       status_code=response['status_code'],
                                       response_body=rsp_body,
                                       method=method, url=url,
                                       params=params, body=body)
            if kwargs['do_raise']:
                raise utils.HBSDError(msg, errobj=errobj)
        return retry, rsp_body, errobj