示例#1
0
def _address(database_ids):
    IMPLMAP = {}
    NOT_CACHED = []
    for database_id in database_ids:
        if database_id in MANAGERCACHE:
            try:
                IMPLMAP[MANAGERCACHE[database_id]].append(database_id)
            except KeyError:
                IMPLMAP[MANAGERCACHE[database_id]] = [
                    database_id,
                ]
        else:
            NOT_CACHED.append(database_id)
    if NOT_CACHED:
        session = endpoint_session(readonly=True)
        query = model_query(session,
                            (GopDatabase.database_id, GopDatabase.impl),
                            filter=GopDatabase.database_id.in_(NOT_CACHED))
        for r in query:
            dbmanager = utils.impl_cls('wsgi', r[1])
            try:
                IMPLMAP[dbmanager].append(r[0])
            except KeyError:
                IMPLMAP[dbmanager] = [
                    r[0],
                ]
        session.close()
    maps = dict()
    for dbmanager in IMPLMAP:
        maps.update(dbmanager.address(IMPLMAP[dbmanager]))
    return maps
示例#2
0
 def rpc_unbond_entity(self, ctxt, entity, **kwargs):
     """从库收到解绑主库命令"""
     dbtype = self._dbtype(entity)
     dbinfo = self.konwn_database[entity]
     if dbinfo.get('slave') == 0:
         return resultutils.AgentRpcResult(
             agent_id=self.manager.agent_id,
             resultcode=manager_common.RESULT_ERROR,
             ctxt=ctxt,
             result=
             'Can not unbond from master, database is master database?')
     dbmanager = utils.impl_cls('rpc', dbtype)
     cfgfile = self._db_conf(entity, dbtype)
     with self.lock(entity, timeout=3):
         p = self._entity_process(entity)
         if not p:
             return resultutils.AgentRpcResult(
                 agent_id=self.manager.agent_id,
                 ctxt=ctxt,
                 result='unbond to master faile, slave db process not exist'
             )
         dbmanager.unbond(cfgfile, postrun=None, timeout=None, **kwargs)
     return resultutils.AgentRpcResult(agent_id=self.manager.agent_id,
                                       ctxt=ctxt,
                                       result='unbond from master success')
示例#3
0
 def select(self, req, impl, body=None):
     body = body or {}
     kwargs = dict(req=req)
     kwargs.update(body)
     dbmanager = utils.impl_cls('wsgi', impl)
     dbresult = dbmanager.select_database(**kwargs)
     return resultutils.results(result='select database success',
                                data=dbresult)
示例#4
0
 def agents(self, req, body=None):
     body = body or {}
     kwargs = dict(req=req)
     kwargs.update(body)
     dbtype = body.pop('dbtype', 'mysql') or 'mysql'
     dbmanager = utils.impl_cls('wsgi', 'local')
     dbresult = dbmanager.select_agents(dbtype, **kwargs)
     return resultutils.results(result='select database agents success',
                                data=dbresult)
示例#5
0
 def rpc_stop_entity(self, ctxt, entity, **kwargs):
     dbtype = self._dbtype(entity)
     dbmanager = utils.impl_cls('rpc', dbtype)
     p = self._entity_process(entity)
     if p:
         cfgfile = self._db_conf(entity, dbtype)
         dbmanager.stop(cfgfile, postrun=None, timeout=None, process=p)
     return resultutils.AgentRpcResult(
         agent_id=self.manager.agent_id,
         ctxt=ctxt,
         result='stop database entity success')
