コード例 #1
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
    def index(self, req, body=None):
        body = body or {}
        order = body.pop('order', None)
        desc = body.pop('desc', False)
        page_num = int(body.pop('page_num', 0))

        session = endpoint_session(readonly=True)
        columns = [
            Group.group_id, Group.name, Group.platfrom_id, Group.warsvr,
            Group.desc, Group.areas
        ]

        results = resultutils.bulk_results(session,
                                           model=Group,
                                           columns=columns,
                                           counter=Group.group_id,
                                           order=order,
                                           desc=desc,
                                           option=joinedload(Group.areas,
                                                             innerjoin=False),
                                           page_num=page_num)
        for column in results['data']:

            areas = column.get('areas', [])
            column['areas'] = []
            for area in areas:
                column['areas'].append(
                    dict(area_id=area.area_id,
                         areaname=area.areaname,
                         show_id=area.show_id))
        return results
コード例 #2
0
ファイル: internal.py プロジェクト: lolizeppelin/gogamechen3
 def entitys(self, req, body=None):
     """批量查询entitys信息接口,内部接口agent启动的时调用,一般由agent端调用"""
     entitys = body.get('entitys')
     if not entitys:
         return resultutils.results(result='not any app entitys found')
     entitys = argutils.map_to_int(entitys)
     session = endpoint_session(readonly=True)
     query = model_query(session,
                         AppEntity,
                         filter=AppEntity.entity.in_(entitys))
     query = query.options(joinedload(AppEntity.areas, innerjoin=False))
     return resultutils.results(result='get app entitys success',
                                data=[
                                    dict(entity=_entity.entity,
                                         group_id=_entity.group_id,
                                         status=_entity.status,
                                         opentime=_entity.opentime,
                                         areas=[
                                             dict(area_id=area.area_id,
                                                  show_id=area.show_id,
                                                  areaname=area.areaname)
                                             for area in _entity.areas
                                         ],
                                         objtype=_entity.objtype)
                                    for _entity in query
                                ])
コード例 #3
0
 def unquote_version(self, req, group_id, objtype, entity, body=None):
     """区服包引用指定资源引用删除"""
     body = body or {}
     if objtype != common.GAMESERVER:
         raise InvalidArgument('Version unquote just for %s' %
                               common.GAMESERVER)
     package_id = int(body.get('package_id'))
     group_id = int(group_id)
     entity = int(entity)
     session = endpoint_session()
     query = model_query(session,
                         AppEntity,
                         filter=AppEntity.entity == entity)
     quote = None
     with session.begin():
         _entity = query.one()
         if _entity.objtype != objtype:
             raise InvalidArgument('Objtype not match')
         if _entity.group_id != group_id:
             raise InvalidArgument('Group id not match')
         versions = jsonutils.loads_as_bytes(
             _entity.versions) if _entity.versions else {}
         str_key = str(package_id)
         if str_key in versions:
             quote = versions.pop(str_key)
             cdnquote_controller.delete(req, quote.get('quote_id'))
             _entity.versions = jsonutils.dumps(
                 versions) if versions else None
             session.flush()
     return resultutils.results(
         result='%s entity version unquote success' % objtype,
         data=[
             dict(version=quote.get('version') if quote else None,
                  quote_id=quote.get('quote_id') if quote else None)
         ])
コード例 #4
0
ファイル: curd.py プロジェクト: lolizeppelin/gogamechen3
 def show(self, req, group_id, objtype, entity, body=None):
     body = body or {}
     group_id = int(group_id)
     entity = int(entity)
     session = endpoint_session(readonly=True)
     _format = body.get('format') or 'list'
     query = model_query(session,
                         AppEntity,
                         filter=AppEntity.entity == entity)
     query = query.options(joinedload(AppEntity.databases, innerjoin=False))
     _entity = query.one()
     if _entity.objtype != objtype:
         raise InvalidArgument('Entity is not %s' % objtype)
     if _entity.group_id != group_id:
         raise InvalidArgument('Entity group %d not match  %d' %
                               (_entity.group_id, group_id))
     metadata, ports = self._entityinfo(req, entity)
     if _format == 'list':
         databases = []
     else:
         databases = {}
     for database in _entity.databases:
         dbinfo = dict(quote_id=database.quote_id,
                       database_id=database.database_id,
                       host=database.host,
                       port=database.port,
                       ro_user=database.ro_user,
                       ro_passwd=database.ro_passwd,
                       subtype=database.subtype,
                       schema='%s_%s_%s_%d' %
                       (common.NAME, objtype, database.subtype, entity))
         if _format == 'list':
             databases.append(dbinfo)
         else:
             databases[database.subtype] = dbinfo
     return resultutils.results(
         result='show %s areas success' % objtype,
         data=[
             dict(entity=_entity.entity,
                  agent_id=_entity.agent_id,
                  objtype=objtype,
                  group_id=_entity.group_id,
                  opentime=_entity.opentime,
                  platform=_entity.platform,
                  status=_entity.status,
                  versions=jsonutils.loads_as_bytes(_entity.versions)
                  if _entity.versions else None,
                  areas=[
                      dict(
                          area_id=area.area_id,
                          gid=0,
                          show_id=area.show_id,
                          areaname=area.areaname.encode('utf-8'),
                      ) for area in _entity.areas
                  ],
                  databases=databases,
                  metadata=metadata,
                  ports=ports)
         ])
コード例 #5
0
ファイル: internal.py プロジェクト: lolizeppelin/gogamechen3
 def bondto(self, req, entity, body=None):
     """本地记录数据库绑定信息,用于数据绑定失败后重新绑定"""
     body = body or {}
     entity = int(entity)
     databases = body.pop('databases')
     session = endpoint_session()
     with session.begin():
         self._bondto(session, entity, databases)
     return resultutils.results(result='bond entity %d database success' %
                                entity)
コード例 #6
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
 def delete(self, req, group_id, body=None):
     body = body or {}
     group_id = int(group_id)
     session = endpoint_session()
     query = model_query(session, Group, filter=Group.group_id == group_id)
     query = query.options(joinedload(Group.entitys, innerjoin=False))
     _group = query.one()
     deleted = dict(group_id=_group.group_id, name=_group.name)
     if _group.entitys:
         raise InvalidArgument('Group has entitys, can not be delete')
     session.delete(_group)
     session.flush()
     return resultutils.results(result='delete group success',
                                data=[deleted])
コード例 #7
0
    def migrate(self, req, group_id, objtype, entity, body=None):
        """Entity变更agent"""
        body = body or {}
        entity = int(entity)
        group_id = int(group_id)
        jsonutils.schema_validate(body, self.MIGRATE)
        new = body.pop('new')
        new = int(new)
        body.update({'databases': True, 'chiefs': True})
        session = endpoint_session(autocommit=False)
        query = model_query(session,
                            AppEntity,
                            filter=AppEntity.entity == entity)
        query = query.options(joinedload(AppEntity.areas, innerjoin=False))
        _entity = query.one()
        if _entity.objtype != objtype:
            raise InvalidArgument('Entity is not %s' % objtype)
        if not self._check_file(_entity.agent_id, objtype,
                                body.get(common.APPFILE)):
            return resultutils.results(
                result='migrate entity %d not run, check appfile fail')
        LOG.debug('Check appfile success, migrate start')
        areas = [
            dict(area_id=area.area_id,
                 areaname=area.areaname,
                 show_id=area.show_id) for area in _entity.areas
        ]
        with entity_controller.migrate_with_out_data(
                common.NAME,
                entity,
                new,
                dict(token=uuidutils.generate_uuid()),
                drop_ports=True):

            _entity.agent_id = new
            session.commit()
            LOG.info(
                'Migrate finish, now call post create entity and reset entity on new agent'
            )
            entity_controller.post_create_entity(entity,
                                                 common.NAME,
                                                 objtype=objtype,
                                                 status=_entity.status,
                                                 opentime=_entity.opentime,
                                                 group_id=group_id,
                                                 areas=areas,
                                                 migrate=True)
            LOG.info('Notify create entity in new agent success')
            return self.reset(req, group_id, objtype, entity, body)
コード例 #8
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
    def databases(self, req, group_id, body=None):
        body = body or {}
        objtype = body.get('objtype', common.GAMESERVER)
        group_id = int(group_id)
        session = endpoint_session(readonly=True)
        _format = body.get('format') or 'list'
        query = model_query(session,
                            AppEntity,
                            filter=and_(AppEntity.group_id == group_id,
                                        AppEntity.objtype == objtype))
        query = query.options(joinedload(AppEntity.databases, innerjoin=False))

        entitys = query.all()
        slaves_map = database_controller.slaves_address([
            database.database_id for entity in entitys
            for database in entity.databases
        ])

        data = []
        for entity in entitys:
            databases = {}
            for database in entity.databases:
                try:
                    slaves = slaves_map[database.database_id]
                except KeyError:
                    slaves = []

                dbinfo = dict(
                    database_id=database.database_id,
                    host=database.host,
                    port=database.port,
                    ro_user=database.ro_user,
                    ro_passwd=database.ro_passwd,
                    subtype=database.subtype,
                    schema='%s_%s_%s_%d' %
                    (common.NAME, objtype, database.subtype, entity.entity),
                    slaves=slaves,
                )
                databases[database.subtype] = dbinfo
            data.append({
                'entity': entity.entity,
                'group_id': group_id,
                'objtype': objtype,
                'databases': databases
            })
        return resultutils.results(result='list group entity database success',
                                   data=data)
