# -*- coding: utf-8 -*- #!/usr/bin/python import os import sys import time import json import redis import pymysql import datetime import pprint import subprocess from string import Template CHAR_SET_UTF8MB4 = 'default character set utf8mb4 collate utf8mb4_unicode_ci' config_obj = None tools_conf_dir = '../tools_conf/' is_test_env = False if os.path.exists('../tools_conf_test'): tools_conf_dir = '../tools_conf_test/' is_test_env = True def error(msg): print('[ERROR]' + str(msg), flush = True) def info(msg): print('[INFO]' + str(msg), flush = True) def warn(msg): print('[WARN]' + str(msg), flush = True) def checkDBOption(db): dbs = db.split(',') def printDBOption(db): dbs = db.split(',') for dbname in dbs: pass def parseOption(db): dbs = db.split(',') dbnames = [] server_hash = {} for dbname in dbs: if dbname.isdigit(): server_hash[int(dbname)] = 1 elif dbname.find('-') > -1: begin_idx, end_idx = dbname.split('-') for server_id in range(int(begin_idx), int(end_idx) + 1): server_hash[server_id] = 1 else: dbnames.append(dbname) #end for dbs server_list = [] for server_id in server_hash.keys(): server_list.append(server_id) server_list.sort() for server_id in server_list: dbnames.append(str(server_id)) return dbnames def readCombineRule(): json_data = json.loads(open('../tools_conf/combine_rule.json', 'r').read()) return json_data def readRedisRule(): json_data = json.loads(open('../tools_conf/redis_rule.json', 'r').read()) return json_data def readServerListConf(): json_data = json.loads(open('../tools_conf/server_list.json', 'r').read()) assert len(json_data) > 1 mysql_conf = getMysqlConf() for svr in json_data: svr['db_host'] = mysql_conf['db_host'] svr['db_port'] = int(mysql_conf['db_port']) svr['db_user'] = mysql_conf['db_user'] svr['db_passwd'] = mysql_conf['db_passwd'] return json_data def getGlobalRedisConf(): json_data = json.loads(open(tools_conf_dir + 'db_conf.json', 'r').read()) return json_data['global_redis'] def getMysqlConf(): json_data = json.loads(open(tools_conf_dir + 'db_conf.json', 'r').read()) return json_data['mysql'] def getGameConf(server_id): global config_obj conf = config_obj['game'][server_id] assert conf return conf def _checkTables(rule_conf, rows): assert(len(rule_conf) == len(rows)) for row in rows: if row[0] not in rule_conf: error(row[0]) assert False def _checkColumns(table_name, a_columns, b_columans): #print(table_name,a_columns,b_columans) assert len(a_columns) > 0 and len(a_columns) == len(b_columans) for a_col in a_columns: found = False for b_col in b_columans: if a_col['Field'] == b_col['Field']: found = True break #end for b_col if not found: print(a_col, b_col) assert found def checkDB(db_conf, rule_conf): table_columns = {} rolename_hash = {} for conf in db_conf: conn = pymysql.connect(host = conf['db_host'], port = conf['db_port'], user = conf['db_user'], passwd = conf['db_passwd'], db = 'legend_' + str(conf['serverid']), charset = 'utf8' ) assert conn cursor = conn.cursor() cursor.execute('SHOW TABLES;') rows = cursor.fetchall() _checkTables(rule_conf, rows) cursor = conn.cursor(cursor = pymysql.cursors.DictCursor) for rule in rule_conf.values(): cursor.execute('SHOW COLUMNS FROM %s;' % (rule['table_name']) ) rows = cursor.fetchall() if rule['table_name'] in table_columns: _checkColumns(rule['table_name'], table_columns[rule['table_name']], rows) else: table_columns[rule['table_name']] = rows cursor = conn.cursor(cursor = pymysql.cursors.DictCursor) cursor.execute('SELECT * FROM role;') rows = cursor.fetchall() for row in rows: assert row['name'] not in rolename_hash rolename_hash[row['name']] = row # pprint.pprint(row) conn.close() def runLocalCmd(cmd): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) output, error_info = p.communicate() info(output) if p.returncode != 0: errmsg = '' if isinstance(error_info, list) or isinstance(error_info, tuple): errmsg = error_info[0] error(errmsg) def dropDataBase(conf, dbname): info('正在删除%s数据库 host:%s port:%d' % (dbname, conf['db_host'], conf['db_port'])) cmdline = 'mysql -h%s -u%s -p%s -e"drop database if exists %s"' % ( conf['db_host'], conf['db_user'], conf['db_passwd'], dbname, ) info(cmdline) ret = runLocalCmd(cmdline) return ret def clearRedis(conf, redis_name): info('正在删除%s host:%s port:%d' % (redis_name, conf['redis_host'], conf['redis_port'])) cmdline = 'redis-cli -h %s -p %s -n 0 flushdb' % ( conf['redis_host'], conf['redis_port'] ) info(cmdline) ret = runLocalCmd(cmdline) def importMysql(conf, dbname, dumpfile, char_set, nodata = False): info('正在删除%s数据库 host:%s port:%d' % (dbname, conf['db_host'], conf['db_port'])) cmdline = 'mysql -h%s -u%s -p%s -e"drop database if exists %s"' % ( conf['db_host'], conf['db_user'], conf['db_passwd'], dbname, ) info(cmdline) ret = runLocalCmd(cmdline) info('正在创建%s数据库 host:%s port:%d' % (dbname, conf['db_host'], conf['db_port'])) cmdline = 'mysql -h%s -u%s -p%s -e"create database %s %s"' % ( conf['db_host'], conf['db_user'], conf['db_passwd'], dbname, char_set ) info(cmdline) ret = runLocalCmd(cmdline) if not nodata: info('正在导入%s数据 host:%s port:%d' % (dbname, conf['db_host'], conf['db_port'])) cmdline = 'mysql -h%s -u%s -p%s %s -e"source %s"' % ( conf['db_host'], conf['db_user'], conf['db_passwd'], dbname, '../data/mysql/' + dumpfile ) info(cmdline) ret = runLocalCmd(cmdline) def importRedis(conf, redis_name, rdbfile): info('正在删除%s host:%s port:%d' % (redis_name, conf['redis_host'], conf['redis_port'])) cmdline = 'redis-cli -h %s -p %s -n 0 flushdb' % ( conf['redis_host'], conf['redis_port'] ) info(cmdline) ret = runLocalCmd(cmdline) info('正在stop%s host:%s port:%d' % (redis_name, conf['redis_host'], conf['redis_port'])) cmdline = 'ssh %s "systemctl stop redis_%d.service"' % ( conf['redis_host'], conf['redis_port'] ) info(cmdline) ret = runLocalCmd(cmdline) time.sleep(2) assert os.path.exists('../data/redis/%s' % (rdbfile)) info('正在复制%s文件到 host:%s' % (rdbfile, conf['redis_host'])) cmdline = 'scp ../data/redis/%s root@%s:/data/logs/redis/dump_%d.rdb' % ( rdbfile, conf['redis_host'], conf['redis_port'] ) info(cmdline) ret = runLocalCmd(cmdline) cmd = 'ssh %s "chown -R kingsome. /data/logs/redis/"' % (conf['redis_host']) runLocalCmd(cmd) info('正在重启redis导入rdb_%d.rdb' % (conf['redis_port'])) if is_test_env: cmdline = 'ssh %s "redis-server /etc/redis/redis_%d.conf"' % ( # cmdline = 'ssh %s "ls -al" && echo ok' % ( conf['redis_host'], conf['redis_port'], ) else: cmdline = 'ssh %s "systemctl start redis_%d.service"' % ( conf['redis_host'], conf['redis_port'], ) info(cmdline) ret = runLocalCmd(cmdline) def _parseServerList(): server_list = json.loads(open(tools_conf_dir + 'server_list.json', 'r').read()) configObj = { 'group': {}, 'admin': {}, 'conf': {}, 'cross': {}, 'game': {}, 'gate': {}, 'global': {}, 'load': {}, 'logger': {}, 'nginx': {}, 'pay': {}, 'stage': {}, } global config_obj config_obj = configObj groupObj = configObj['group'] gameObj = configObj['game'] loggerObj = configObj['logger'] stageObj = configObj['stage'] confObj = configObj['conf'] mysql_conf = getMysqlConf() for svr in server_list: assert svr['serverid'] not in gameObj gameObj[svr['serverid']] = { 'serverid': svr['serverid'], 'db_host': mysql_conf['db_host'], 'db_port': int(mysql_conf['db_port']), 'db_user': mysql_conf['db_user'], 'db_passwd': mysql_conf['db_passwd'], 'redis_host': svr['redis_host'], 'redis_port': int(svr['redis_port']), '_i': svr } _checkServerList(configObj) def _checkServerList(configObj): pass _parseServerList()