示例#6
0
    def rpc_slave_entity(self, ctxt, entity, **kwargs):
        """主库收到绑定从库命令"""
        bond = kwargs.pop('bond')
        dbtype = self._dbtype(entity)
        dbinfo = self.konwn_database[entity]
        port = self._get_port(entity)
        replication = privilegeutils.mysql_replprivileges(
            bond.get('database_id'), bond.get('host'))
        kwargs['replication'] = replication

        if dbinfo.get('slave') != 0:
            return resultutils.AgentRpcResult(
                agent_id=self.manager.agent_id,
                resultcode=manager_common.RESULT_ERROR,
                ctxt=ctxt,
                result='Can not bond a slave, database is not master database?'
            )
        dbmanager = utils.impl_cls('rpc', dbtype)
        cfgfile = self._db_conf(entity, dbtype)
        with self.lock(entity, timeout=3):
            p = self._entity_process(entity)
            if not p:
                return resultutils.AgentRpcResult(
                    agent_id=self.manager.agent_id,
                    resultcode=manager_common.RESULT_ERROR,
                    ctxt=ctxt,
                    result='Cat not bond a slave, master db process not exist')

            def _bond_slave(_binlog, _scheams):
                LOG.debug('Try bond slave database')
                self.client.database_bond(database_id=bond.get('database_id'),
                                          body={
                                              'master':
                                              dbinfo.get('database_id'),
                                              'host': self.manager.local_ip,
                                              'port': port,
                                              'passwd':
                                              replication.get('passwd'),
                                              'file': _binlog.get('File'),
                                              'position':
                                              _binlog.get('Position'),
                                              'schemas': _scheams,
                                          })

            dbmanager.bondslave(cfgfile,
                                postrun=_bond_slave,
                                timeout=None,
                                dbinfo=dbinfo,
                                **kwargs)
        return resultutils.AgentRpcResult(
            agent_id=self.manager.agent_id,
            ctxt=ctxt,
            result='bond slave for master success')
示例#7
0
def _impl(database_id):
    try:
        return MANAGERCACHE[database_id]
    except KeyError:
        session = endpoint_session(readonly=True)
        try:
            database = model_query(
                session, GopDatabase,
                GopDatabase.database_id == database_id).one()
            if database_id not in MANAGERCACHE:
                dbmanager = utils.impl_cls('wsgi', database.impl)
                MANAGERCACHE.setdefault(database_id, dbmanager)
            return MANAGERCACHE[database_id]
        finally:
            session.close()
示例#8
0
 def rpc_revoke_entity(self, ctxt, entity, **kwargs):
     dbtype = self._dbtype(entity)
     dbmanager = utils.impl_cls('rpc', dbtype)
     cfgfile = self._db_conf(entity, dbtype)
     with self.lock(entity, timeout=3):
         p = self._entity_process(entity)
         if not p:
             return resultutils.AgentRpcResult(
                 agent_id=self.manager.agent_id,
                 ctxt=ctxt,
                 result='revoke entity fail, process not exist')
         dbmanager.revoke(cfgfile, postrun=None, timeout=None, **kwargs)
     return resultutils.AgentRpcResult(agent_id=self.manager.agent_id,
                                       ctxt=ctxt,
                                       result='revoke to master success')
示例#9
0
 def rpc_entity_replication_ready(self, ctxt, entity, **kwargs):
     dbtype = self._dbtype(entity)
     dbmanager = utils.impl_cls('rpc', dbtype)
     cfgfile = self._db_conf(entity, dbtype)
     with self.lock(entity, timeout=3):
         p = self._entity_process(entity)
         if not p:
             return resultutils.AgentRpcResult(
                 agent_id=self.manager.agent_id,
                 ctxt=ctxt,
                 result='get replication status fail, process not exist')
         success, msg = dbmanager.replication_status(cfgfile,
                                                     postrun=None,
                                                     timeout=None,
                                                     **kwargs)
     return resultutils.AgentRpcResult(
         agent_id=self.manager.agent_id,
         resultcode=manager_common.RESULT_SUCCESS
         if success else manager_common.RESULT_ERROR,
         ctxt=ctxt,
         result=msg)
示例#10
0
 def rpc_start_entity(self, ctxt, entity, **kwargs):
     dbtype = self._dbtype(entity)
     dbmanager = utils.impl_cls('rpc', dbtype)
     cfgfile = self._db_conf(entity, dbtype)
     p = self._entity_process(entity)
     with self.lock(entity, timeout=3):
         if not p:
             dbmanager.start(cfgfile)
             eventlet.sleep(0.5)
             p = self._entity_process(entity)
     if not p:
         return resultutils.AgentRpcResult(
             agent_id=self.manager.agent_id,
             resultcode=manager_common.RESULT_ERROR,
             ctxt=ctxt,
             result='start entity faile, process not exist after start')
     return resultutils.AgentRpcResult(
         agent_id=self.manager.agent_id,
         ctxt=ctxt,
         result='start entity success, runinng on pid %d' %
         p.info.get('pid'))