コード例 #9
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
 def packages(self, req, group_id, body=None):
     body = body or {}
     group_id = int(group_id)
     session = endpoint_session(readonly=True)
     query = model_query(session, Group, filter=Group.group_id == group_id)
     query = query.options(joinedload(Group.packages, innerjoin=False))
     _group = query.one()
     return resultutils.results(result='list group packages success',
                                data=[
                                    dict(
                                        package_id=package.package_id,
                                        package_name=package.package_name,
                                        mark=package.mark,
                                        status=package.status,
                                        resource_id=package.resource_id,
                                    ) for package in _group.packages
                                ])
コード例 #10
0
 def opentime(self, req, group_id, objtype, entity, body=None):
     """修改开服时间接口"""
     body = body or {}
     group_id = int(group_id)
     entity = int(entity)
     if objtype != common.GAMESERVER:
         raise InvalidArgument('Api just for %s' % common.GAMESERVER)
     opentime = int(body.pop('opentime'))
     if opentime < 0 or opentime >= int(time.time()) + 86400 * 15:
         raise InvalidArgument('opentime value error')
     session = endpoint_session()
     with session.begin():
         query = model_query(session,
                             AppEntity,
                             filter=AppEntity.entity == entity)
         _entity = query.one()
         if _entity.objtype != objtype:
             raise InvalidArgument('Entity is not %s' % objtype)
         if _entity.group_id != group_id:
             raise InvalidArgument('Entity group %d not match  %d' %
                                   (_entity.group_id, group_id))
         metadata, ports = self._entityinfo(req=req, entity=entity)
         target = targetutils.target_agent_by_string(
             metadata.get('agent_type'), metadata.get('host'))
         target.namespace = common.NAME
         rpc = get_client()
         finishtime, timeout = rpcfinishtime()
         # with session.begin():
         rpc_ret = rpc.call(target,
                            ctxt={'finishtime': finishtime},
                            msg={
                                'method': 'opentime_entity',
                                'args': dict(entity=entity,
                                             opentime=opentime)
                            },
                            timeout=timeout)
         query.update({'opentime': opentime})
         if not rpc_ret:
             raise RpcResultError('change entity opentime result is None')
         if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
             raise RpcResultError('change entity opentime fail %s' %
                                  rpc_ret.get('result'))
     return resultutils.results(result='change entity %d opentime success' %
                                entity)
コード例 #11
0
ファイル: merge.py プロジェクト: lolizeppelin/gogamechen3
 def continues(self, req, uuid, body=None):
     """中途失败的合服任务再次运行"""
     session = endpoint_session()
     query = model_query(session, MergeTask, filter=MergeTask.uuid == uuid)
     query = query.options(joinedload(MergeTask.entitys, innerjoin=False))
     etask = query.one()
     if etask.status == common.MERGEFINISH:
         raise InvalidArgument('Merge task has all ready finished')
     _query = model_query(session,
                          AppEntity,
                          filter=AppEntity.entity == etask.entity)
     _query = _query.options(
         joinedload(AppEntity.databases, innerjoin=False))
     appentity = _query.one_or_none()
     if not appentity or not appentity.databases or appentity.objtype != common.GAMESERVER:
         LOG.error('Etask entity can not be found or type/database error')
         raise exceptions.MergeException(
             'Etask entity can not be found or type/database error')
     databases = self._database_to_dict(appentity)
     rpc = get_client()
     metadata, ports = self._entityinfo(req=req, entity=appentity.entity)
     target = targetutils.target_agent_by_string(metadata.get('agent_type'),
                                                 metadata.get('host'))
     target.namespace = common.NAME
     rpc_ret = rpc.call(target,
                        ctxt={'agents': [
                            appentity.agent_id,
                        ]},
                        msg={
                            'method':
                            'continue_merge',
                            'args':
                            dict(entity=etask.entity,
                                 uuid=uuid,
                                 databases=databases)
                        })
     if not rpc_ret:
         raise RpcResultError('continue entity result is None')
     if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
         raise RpcResultError('continue entity fail %s' %
                              rpc_ret.get('result'))
     return resultutils.results(
         result='continue merge task command has been send',
         data=[dict(uuid=etask.uuid, entity=etask.entity)])
コード例 #12
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
 def create(self, req, body=None):
     body = body or {}
     session = endpoint_session()
     name = utils.validate_string(body.get('name'))
     desc = body.get('desc')
     _group = Group(name=name, desc=desc, platfrom_id=0, warsvr=False)
     session.add(_group)
     try:
         session.flush()
     except DBDuplicateEntry:
         raise InvalidArgument('Group name duplicate')
     return resultutils.results(result='create group success',
                                data=[
                                    dict(group_id=_group.group_id,
                                         name=_group.name,
                                         platfrom_id=_group.platfrom_id,
                                         warsvr=_group.warsvr,
                                         desc=_group.desc)
                                ])
コード例 #13
0
ファイル: merge.py プロジェクト: lolizeppelin/gogamechen3
 def finish(self, req, uuid, body=None):
     """合服完毕接口"""
     session = endpoint_session()
     query = model_query(session, MergeTask, filter=MergeTask.uuid == uuid)
     query = query.options(joinedload(MergeTask.entitys, innerjoin=False))
     etask = query.one()
     if etask.status == common.MERGEFINISH:
         return resultutils.results(
             result='swallowed finished',
             data=[dict(uuid=etask.uuid, entity=etask.entity)])
     for _entity in etask.entitys:
         if _entity.status != common.MERGEED:
             raise InvalidArgument('Entity %d status is not mergeed' %
                                   _entity.entity)
     etask.status = common.MERGEFINISH
     session.flush()
     return resultutils.results(
         result='swallowed finished',
         data=[dict(uuid=etask.uuid, entity=etask.entity)])
コード例 #14
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
def areas_map(group_id):
    session = endpoint_session(readonly=True)
    query = model_query(session,
                        GameArea,
                        filter=GameArea.group_id == group_id)
    maps = {}
    for _area in query:
        try:
            maps[_area.entity].append(
                dict(area_id=_area.area_id,
                     areaname=_area.areaname,
                     show_id=_area.show_id))
        except KeyError:
            maps[_area.entity] = [
                dict(area_id=_area.area_id,
                     areaname=_area.areaname,
                     show_id=_area.show_id),
            ]
    session.close()
    return maps
コード例 #15
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
 def show(self, req, group_id, body=None):
     body = body or {}
     group_id = int(group_id)
     detail = body.get('detail', False)
     session = endpoint_session(readonly=True)
     query = model_query(session, Group, filter=Group.group_id == group_id)
     joins = joinedload(Group.entitys, innerjoin=False)
     if detail:
         joins = joins.joinedload(AppEntity.areas, innerjoin=False)
     query = query.options(joins)
     _group = query.one()
     group_info = dict(group_id=_group.group_id,
                       name=_group.name,
                       platfrom_id=_group.platfrom_id,
                       warsvr=_group.warsvr,
                       desc=_group.desc)
     if detail:
         _entitys = {}
         for entity in _group.entitys:
             objtype = entity.objtype
             entityinfo = dict(entity=entity.entity, status=entity.status)
             if objtype == common.GAMESERVER:
                 entityinfo.setdefault('areas', [
                     dict(area_id=area.area_id,
                          areaname=area.areaname,
                          show_id=area.show_id) for area in entity.areas
                 ])
             try:
                 _entitys[objtype].append(entityinfo)
             except KeyError:
                 _entitys[objtype] = [
                     entityinfo,
                 ]
         group_info.setdefault('entitys', _entitys)
     return resultutils.results(result='show group success',
                                data=[
                                    group_info,
                                ])
コード例 #16
0
ファイル: utils.py プロジェクト: lolizeppelin/gogamechen3
def gmurl(req, group_id, interface):
    session = endpoint_session(readonly=True)
    query = model_query(session,
                        AppEntity,
                        filter=and_(AppEntity.objtype == common.GMSERVER,
                                    AppEntity.group_id == group_id))
    gm = query.one_or_none()
    if not gm or gm.status != common.OK:
        raise exceptions.GmSvrHttpError('GM is none or not active' %
                                        common.GMSERVER)
    entityinfo = entity_controller.show(req=req,
                                        entity=gm.entity,
                                        endpoint=common.NAME,
                                        body={'ports': True})['data'][0]
    port = entityinfo.get('ports')[0]
    metadata = entityinfo.get('metadata')
    if not metadata:
        raise exceptions.GmSvrHttpError(
            '%s.%d is off line, can not stop by %s' %
            (gm.objtype, gm.entity, gm.objtype))
    ipaddr = metadata.get('local_ip')
    url = 'http://%s:%d/%s' % (ipaddr, port, interface)
    return url