示例#11
0
 def create(self, req, body=None):
     body = body or {}
     jsonutils.schema_validate(body, self.CREATEDATABASE)
     impl = body.pop('impl')
     dbtype = body.pop('dbtype')
     user = body.pop('user')
     passwd = body.pop('passwd')
     dbversion = body.pop('dbversion', None)
     affinity = body.pop('affinity', 0)
     if body.get('slave'):
         if body.get('bond'):
             raise InvalidArgument(
                 'Slave database can not bond to another database ')
         affinity = 0
     kwargs = dict(req=req)
     kwargs.update(body)
     dbmanager = utils.impl_cls('wsgi', impl)
     dbresult = dbmanager.create_database(user, passwd, dbtype, dbversion,
                                          affinity, **kwargs)
     return resultutils.results(result='create database success',
                                data=[
                                    dbresult,
                                ])
示例#12
0
    def create_entity(self, entity, timeout, **kwargs):
        """
        @param dbtype:        string 数据库类型
        @param configs:       dict   数据库配置字典
        @param auth:          dict   远程管理员账号密码
        @param bond:          dict   需要绑定的从库(主库专用参数)
        """
        dbtype = kwargs.pop('dbtype')
        configs = kwargs.pop('configs', {})
        bond = kwargs.pop('bond', None)
        if bond:
            replication = privilegeutils.mysql_replprivileges(
                bond.get('database_id'), bond.get('host'))
            kwargs['replication'] = replication
        port = configs.pop('port', None)
        pidfile = os.path.join(self.entity_home(entity), '%s.pid' % dbtype)
        sockfile = os.path.join(self.entity_home(entity), '%s.sock' % dbtype)
        logfile = os.path.join(self.logpath(entity), '%s.log' % dbtype)
        install_log = os.path.join(self.logpath(entity), 'install.log')
        cfgfile = self._db_conf(entity, dbtype)
        LOG.info('Load database manager for %s' % dbtype)
        dbmanager = utils.impl_cls('rpc', dbtype)

        with self._prepare_entity_path(entity, apppath=False):
            with self._allocate_port(entity, port) as ports:
                port = ports[0]
                configs.setdefault('entity', entity)
                configs.setdefault('port', port)
                configs.setdefault('datadir', self.apppath(entity))
                configs.setdefault('pidfile', pidfile)
                configs.setdefault('sockfile', sockfile)
                configs.setdefault('logfile', logfile)
                configs.setdefault('runuser', self.entity_user(entity))
                dbmanager.save_conf(cfgfile, **configs)
                LOG.info('Prepare database config file success')

                def _notify_success(binlog):
                    """notify database intance create success"""
                    self.manager.change_performance()
                    dbinfo = self.konwn_database.get(entity)
                    if not dbinfo:
                        LOG.warning(
                            'Can not find entity database id, active fail')
                        return
                    if bond:
                        LOG.debug('Try bond slave database')
                        self.client.database_bond(
                            database_id=bond.get('database_id'),
                            body={
                                'master': dbinfo.get('database_id'),
                                'host': self.manager.local_ip,
                                'port': port,
                                'passwd': replication.get('passwd'),
                                'file': binlog.get('File'),
                                'position': binlog.get('Position'),
                                'schemas': [],
                            })
                    if self._entity_process(entity):
                        self.client.database_update(
                            database_id=dbinfo.get('database_id'),
                            body={'status': common.OK})

                kwargs.update({'logfile': install_log})
                threadpool.add_thread(dbmanager.install, cfgfile,
                                      _notify_success, timeout, **kwargs)

        # def _port_notify():
        #     """notify port bond"""
        #     _timeout = timeout if timeout else 30
        #     overtime = int(time.time()) + _timeout
        #     while entity not in self.konwn_database:
        #         if int(time.time()) > overtime:
        #             LOG.error('Fail allocate port %d for %s.%d' % (ports[0], common.DB, entity))
        #             return
        #         eventlet.sleep(1)
        #     self.client.ports_add(agent_id=self.manager.agent_id,
        #                           endpoint=common.DB, entity=entity, ports=ports)

        # threadpool.add_thread(_port_notify)
        return port