コード例 #17
0
ファイル: merge.py プロジェクト: lolizeppelin/gogamechen3
 def swallow(self, req, entity, body=None):
     """合服内部接口,一般由agent调用
     用于新实体吞噬旧实体的区服和数据库"""
     body = body or {}
     entity = int(entity)
     uuid = body.get('uuid')
     if not uuid:
         raise InvalidArgument('Merger uuid is None')
     session = endpoint_session()
     query = model_query(session, MergeTask, filter=MergeTask.uuid == uuid)
     query = query.options(joinedload(MergeTask.entitys, innerjoin=False))
     glock = get_gamelock()
     rpc = get_client()
     with session.begin():
         etask = query.one_or_none()
         if not etask:
             raise InvalidArgument('Not task exit with %s' % uuid)
         # 新实体不匹配
         if etask.entity != body.get('entity'):
             raise InvalidArgument('New entity not %d' % etask.entity)
         # 找到目标实体
         appentity = None
         for _entity in etask.entitys:
             if _entity.entity == entity:
                 if _entity.status != common.MERGEING:
                     if _entity.status != common.SWALLOWING:
                         raise InvalidArgument(
                             'Swallow entity find status error')
                     if not _entity.databases or not _entity.areas:
                         raise InvalidArgument(
                             'Entity is swallowing but database or ares is None'
                         )
                     LOG.warning('Entit is swallowing, return saved data')
                     return resultutils.results(
                         result='swallow entity is success',
                         data=[
                             dict(databases=jsonutils.loads_as_bytes(
                                 _entity.databases),
                                  areas=jsonutils.loads_as_bytes(
                                      _entity.areas))
                         ])
                 _query = model_query(session,
                                      AppEntity,
                                      filter=AppEntity.entity == entity)
                 _query = _query.options(
                     joinedload(AppEntity.databases, innerjoin=False))
                 appentity = _query.one_or_none()
                 break
         if not appentity:
             raise InvalidArgument('Can not find app entity?')
         if appentity.objtype != common.GAMESERVER:
             raise InvalidArgument('objtype error, entity not %s' %
                                   common.GAMESERVER)
         if appentity.status != common.MERGEING:
             raise InvalidArgument('find status error, when swallowing')
         databases = self._database_to_dict(appentity)
         areas = [area.to_dict() for area in appentity.areas]
         if not databases or not areas:
             LOG.error('Entity no areas or databases record')
             return resultutils.results(
                 result='swallow entity fail, '
                 'target entity can not found database or areas',
                 resultcode=manager_common.RESULT_ERROR)
         with glock.grouplock(group=appentity.group_id):
             # 发送吞噬命令到目标区服agent
             metadata, ports = self._entityinfo(req=req, entity=entity)
             target = targetutils.target_agent_by_string(
                 metadata.get('agent_type'), metadata.get('host'))
             target.namespace = common.NAME
             rpc_ret = rpc.call(target,
                                ctxt={'agents': [
                                    appentity.agent_id,
                                ]},
                                msg={
                                    'method': 'swallow_entity',
                                    'args': dict(entity=entity)
                                })
             if not rpc_ret:
                 raise RpcResultError('swallow entity result is None')
             if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
                 raise RpcResultError('swallow entity fail %s' %
                                      rpc_ret.get('result'))
         # 修改实体在合服任务中的状态,存储areas以及databases
         appentity.status = common.SWALLOWING
         _entity.status = common.SWALLOWING
         _entity.areas = jsonutils.dumps(areas)
         _entity.databases = jsonutils.dumps(databases)
         session.flush()
         return resultutils.results(
             result='swallow entity is success',
             data=[dict(databases=databases, areas=areas)])
コード例 #18
0
ファイル: merge.py プロジェクト: lolizeppelin/gogamechen3
    def swallowed(self, req, entity, body=None):
        """
        合服内部接口,一般由agent调用
        用于新实体吞噬旧实体的区服完成后调用
        调用后将设置appentity为deleted状态
        """
        body = body or {}
        entity = int(entity)
        uuid = body.get('uuid')
        if not uuid:
            raise InvalidArgument('Merger uuid is None')
        session = endpoint_session()
        query = model_query(session, MergeTask, filter=MergeTask.uuid == uuid)
        query = query.options(joinedload(MergeTask.entitys, innerjoin=False))
        glock = get_gamelock()
        rpc = get_client()
        appentity = None
        with session.begin():
            etask = query.one_or_none()
            if not etask:
                raise InvalidArgument('Not task exit with %s' % uuid)
            # 新实体不匹配
            if etask.entity != body.get('entity'):
                raise InvalidArgument('New entity not %d' % etask.entity)
            for _entity in etask.entitys:
                if _entity.entity == entity:
                    if _entity.status != common.SWALLOWING:
                        raise InvalidArgument(
                            'Swallowed entity find status error')
                    _query = model_query(session,
                                         AppEntity,
                                         filter=AppEntity.entity == entity)
                    _query = _query.options(
                        joinedload(AppEntity.databases, innerjoin=False))
                    appentity = _query.one_or_none()
                    break
            if not appentity:
                raise InvalidArgument('Can not find app entity?')
            if appentity.objtype != common.GAMESERVER:
                raise InvalidArgument('objtype error, entity not %s' %
                                      common.GAMESERVER)
            if appentity.status != common.SWALLOWING:
                raise InvalidArgument('find status error, when swallowed')

            with glock.grouplock(group=appentity.group_id):
                # 发送吞噬完成命令到目标区服agent
                metadata, ports = self._entityinfo(req=req, entity=entity)
                target = targetutils.target_agent_by_string(
                    metadata.get('agent_type'), metadata.get('host'))
                target.namespace = common.NAME
                rpc_ret = rpc.call(target,
                                   ctxt={'agents': [
                                       appentity.agent_id,
                                   ]},
                                   msg={
                                       'method': 'swallowed_entity',
                                       'args': dict(entity=entity)
                                   })
                if not rpc_ret:
                    raise RpcResultError('swallowed entity result is None')
                if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
                    raise RpcResultError('swallowed entity fail %s' %
                                         rpc_ret.get('result'))
            # appentity状态修改为deleted
            appentity.status = common.DELETED
            # 修改实体在合服任务中的状态
            _entity.status = common.MERGEED
            session.flush()
            # area绑定新实体
            _query = model_query(session,
                                 GameArea,
                                 filter=GameArea.entity == entity)
            _query.update({'entity': etask.entity})
            session.flush()

        def _unquote():
            LOG.info('Swallowed %d finish, try unquote database' %
                     appentity.entity)
            for database in appentity.databases:
                try:
                    schema_controller.unquote(req, quote_id=database.quote_id)
                except Exception:
                    LOG.error('Delete database quote fail')

        eventlet.spawn_n(_unquote)

        return resultutils.results(
            result='swallowed entity is success',
            data=[
                dict(databases=jsonutils.loads_as_bytes(_entity.databases),
                     areas=jsonutils.loads_as_bytes(_entity.areas))
            ])
コード例 #19
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
    def entitys(objtypes=None, group_ids=None, need_ok=False, packages=False):
        filters = [
            AppEntity.objtype.in_(objtypes), AppEntity.status > common.DELETED
        ]
        if group_ids:
            filters.append(
                AppEntity.group_id.in_(argutils.map_to_int(group_ids)))
        session = endpoint_session(readonly=True)
        query = model_query(session, AppEntity, filter=and_(*filters))
        query = query.options(joinedload(AppEntity.areas))
        appentitys = query.all()
        entitys = set()
        for entity in appentitys:
            entitys.add(entity.entity)

        if not entitys:
            return [], []

        # 反查渠道
        if packages and common.GAMESERVER in objtypes:
            pmaps = {}
            pquery = model_query(session, Package)
            pquery = pquery.options(joinedload(Package.areas, innerjoin=False))
            if group_ids:
                pquery = pquery.filter(
                    Package.group_id.in_(argutils.map_to_int(group_ids)))

            def _pmaps():
                for package in pquery:
                    for parea in package.areas:
                        try:
                            pmaps[parea.area_id].append(package.package_name)
                        except KeyError:
                            pmaps[parea.area_id] = [
                                package.package_name,
                            ]

            th = eventlet.spawn(_pmaps)

        emaps = entity_controller.shows(common.NAME,
                                        entitys,
                                        ports=True,
                                        metadata=True)

        if packages and common.GAMESERVER in objtypes:
            th.wait()

        chiefs = []
        areas = []
        for entity in appentitys:
            if need_ok and entity.status != common.OK:
                continue
            entityinfo = emaps.get(entity.entity)
            ports = entityinfo.get('ports')
            metadata = entityinfo.get('metadata')
            if not metadata:
                raise ValueError('Can not get agent metadata for %d' %
                                 entity.entity)
            if entity.objtype == common.GAMESERVER:
                for area in entity.areas:
                    info = dict(
                        area_id=area.area_id,
                        show_id=area.show_id,
                        areaname=area.areaname,
                        entity=entity.entity,
                        group_id=entity.group_id,
                        opentime=entity.opentime,
                        platform=entity.platform,
                        status=entity.status,
                        versions=jsonutils.loads_as_bytes(entity.versions)
                        if entity.versions else None,
                        external_ips=metadata.get('external_ips'),
                        dnsnames=metadata.get('dnsnames'),
                        port=ports[0])
                    if packages:
                        info.setdefault('packagenames',
                                        pmaps.get(area.area_id, []))
                    areas.append(info)
            else:
                chiefs.append(
                    dict(entity=entity.entity,
                         objtype=entity.objtype,
                         group_id=entity.group_id,
                         ports=ports,
                         local_ip=metadata.get('local_ip'),
                         dnsnames=metadata.get('dnsnames'),
                         external_ips=metadata.get('external_ips')))
        return chiefs, areas
コード例 #20
0
ファイル: __init__.py プロジェクト: lolizeppelin/gogamechen3
 def area(self, req, group_id, body=None):
     """change entity area"""
     body = body or {}
     try:
         group_id = int(group_id)
     except (TypeError, ValueError):
         raise InvalidArgument('Group id value error')
     area_id = body.get('area_id')
     areaname = body.get('areaname')
     show_id = body.get('show_id')
     if not areaname and not show_id:
         raise InvalidArgument('No value change')
     rpc = get_client()
     session = endpoint_session()
     query = model_query(session,
                         GameArea,
                         filter=GameArea.area_id == area_id)
     with session.begin():
         area = query.one_or_none()
         if not area:
             raise InvalidArgument('No area found')
         if area.group_id != group_id:
             raise InvalidArgument('Area group not %d' % group_id)
         entityinfo = entity_controller.show(req=req,
                                             entity=area.entity,
                                             endpoint=common.NAME,
                                             body={'ports':
                                                   False})['data'][0]
         agent_id = entityinfo['agent_id']
         metadata = entityinfo['metadata']
         if not metadata:
             raise InvalidArgument(
                 'Agent is off line, can not reset entity')
         if areaname:
             if model_count_with_key(session,
                                     GameArea,
                                     filter=and_(
                                         GameArea.group_id == group_id,
                                         GameArea.areaname == areaname)):
                 raise InvalidArgument('Area name duplicate in group %d' %
                                       group_id)
             area.areaname = areaname
         if show_id:
             area.show_id = show_id
         target = targetutils.target_agent_by_string(
             metadata.get('agent_type'), metadata.get('host'))
         target.namespace = common.NAME
         finishtime, timeout = rpcfinishtime()
         rpc_ret = rpc.call(target,
                            ctxt={
                                'finishtime': finishtime,
                                'agents': [
                                    agent_id,
                                ]
                            },
                            msg={
                                'method':
                                'change_entity_area',
                                'args':
                                dict(entity=area.entity,
                                     area_id=area.area_id,
                                     show_id=area.show_id,
                                     areaname=area.areaname)
                            },
                            timeout=timeout)
         if not rpc_ret:
             raise RpcResultError('change entity area result is None')
         if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
             raise RpcResultError('change entity area fail %s' %
                                  rpc_ret.get('result'))
         session.flush()
     return resultutils.results(result='change group areas success')
コード例 #21
0
ファイル: async.py プロジェクト: lolizeppelin/gogamechen3
    def _async_bluck_rpc(self,
                         action,
                         group_id,
                         objtype,
                         entity,
                         body=None,
                         context=None):
        caller = inspect.stack()[0][3]
        body = body or {}
        group_id = int(group_id)

        context = context or empty_context

        if entity == 'all':
            entitys = 'all'
        else:
            entitys = argutils.map_to_int(entity)
        asyncrequest = self.create_asyncrequest(body)
        target = targetutils.target_endpoint(common.NAME)
        session = endpoint_session(readonly=True)
        query = model_query(session,
                            AppEntity,
                            filter=and_(AppEntity.group_id == group_id,
                                        AppEntity.objtype == objtype))
        emaps = dict()

        for _entity in query:
            if _entity.status <= common.DELETED:
                continue
            if _entity.status != common.OK and action != 'stop':
                continue
            emaps.setdefault(_entity.entity, _entity.agent_id)

        if entitys == 'all':
            entitys = emaps.keys()
            agents = set(emaps.values())
        else:
            if entitys - set(emaps.keys()):
                raise InvalidArgument(
                    'Some entitys not found or status is not active')
            agents = set()
            for entity in emaps:
                if entity in entitys:
                    agents.add(emaps[entity])

        with context(asyncrequest.request_id, entitys, agents):
            async_ctxt = dict(pre_run=body.pop('pre_run', None),
                              after_run=body.pop('after_run', None),
                              post_run=body.pop('post_run', None))
            rpc_ctxt = {}
            rpc_ctxt.setdefault('agents', agents)
            rpc_method = '%s_entitys' % action
            rpc_args = dict(entitys=list(entitys))
            rpc_args.update(body)

            def wapper():
                self.send_asyncrequest(asyncrequest, target, rpc_ctxt,
                                       rpc_method, rpc_args, async_ctxt)

            threadpool.add_thread(safe_func_wrapper, wapper, LOG)

        return resultutils.results(
            result='gogamechen3 %s entitys %s spawning' % (objtype, caller),
            data=[asyncrequest.to_dict()])
コード例 #22
0
ファイル: curd.py プロジェクト: lolizeppelin/gogamechen3
    def index(self, req, group_id, objtype, body=None):
        body = body or {}
        group_id = int(group_id)
        order = body.pop('order', None)
        desc = body.pop('desc', False)
        detail = body.pop('detail', False)
        packages = body.pop('packages', False)
        page_num = int(body.pop('page_num', 0))

        session = endpoint_session(readonly=True)
        columns = [
            AppEntity.entity, AppEntity.group_id, AppEntity.agent_id,
            AppEntity.opentime, AppEntity.platform, AppEntity.versions,
            AppEntity.status, AppEntity.objtype
        ]

        joins = None
        if objtype == common.GAMESERVER:
            columns.append(AppEntity.areas)
            joins = joinedload(AppEntity.areas, innerjoin=False)
            if packages:
                joins = joins.joinedload(GameArea.packages, innerjoin=False)

        def _databases():
            _maps = {}
            if objtype != common.GAMESERVER:
                return _maps
            query = model_query(session, AreaDatabase)
            for _db in query:
                dbinfo = dict(
                    quote_id=_db.quote_id,
                    subtype=_db.subtype,
                    host=_db.host,
                    port=_db.port,
                )
                try:
                    _maps[_db.entity].append(dbinfo)
                except KeyError:
                    _maps[_db.entity] = [
                        dbinfo,
                    ]
            return _maps

        if detail:
            dth = eventlet.spawn(_databases)

        results = resultutils.bulk_results(session,
                                           model=AppEntity,
                                           columns=columns,
                                           counter=AppEntity.entity,
                                           order=order,
                                           desc=desc,
                                           option=joins,
                                           filter=and_(
                                               AppEntity.group_id == group_id,
                                               AppEntity.objtype == objtype),
                                           page_num=page_num)
        if detail:
            dbmaps = dth.wait()

        if not results['data']:
            return results

        emaps = entity_controller.shows(
            endpoint=common.NAME,
            entitys=[column.get('entity') for column in results['data']])

        for column in results['data']:
            entity = column.get('entity')
            entityinfo = emaps.get(entity)
            if detail:
                try:
                    column['databases'] = dbmaps[entity]
                except KeyError:
                    LOG.error('Entity %d lose database' % entity)
            if column['agent_id'] != entityinfo.get('agent_id'):
                raise RuntimeError(
                    'Entity agent id %d not the same as %d' %
                    (column['agent_id'], entityinfo.get('agent_id')))
            areas = column.pop('areas', [])
            if objtype == common.GAMESERVER:
                _areas = []
                for area in areas:
                    _area = dict(area_id=area.area_id,
                                 show_id=area.show_id,
                                 gid=0,
                                 areaname=area.areaname)
                    if packages:
                        _area.setdefault(
                            'packages',
                            [parea.package_id for parea in area.packages])
                    _areas.append(_area)
                areas = _areas
            column['areas'] = areas
            column['ports'] = entityinfo.get('ports')
            metadata = entityinfo.get('metadata')
            if metadata:
                local_ip = metadata.get('local_ip')
                external_ips = metadata.get('external_ips')
            else:
                local_ip = external_ips = None
            column['local_ip'] = local_ip
            column['external_ips'] = external_ips
            versions = column.get('versions')
            if versions:
                column['versions'] = jsonutils.loads_as_bytes(versions)
        return results
コード例 #23
0
ファイル: async.py プロジェクト: lolizeppelin/gogamechen3
 def flushconfig(self, req, group_id, objtype, entity, body=None):
     body = body or {}
     group_id = int(group_id)
     jsonutils.schema_validate(body, self.FLUSH)
     if objtype == common.GAMESERVER:
         gm = body.pop(common.GMSERVER, 0)
         cross = body.pop(common.CROSSSERVER, 0)
         entitys = []
         if gm:
             entitys.append(gm)
         if cross:
             entitys.append(cross)
         entitys = list(set(entitys))
         if entitys:
             chiefs = {}
             session = endpoint_session()
             query = model_query(session,
                                 AppEntity,
                                 filter=and_(AppEntity.group_id == group_id,
                                             AppEntity.entity.in_(entitys)))
             gmsvr = crosssvr = None
             for appserver in query:
                 if appserver.group_id != group_id:
                     raise InvalidArgument('Entity group value error')
                 if appserver.objtype == common.GMSERVER:
                     if appserver.entity != gm:
                         raise InvalidArgument('Find %s but entity is %d' %
                                               (common.GMSERVER, gm))
                     gmsvr = appserver
                 elif appserver.objtype == common.CROSSSERVER:
                     if appserver.entity != cross:
                         raise InvalidArgument('Find %s but entity is %d' %
                                               (common.CROSSSERVER, cross))
                     crosssvr = appserver
             if gm and not gmsvr:
                 raise InvalidArgument('%s.%d can not be found' %
                                       (common.GMSERVER, gm))
             if cross and not crosssvr:
                 raise InvalidArgument('%s.%d can not be found' %
                                       (common.CROSSSERVER, cross))
             # 获取实体相关服务器信息(端口/ip)
             maps = entity_controller.shows(endpoint=common.NAME,
                                            entitys=entitys)
             if gmsvr:
                 chiefs.setdefault(
                     common.GMSERVER,
                     dict(
                         entity=gmsvr.entity,
                         ports=maps.get(gmsvr.entity).get('ports'),
                         local_ip=maps.get(
                             gmsvr.entity).get('metadata').get('local_ip')))
             if crosssvr:
                 chiefs.setdefault(
                     common.CROSSSERVER,
                     dict(entity=crosssvr.entity,
                          ports=maps.get(crosssvr.entity).get('ports'),
                          local_ip=maps.get(crosssvr.entity).get(
                              'metadata').get('local_ip')))
             body.update({'chiefs': chiefs})
     return self._async_bluck_rpc('flushconfig', group_id, objtype, entity,
                                  body)
コード例 #24
0
    def clean(self, req, group_id, objtype, entity, body=None):
        """彻底删除entity"""
        body = body or {}
        action = body.pop('clean', 'unquote')
        force = False
        ignores = body.pop('ignores', [])
        if action not in ('delete', 'unquote', 'force'):
            raise InvalidArgument('clean option value error')
        if action == 'force':
            action = 'delete'
            force = True
        group_id = int(group_id)
        entity = int(entity)
        session = endpoint_session()
        glock = get_gamelock()
        metadata, ports = self._entityinfo(req=req, entity=entity)
        if not metadata:
            raise InvalidArgument('Agent offline, can not delete entity')
        query = model_query(session,
                            AppEntity,
                            filter=AppEntity.entity == entity)
        query = query.options(joinedload(AppEntity.databases, innerjoin=False))
        _entity = query.one()

        rollbacks = []

        def _rollback():
            for back in rollbacks:
                __database_id = back.get('database_id')
                __schema = back.get('schema')
                __quote_id = back.get('quote_id')
                rbody = dict(quote_id=__quote_id, entity=entity)
                rbody.setdefault(dbcommon.ENDPOINTKEY, common.NAME)
                try:
                    schema_controller.bond(req,
                                           database_id=__database_id,
                                           schema=__schema,
                                           body=rbody)
                except Exception:
                    LOG.error('rollback entity %d quote %d.%s.%d fail' %
                              (entity, __database_id, schema, __quote_id))

        with glock.grouplock(group=group_id):
            target = targetutils.target_agent_by_string(
                metadata.get('agent_type'), metadata.get('host'))
            target.namespace = common.NAME
            rpc = get_client()
            finishtime, timeout = rpcfinishtime()
            LOG.warning('Clean entity %s.%d with action %s' %
                        (objtype, entity, action))
            with session.begin():
                rpc_ret = rpc.call(target,
                                   ctxt={'finishtime': finishtime},
                                   msg={
                                       'method': 'stoped',
                                       'args': dict(entity=entity)
                                   })
            if not rpc_ret:
                raise RpcResultError('check entity is stoped result is None')
            if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
                raise RpcResultError('check entity is stoped fail, running')

            with session.begin():
                if _entity.status != common.DELETED:
                    raise InvalidArgument(
                        'Entity status is not DELETED, '
                        'mark status to DELETED before delete it')
                if _entity.objtype != objtype:
                    raise InvalidArgument('Objtype not match')
                if _entity.group_id != group_id:
                    raise InvalidArgument('Group id not match')
                # esure database delete
                if action == 'delete':
                    LOG.warning(
                        'Clean option is delete, can not rollback when fail')
                    if not force:
                        for _database in _entity.databases:
                            schema = '%s_%s_%s_%d' % (common.NAME, objtype,
                                                      _database.subtype,
                                                      entity)
                            schema_info = schema_controller.show(
                                req=req,
                                database_id=_database.database_id,
                                schema=schema,
                                body={'quotes': True})['data'][0]
                            quotes = {}
                            for _quote in schema_info['quotes']:
                                quotes[_quote.get('quote_id')] = _quote.get(
                                    'desc')
                            if _database.quote_id not in quotes.keys():
                                # if set(quotes) != set([_database.quote_id]):
                                result = 'delete %s:%d fail' % (objtype,
                                                                entity)
                                reason = ': database [%d].%s quote: %s' % (
                                    _database.database_id, schema, str(quotes))
                                return resultutils.results(
                                    result=(result + reason),
                                    resultcode=manager_common.RESULT_ERROR)
                            quotes.pop(_database.quote_id)
                            for quote_id in quotes.keys():
                                if quotes[quote_id] in ignores:
                                    quotes.pop(quote_id, None)
                            if quotes:
                                if LOG.isEnabledFor(logging.DEBUG):
                                    LOG.debug(
                                        'quotes not match for %d: %s' %
                                        (schema_info['schema_id'], schema))
                                    for quote_id in quotes.keys():
                                        LOG.debug('quote %d: %s exist' %
                                                  (quote_id, quotes[quote_id]))
                                    LOG.debug(
                                        'Can not delete schema before delete quotes'
                                    )
                                return resultutils.results(
                                    result='Quotes not match',
                                    resultcode=manager_common.RESULT_ERROR)
                            LOG.info('Databae quotes check success for %s' %
                                     schema)
                # clean database
                for _database in _entity.databases:
                    schema = '%s_%s_%s_%d' % (common.NAME, objtype,
                                              _database.subtype, entity)
                    if action == 'delete':
                        LOG.warning('Delete schema %s from %d' %
                                    (schema, _database.database_id))
                        try:
                            schema_controller.delete(
                                req=req,
                                database_id=_database.database_id,
                                schema=schema,
                                body={
                                    'unquotes': [_database.quote_id],
                                    'ignores': ignores,
                                    'force': force
                                })
                        except GopdbError as e:
                            LOG.error(
                                'Delete schema:%s from %d fail, %s' %
                                (schema, _database.database_id, e.message))
                            if not force:
                                raise e
                        except Exception:
                            LOG.exception('Delete schema:%s from %d fail' %
                                          (schema, _database.database_id))
                            if not force:
                                raise
                    elif action == 'unquote':
                        LOG.info('Try unquote %d' % _database.quote_id)
                        try:
                            quote = schema_controller.unquote(
                                req=req,
                                quote_id=_database.quote_id)['data'][0]
                            if quote.get(
                                    'database_id') != _database.database_id:
                                LOG.critical(
                                    'quote %d with database %d, not %d' %
                                    (_database.quote_id,
                                     quote.get('database_id'),
                                     _database.database_id))
                                raise RuntimeError(
                                    'Data error, quote database not the same')
                            rollbacks.append(
                                dict(database_id=_database.database_id,
                                     quote_id=_database.quote_id,
                                     schema=schema))
                        except Exception as e:
                            LOG.error('Unquote %d fail, try rollback' %
                                      _database.quote_id)
                            if not force:
                                threadpool.add_thread(_rollback)
                                raise e
                token = uuidutils.generate_uuid()
                LOG.info('Send delete command with token %s' % token)
                session.delete(_entity)
                session.flush()
                try:
                    entity_controller.delete(req,
                                             common.NAME,
                                             entity=entity,
                                             body=dict(token=token))
                except Exception as e:
                    # roll back unquote
                    threadpool.add_thread(_rollback)
                    raise e
        return resultutils.results(result='delete %s:%d success' %
                                   (objtype, entity),
                                   data=[
                                       dict(entity=entity,
                                            objtype=objtype,
                                            ports=ports,
                                            metadata=metadata)
                                   ])
コード例 #25
0
group_id = 97
platform = 'ios'

a = 'C:\\Users\\loliz_000\\Desktop\\etc\\goperation\\goperation.conf'
b = 'C:\\Users\\loliz_000\\Desktop\\etc\\goperation\\gcenter.conf'
c = 'C:\\Users\\loliz_000\\Desktop\\etc\\goperation\\endpoints\gogamechen3.server.conf'

from goperation.manager import common as manager_common
from goperation import config as goperation_config

# create a new project and group named gcenter
name = manager_common.SERVER
# init goperation config
main_group = goperation_config.configure(name, [a, b, c])
from simpleservice.ormdb.config import database_opts

endpoint_group = cfg.OptGroup(common.NAME,
                              title='endpopint of %s' % common.NAME)
CONF.register_group(endpoint_group)
CONF.register_opts(database_opts, endpoint_group)

session = endpoint_session(readonly=True)

query = session.query(func.max(GameArea.show_id)).select_from(AppEntity)
query = query.join(AppEntity.areas, isouter=True)
query = query.filter(
    and_(AppEntity.group_id == group_id, AppEntity.platform == platform))
last_show_id = query.scalar() or 0

print last_show_id
コード例 #26
0
ファイル: curd.py プロジェクト: lolizeppelin/gogamechen3
    def create(self, req, group_id, objtype, body=None):
        body = body or {}
        group_id = int(group_id)
        jsonutils.schema_validate(body, self.CREATEAPPENTITY)
        if body.get('packages'):
            raise InvalidArgument('Package parameter is removed')
        # 找cross服务, gameserver专用
        cross_id = body.pop('cross_id', None)
        # 开服时间, gameserver专用
        opentime = body.pop('opentime', None)
        # 区服显示id, gameserver专用
        show_id = body.pop('show_id', None)
        # 区服显示民称, gameserver专用
        areaname = body.pop('areaname', None)
        # 平台类型
        platform = body.get('platform')

        include = set(body.pop('include', []))
        exclude = set(body.pop('exclude', []))
        if include and exclude:
            raise InvalidArgument('Both packages and exclude is forbidden')
        packages = []

        session = endpoint_session()
        if objtype == common.GAMESERVER:
            platform = common.PlatformTypeMap.get(platform)
            if not areaname or not opentime or not platform or not show_id:
                raise InvalidArgument(
                    '%s need opentime and areaname and platform and show_id' %
                    objtype)
        # 安装文件信息
        appfile = body.pop(common.APPFILE)
        LOG.debug('Try find agent and database for entity')
        # 选择实例运行服务器
        agent_id = body.get('agent_id') or self._agentselect(
            req, objtype, **body)
        # 选择实例运行数据库
        databases = self._dbselect(req, objtype, **body)
        # 校验数据库信息
        if not self._validate_databases(objtype, databases):
            raise InvalidArgument('Miss some database')
        LOG.info(
            'Find agent and database for entity success, to agent %d, to databse %s'
            % (agent_id, str(databases)))
        query = model_query(session, Group, filter=Group.group_id == group_id)
        joins = joinedload(Group.entitys, innerjoin=False)
        joins = joins.joinedload(AppEntity.databases, innerjoin=False)
        query = query.options(joins)
        _group = query.one()
        glock = get_gamelock()
        with glock.grouplock(group_id):
            if objtype == common.GAMESERVER:
                _pquery = model_query(session,
                                      Package,
                                      filter=Package.group_id == group_id)
                _packages = set([
                    p.package_id for p in _pquery.all()
                    if p.platform & platform
                ])

                if (include - _packages) or (exclude - _packages):
                    raise InvalidArgument(
                        'Package can not be found in include or exclude')
                if exclude:
                    packages = _packages - exclude
                elif include:
                    packages = include
                else:
                    packages = _packages

            typemap = {}
            for _entity in _group.entitys:
                # 跳过未激活的实体
                if _entity.status != common.OK:
                    continue
                try:
                    typemap[_entity.objtype].append(_entity)
                except KeyError:
                    typemap[_entity.objtype] = [
                        _entity,
                    ]
            # 前置实体
            chiefs = None
            # 相同类型的实例列表
            same_type_entitys = typemap.get(objtype, [])
            if objtype == common.GMSERVER:
                # GM服务不允许相同实例,必须clean掉所有同组GM服务器
                for _entity in _group.entitys:
                    if _entity.objtype == common.GMSERVER:
                        return resultutils.results(
                            result='create entity fail, %s duplicate in group'
                            % objtype,
                            resultcode=manager_common.RESULT_ERROR)
            else:
                # 非gm实体添加需要先找到同组的gm
                try:
                    gm = typemap[common.GMSERVER][0]
                    if gm.status <= common.DELETED:
                        return resultutils.results(
                            result='Create entity fail, gm mark deleted',
                            resultcode=manager_common.RESULT_ERROR)
                except KeyError as e:
                    return resultutils.results(
                        result='Create entity fail, can not find GMSERVER: %s'
                        % e.message,
                        resultcode=manager_common.RESULT_ERROR)
                if objtype == common.GAMESERVER:

                    if model_count_with_key(
                            session,
                            GameArea,
                            filter=and_(GameArea.group_id == group_id,
                                        GameArea.areaname == areaname)):
                        return resultutils.results(
                            result='Create entity fail, name exist',
                            resultcode=manager_common.RESULT_ERROR)
                    cross = None
                    # 游戏服务器需要在同组中找到cross实例
                    try:
                        crossservers = typemap[common.CROSSSERVER]
                    except KeyError as e:
                        return resultutils.results(
                            result=
                            'create entity fail, can not find my chief: %s' %
                            e.message,
                            resultcode=manager_common.RESULT_ERROR)
                    # 如果指定了cross实例id
                    if cross_id:
                        # 判断cross实例id是否在当前组中
                        for _cross in crossservers:
                            if cross_id == _cross.entity:
                                cross = _cross
                                break
                    else:
                        # 游戏服没有相同实例,直接使用第一个cross实例
                        if not same_type_entitys:
                            cross = crossservers[0]
                        else:
                            # 统计所有cross实例的引用次数
                            counted = set()
                            counter = dict()
                            for _cross in crossservers:
                                counter.setdefault(_cross.entity, 0)
                            # 查询当前组内所有entity对应的cross_id
                            for _entity in _group.entitys:
                                if _entity.objtype != common.GAMESERVER:
                                    continue
                                if _entity.cross_id in counted:
                                    continue
                                counter[_entity.cross_id] += 1
                            # 选取引用次数最少的cross_id
                            cross_id = sorted(
                                zip(counter.itervalues(),
                                    counter.iterkeys()))[0][1]
                            for _cross in crossservers:
                                if cross_id == _cross.entity:
                                    cross = _cross
                                    break
                    if not cross:
                        raise InvalidArgument(
                            'cross server can not be found or not active')
                    # 获取实体相关服务器信息(端口/ip)
                    maps = entity_controller.shows(
                        endpoint=common.NAME,
                        entitys=[gm.entity, cross.entity])
                    for v in six.itervalues(maps):
                        if v is None:
                            raise InvalidArgument(
                                'Get chiefs info error, agent not online?')
                    chiefs = dict()
                    # 战场与GM服务器信息
                    for chief in (cross, gm):
                        chiefmetadata = maps.get(chief.entity).get('metadata')
                        ports = maps.get(chief.entity).get('ports')
                        if not chiefmetadata:
                            raise InvalidArgument(
                                '%s.%d is offline' %
                                (chief.objtype, chief.entity))
                        need = common.POSTS_COUNT[chief.objtype]
                        if need and len(ports) != need:
                            raise InvalidArgument('%s.%d port count error, '
                                                  'find %d, need %d' %
                                                  (chief.objtype, chief.entity,
                                                   len(ports), need))
                        chiefs.setdefault(
                            chief.objtype,
                            dict(entity=chief.entity,
                                 ports=ports,
                                 local_ip=chiefmetadata.get('local_ip')))
                    cross_id = cross.entity
            # 完整的rpc数据包
            create_body = dict(objtype=objtype,
                               appfile=appfile,
                               databases=databases,
                               chiefs=chiefs,
                               entity=int(body.get('entity', 0)))

            with session.begin():
                body.setdefault('finishtime', rpcfinishtime()[0] + 5)
                try:
                    create_result = entity_controller.create(
                        req=req,
                        agent_id=agent_id,
                        endpoint=common.NAME,
                        body=create_body)['data'][0]
                except RpcResultError as e:
                    LOG.error('Create entity rpc call fail: %s' % e.message)
                    raise InvalidArgument(e.message)
                entity = create_result.get('entity')
                rpc_result = create_result.get('notify')
                LOG.info('Create new entity %d' % entity)
                LOG.debug('Entity controller create rpc result %s',
                          str(rpc_result))
                # 插入实体信息
                appentity = AppEntity(entity=entity,
                                      agent_id=agent_id,
                                      group_id=group_id,
                                      objtype=objtype,
                                      cross_id=cross_id,
                                      opentime=opentime,
                                      platform=platform)
                session.add(appentity)
                session.flush()
                if objtype == common.GAMESERVER:
                    areaname = areaname.decode('utf-8') if isinstance(
                        areaname, six.binary_type) else areaname
                    gamearea = GameArea(group_id=_group.group_id,
                                        show_id=show_id,
                                        areaname=areaname,
                                        gid=None,
                                        entity=appentity.entity)
                    session.add(gamearea)
                    session.flush()
                    # area id插入渠道包包含列表中,批量操作
                    if packages:
                        for package_id in packages:
                            session.add(
                                PackageArea(package_id=package_id,
                                            area_id=gamearea.area_id))
                            session.flush()
                # 插入数据库绑定信息
                if rpc_result.get('databases'):
                    self._bondto(session, entity, rpc_result.get('databases'))
                else:
                    LOG.error('New entity database miss')

            _result = dict(entity=entity,
                           objtype=objtype,
                           agent_id=agent_id,
                           connection=rpc_result.get('connection'),
                           ports=rpc_result.get('ports'),
                           databases=rpc_result.get('databases'))

            areas = []
            if objtype == common.GAMESERVER:
                areas = [
                    dict(area_id=gamearea.area_id,
                         gid=0,
                         areaname=areaname,
                         show_id=show_id)
                ]
                _result.setdefault('areas', areas)
                _result.setdefault('cross_id', cross_id)
                _result.setdefault('opentime', opentime)
                _result.setdefault('platform', platform)
                _result.setdefault('packages', sorted(packages))

        # 添加端口
        # threadpool.add_thread(port_controller.unsafe_create,
        #                       agent_id, common.NAME, entity, rpc_result.get('ports'))
        port_controller.unsafe_create(agent_id, common.NAME, entity,
                                      rpc_result.get('ports'))
        # agent 后续通知
        threadpool.add_thread(entity_controller.post_create_entity,
                              entity,
                              common.NAME,
                              objtype=objtype,
                              status=common.UNACTIVE,
                              opentime=opentime,
                              group_id=group_id,
                              areas=areas)
        return resultutils.results(result='create %s entity success' % objtype,
                                   data=[
                                       _result,
                                   ])
コード例 #27
0
    def reset(self, req, group_id, objtype, entity, body=None):
        """重置Entity程序以及配置"""
        body = body or {}
        group_id = int(group_id)
        entity = int(entity)
        # 重置程序文件,为空表示不需要重置程序文件
        appfile = body.pop(common.APPFILE, None)
        # 重置数据库信息
        databases = body.pop('databases', False)
        # 重置主服务器信息(gameserver专用)
        chiefs = body.pop('chiefs', False)
        # 查询entity信息
        session = endpoint_session()
        query = model_query(session,
                            AppEntity,
                            filter=AppEntity.entity == entity)
        query = query.options(joinedload(AppEntity.databases, innerjoin=False))
        _entity = query.one()
        if _entity.objtype != objtype:
            raise InvalidArgument('Entity is not %s' % objtype)
        if _entity.group_id != group_id:
            raise InvalidArgument('Entity group %d not match  %d' %
                                  (_entity.group_id, group_id))
        entityinfo = entity_controller.show(req=req,
                                            entity=entity,
                                            endpoint=common.NAME,
                                            body={'ports': False})['data'][0]
        agent_id = entityinfo['agent_id']
        metadata = entityinfo['metadata']
        if not metadata:
            raise InvalidArgument('Agent is off line, can not reset entity')
        # 需要更新数据库
        if databases:
            miss = []
            databases = {}
            # 从本地查询数据库信息
            for database in _entity.databases:
                subtype = database.subtype
                schema = '%s_%s_%s_%d' % (common.NAME, objtype, subtype,
                                          entity)
                databases[subtype] = dict(host=database.host,
                                          port=database.port,
                                          user=database.user,
                                          passwd=database.passwd,
                                          schema=schema,
                                          character_set=database.character_set)

            # 必要数据库信息
            NEEDED = common.DBAFFINITYS[objtype].keys()
            # 数据库信息不匹配,从gopdb接口反查数据库信息
            if set(NEEDED) != set(databases.keys()):
                LOG.warning(
                    'Database not match, try find schema info from gopdb')
                quotes = schema_controller.quotes(
                    req, body=dict(entitys=[
                        entity,
                    ], endpoint=common.NAME))['data']
                for subtype in NEEDED:
                    if subtype not in databases:
                        # 从gopdb接口查询引用信息
                        schema = '%s_%s_%s_%d' % (common.NAME, objtype,
                                                  subtype, entity)
                        for quote_detail in quotes:
                            # 确认引用不是从库且结构名称相等
                            if quote_detail['qdatabase_id'] == quote_detail['database_id'] \
                                    and quote_detail['schema'] == schema:
                                databases.setdefault(
                                    subtype,
                                    dict(host=quote_detail['host'],
                                         port=quote_detail['port'],
                                         user=quote_detail['user'],
                                         passwd=quote_detail['passwd'],
                                         schema=schema,
                                         character_set=quote_detail[
                                             'character_set']))
                                miss.append(
                                    AreaDatabase(
                                        quote_id=quote_detail['quote_id'],
                                        database_id=quote_detail[
                                            'qdatabase_id'],
                                        entity=entity,
                                        subtype=subtype,
                                        host=quote_detail['host'],
                                        port=quote_detail['port'],
                                        user=quote_detail['user'],
                                        passwd=quote_detail['passwd'],
                                        ro_user=quote_detail['ro_user'],
                                        ro_passwd=quote_detail['ro_passwd'],
                                        character_set=quote_detail[
                                            'character_set']))
                                quotes.remove(quote_detail)
                                break
                        if subtype not in databases:
                            LOG.critical('Miss database of %s' % schema)
                            # 数据库信息无法从gopdb中反查到
                            raise ValueError(
                                'Not %s.%s database found for %d' %
                                (objtype, subtype, entity))
            self._validate_databases(objtype, databases)
            # 有数据库信息遗漏
            if miss:
                with session.begin():
                    for obj in miss:
                        session.add(obj)
                        session.flush()

        if objtype == common.GAMESERVER and chiefs:
            chiefs = {}
            cross_id = _entity.cross_id
            if cross_id is None:
                raise ValueError('%s.%d cross_id is None' % (objtype, entity))
            query = model_query(session,
                                AppEntity,
                                filter=and_(
                                    AppEntity.group_id == group_id,
                                    or_(AppEntity.entity == cross_id,
                                        AppEntity.objtype == common.GMSERVER)))
            _chiefs = query.all()
            if len(_chiefs) != 2:
                raise ValueError(
                    'Try find %s.%d chiefs from local database error' %
                    (objtype, entity))
            for chief in _chiefs:
                for _objtype in (common.GMSERVER, common.CROSSSERVER):
                    _metadata, ports = self._entityinfo(req, chief.entity)
                    if not _metadata:
                        raise InvalidArgument('Metadata of %s.%d is none' %
                                              (_objtype, chief.entity))
                    if chief.objtype == _objtype:
                        chiefs[_objtype] = dict(
                            entity=chief.entity,
                            ports=ports,
                            local_ip=_metadata.get('local_ip'))
            if len(chiefs) != 2:
                raise ValueError('%s.%d chiefs error' % (objtype, entity))

        target = targetutils.target_agent_by_string(metadata.get('agent_type'),
                                                    metadata.get('host'))
        target.namespace = common.NAME
        rpc = get_client()
        finishtime, timeout = rpcfinishtime()
        if appfile:
            finishtime += 30
            timeout += 35
        rpc_ret = rpc.call(target,
                           ctxt={
                               'finishtime': finishtime,
                               'agents': [
                                   agent_id,
                               ]
                           },
                           msg={
                               'method':
                               'reset_entity',
                               'args':
                               dict(entity=entity,
                                    appfile=appfile,
                                    opentime=_entity.opentime,
                                    databases=databases,
                                    chiefs=chiefs)
                           },
                           timeout=timeout)
        if not rpc_ret:
            raise RpcResultError('reset entity result is None')
        if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
            raise RpcResultError('reset entity fail %s' %
                                 rpc_ret.get('result'))
        return resultutils.results(result='reset entity %d success' % entity)
コード例 #28
0
ファイル: curd.py プロジェクト: lolizeppelin/gogamechen3
 def update(self, req, group_id, objtype, entity, body=None):
     body = body or {}
     group_id = int(group_id)
     entity = int(entity)
     status = body.get('status', common.OK)
     if status not in (common.UNACTIVE, common.OK):
         raise InvalidArgument('Status not in 0, 1, 2')
     session = endpoint_session()
     glock = get_gamelock()
     query = model_query(session,
                         AppEntity,
                         filter=AppEntity.entity == entity)
     if objtype == common.GAMESERVER:
         query = query.options(joinedload(AppEntity.areas, innerjoin=False))
     _entity = query.one()
     if status == _entity.status:
         return resultutils.results(result='%s entity status in same' %
                                    objtype)
     if _entity.status not in (common.OK, common.UNACTIVE):
         return resultutils.results(
             resultcode=manager_common.RESULT_ERROR,
             result='%s entity is not ok or unactive' % objtype)
     if _entity.objtype != objtype:
         raise InvalidArgument('Objtype not match')
     if _entity.group_id != group_id:
         raise InvalidArgument('Group id not match')
     entityinfo = entity_controller.show(req=req,
                                         entity=entity,
                                         endpoint=common.NAME,
                                         body={'ports': False})['data'][0]
     agent_id = entityinfo['agent_id']
     metadata = entityinfo['metadata']
     if not metadata:
         raise InvalidArgument('Agent is off line, can not reset entity')
     rpc = get_client()
     target = targetutils.target_agent_by_string(metadata.get('agent_type'),
                                                 metadata.get('host'))
     target.namespace = common.NAME
     if objtype == common.GAMESERVER:
         lock = functools.partial(
             glock.arealock,
             group=group_id,
             areas=[area.area_id for area in _entity.areas])
     else:
         lock = functools.partial(glock.grouplock, group=group_id)
     with lock():
         with session.begin():
             _entity.status = status
             session.flush()
             finishtime, timeout = rpcfinishtime()
             rpc_ret = rpc.call(target,
                                ctxt={
                                    'finishtime': finishtime,
                                    'agents': [
                                        agent_id,
                                    ]
                                },
                                msg={
                                    'method': 'change_status',
                                    'args': dict(entity=entity,
                                                 status=status)
                                },
                                timeout=timeout)
             if not rpc_ret:
                 raise RpcResultError('change entity sttus result is None')
             if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
                 raise RpcResultError('change entity status fail %s' %
                                      rpc_ret.get('result'))
     return resultutils.results(result='%s entity update success' % objtype)
コード例 #29
0
ファイル: curd.py プロジェクト: lolizeppelin/gogamechen3
 def delete(self, req, group_id, objtype, entity, body=None):
     """标记删除entity"""
     body = body or {}
     force = body.get('force', False)
     group_id = int(group_id)
     entity = int(entity)
     session = endpoint_session()
     glock = get_gamelock()
     metadata, ports = self._entityinfo(req=req, entity=entity)
     if not metadata:
         raise InvalidArgument('Agent offline, can not delete entity')
     query = model_query(session,
                         AppEntity,
                         filter=AppEntity.entity == entity)
     if objtype == common.GAMESERVER:
         query = query.options(joinedload(AppEntity.areas, innerjoin=False))
     _entity = query.one()
     if _entity.status == common.DELETED:
         return resultutils.results(result='mark %s entity delete success' %
                                    objtype,
                                    data=[
                                        dict(entity=entity,
                                             objtype=objtype,
                                             ports=ports,
                                             metadata=metadata)
                                    ])
     if _entity.objtype != objtype:
         raise InvalidArgument('Objtype not match')
     if _entity.group_id != group_id:
         raise InvalidArgument('Group id not match')
     target = targetutils.target_agent_by_string(metadata.get('agent_type'),
                                                 metadata.get('host'))
     target.namespace = common.NAME
     rpc = get_client()
     with glock.grouplock(group=group_id):
         if objtype == common.GMSERVER:
             if model_count_with_key(
                     session, AppEntity, filter=AppEntity.group_id
                     == group_id) > 1:
                 raise InvalidArgument(
                     'You must delete other objtype entity before delete gm'
                 )
             if model_count_with_key(
                     session, Package, filter=Package.group_id
                     == group_id) > 1:
                 raise InvalidArgument(
                     'You must delete other Package before delete gm')
         elif objtype == common.CROSSSERVER:
             if model_count_with_key(
                     session,
                     AppEntity,
                     filter=AppEntity.cross_id == _entity.entity):
                 raise InvalidArgument('Cross server are reflected')
         with session.begin():
             # 确认实体没有运行
             rpc_ret = rpc.call(target,
                                ctxt={'agents': [
                                    _entity.agent_id,
                                ]},
                                msg={
                                    'method': 'stoped',
                                    'args': dict(entity=entity)
                                })
             if not rpc_ret:
                 raise RpcResultError('check entity stoped result is None')
             if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS:
                 raise RpcResultError('check entity fail %s' %
                                      rpc_ret.get('result'))
             _entity.status = common.DELETED
             session.flush()
             if objtype == common.GAMESERVER:
                 # 删除所有资源版本引用
                 if _entity.versions:
                     for quote in six.itervalues(
                             jsonutils.loads_as_bytes(_entity.versions)):
                         threadpool.add_thread(cdnquote_controller.delete,
                                               req, quote.get('quote_id'))
                 _entity.versions = None
                 session.flush()
                 if _entity.areas:
                     if len(_entity.areas) > 1:
                         raise InvalidArgument('%s areas more then one' %
                                               objtype)
                     area = _entity.areas[0]
                     if not force:
                         if _entity.entity != model_max_with_key(
                                 session,
                                 AppEntity.entity,
                                 filter=and_(
                                     AppEntity.objtype == common.GAMESERVER,
                                     AppEntity.group_id == group_id)):
                             raise InvalidArgument(
                                 'entity %d is not the last gamesvr entity in group'
                                 % entity)
                     session.flush()
                     session.delete(area)
                     session.flush()
                     _query = model_query(
                         session,
                         PackageArea,
                         filter=PackageArea.area_id == area.area_id)
                     _query.delete()
                     session.flush()
             rpc.cast(target,
                      ctxt={'agents': [
                          _entity.agent_id,
                      ]},
                      msg={
                          'method': 'change_status',
                          'args': dict(entity=entity, status=common.DELETED)
                      })
     return resultutils.results(result='mark %s entity delete success' %
                                objtype,
                                data=[
                                    dict(entity=entity,
                                         objtype=objtype,
                                         ports=ports,
                                         metadata=metadata)
                                ])
コード例 #30
0
 def quote_version(self, req, group_id, objtype, entity, body=None):
     """区服包引用指定资源版本"""
     body = body or {}
     if objtype != common.GAMESERVER:
         raise InvalidArgument('Version quote just for %s' %
                               common.GAMESERVER)
     package_id = int(body.get('package_id'))
     rversion = body.get('rversion')
     group_id = int(group_id)
     entity = int(entity)
     session = endpoint_session()
     query = model_query(session, Group, filter=Group.group_id == group_id)
     query = query.options(joinedload(Group.packages, innerjoin=False))
     group = query.one()
     resource_id = None
     for package in group.packages:
         if package.package_id == package_id:
             resource_id = package.resource_id
     if not resource_id:
         raise InvalidArgument(
             'Entity can not find package or package resource is None')
     query = model_query(session,
                         AppEntity,
                         filter=AppEntity.entity == entity)
     query = query.options(joinedload(AppEntity.areas, innerjoin=False))
     with session.begin():
         _entity = query.one()
         if _entity.objtype != objtype:
             raise InvalidArgument('Objtype not match')
         if _entity.group_id != group_id:
             raise InvalidArgument('Group id not match')
         if not model_count_with_key(
                 session,
                 PackageArea.package_id,
                 filter=and_(
                     PackageArea.package_id == package_id,
                     PackageArea.area_id.in_(
                         [area.area_id for area in _entity.areas]))):
             raise InvalidArgument('Entity area not in package areas')
         versions = jsonutils.loads_as_bytes(
             _entity.versions) if _entity.versions else {}
         str_key = str(package_id)
         if str_key in versions:
             quote = versions.get(str_key)
             if quote.get('version') != rversion:
                 body = {'version': rversion}
                 quote.update(body)
                 cdnquote_controller.update(req,
                                            quote.get('quote_id'),
                                            body=body)
         else:
             qresult = cdnresource_controller.vquote(
                 req,
                 resource_id,
                 body={
                     'version': rversion,
                     'desc': '%s.%d' % (common.NAME, entity)
                 })
             quote = qresult['data'][0]
             quote = dict(version=rversion, quote_id=quote.get('quote_id'))
             versions.setdefault(str_key, quote)
         _entity.versions = jsonutils.dumps(versions)
         session.flush()
     return resultutils.results(result='set entity version quote success',
                                data=[
                                    dict(resource_id=resource_id,
                                         version=rversion,
                                         quote_id=quote.get('quote_id'))
                                ])