def tcp_port(self):
"""
The tcp port used for the game server. Will try to get only once and save to self._tcp_port for later use.
"""
def get_tcp_port():
cmd = '''grep 'name="port" type="int"' conf.xml |awk -F[\<\>] '{print $3}' '''
@hosts(self.int_ip)
def _get_tcp_port():
with cd('/app/{}/backend/apps'.format(self.name)):
result = run(cmd)
lines = result.splitlines()
if len(lines) == 1:
return int(lines[0])
else:
raise Exception("Can't get tcp port using cmd: {}".format(cmd))
result = execute(_get_tcp_port)
return result[self.int_ip]
if not self._tcp_port:
self._tcp_port = get_tcp_port()
return self._tcp_port
python类hosts()的实例源码
def dns(self):
"""
The dns for the game server. Will try to get only once and save to self._dns for later use.
"""
def get_dns():
cmd = '''grep server_name %s.conf | awk '{print $2}' | tr -d ";" ''' % self.name
@hosts(self.int_ip)
def _get_dns():
with cd('/app/nginx/conf/vhost'.format(self.name)):
result = run(cmd)
lines = result.splitlines()
if len(lines) == 1:
return lines[0]
else:
raise Exception("Can't get dns using cmd: {}".format(cmd))
result = execute(_get_dns)
return result[self.int_ip]
if not self._dns:
self._dns = get_dns()
return self._dns
def modify_mobile_www_config(game, region, scopes, filename, option_name, option_value):
conf = ConfigReader(game, region)
ip = conf.get("mobile_www_ip")
if conf.has_option("mobile_www_port"):
"""
????????????ssh?????????Fabric?????host???
"""
port = conf.getint("mobile_www_port")
if port:
ip = '{}:{}'.format(ip, port)
root_dir = conf.get("mobile_www_root_test")
@hosts(ip)
def _modify_mobile_www_config():
for each_scope in scopes:
with cd(root_dir):
_filename = '{}/{}'.format(each_scope, filename)
config_file = MConfig(_filename)
config_file.modify(key=option_name, value=option_value)
execute(_modify_mobile_www_config)
def bundle_merge(file):
merge_details = parse_merge_list(file)
print(merge_details)
target_servers = merge_details.keys()
print(target_servers)
@parallel(pool_size=2) #???????????
def _bundle_merge():
target_server = GameServer(env.host_string)
source_server_info_list = merge_details[target_server]
for each_server, each_sequence in source_server_info_list[:-1]:
each_source_server = GameServer(each_server)
single_merge(each_source_server, target_server, each_sequence)
#???????????????????????????????????
#??: ???37wan_8,37wan_9,37wan_10??37wan_7???37wan_10??????????????????37wan_7?
last_source_server, last_sequence = source_server_info_list[-1]
single_merge(last_source_server, target_server, last_sequence, restart='yes')
execute(_bundle_merge, hosts=target_servers)
print('Done!')
def add_match_dns(self):
@hosts('dns')
def _add_match_dns(id, ip):
dns_add_cmd = '/app/opbin/dns/dnsapi -g {0} -a add -d match{1}.{0} -l 1 -i {2}'.format(GAME, id, ip)
print('??????????????: {}'.format(dns_add_cmd))
ret_value = run(dns_add_cmd)
if ret_value != 'Record add success':
print('[WARNING] Failed to add dns, you can try again manually: {}'.format(dns_add_cmd))
execute(_add_match_dns, self.id, self.ip)
# def clean_job(self):
#
# @hosts(self.template_matchServer)
# def _clean_on_template_server():
# with cd('/app/nginx/conf/vhost'):
# run('rm -f download_{}.conf'.format(TIME))
# reload_nginx()
#
# execute(_clean_on_template_server)
def set_host(host_index):
"""A helper task to change env.hosts from the
command line. It will only "stick" for the duration
of the fab command that called it.
Args:
host_index (int): 0, 1, 2, 3, etc.
Example:
fab set_host:4 fab_task_A fab_task_B
will set env.hosts = [public_dns_names[4]]
but only for doing fab_task_A and fab_task_B
"""
env.hosts = [public_hosts[int(host_index)]]
env.password = [public_pwds[int(host_index)]]
# Install base software
def set_allnodes():
#read by line
f=open('blockchain-nodes')
for line in f.readlines():
temp=line.strip('\r\n').split(" ")
host=temp[0]
password=temp[1]
env['passwords'][host]=password
# order
env['hosts']=env['passwords'].keys()
#set on node
def upload_log(self, gameserver, logtype=None, date=None, logfile=None):
from bible.utils import BZIP2
gameserver = GameServer(gameserver)
ftp_log_path = '/{}_log/{}'.format(gameserver.game, gameserver.name)
logtypes = ['dayreport', 'rtreport']
date = date if date else time.strftime('%Y-%m-%d')
if logfile:
logfiles = [logfile]
else:
if logtype:
logfiles = ['/app/{0}/backend/logs/game/{1}/{1}_{2}.log'.format(gameserver.name, logtype, date)]
else:
logfiles = ['/app/{0}/backend/logs/game/{1}/{1}_{2}.log'.format(gameserver.name, each_logtype, date) for each_logtype in logtypes]
@hosts(gameserver.int_ip)
def _upload_log():
for each_log in logfiles:
dir, filename = os.path.split(each_log)
with cd(dir):
file_bz2 = '{}.bz2'.format(filename)
file_md5 = '{}.MD5'.format(file_bz2)
run('[ -f {0} ] && echo "{0} already exists" || {1} {2}'.format(file_bz2, BZIP2, filename))
run('[ -f {0} ] && echo "{0} already exists" || md5sum {1} >{0}'.format(file_md5, file_bz2))
run('''pandora --ftp -r 30 -t 1200 -z -m {} {} {}.bz2*'''.format(self.ip, ftp_log_path, each_log) )
execute(_upload_log)
def get_external_ip(int_ip):
@hosts(int_ip)
def _get_external_ip():
ext_ip = run('''curl -s ip.cn |awk '{split($2,x,"?");print x[2]}' ''')
return ext_ip
ret_value = execute(_get_external_ip)[int_ip]
return ret_value
def transform(self, gameServers, all_gameServer_info=None):
"""
Transform funcion.
eg: it will transformat from
['astd_37wan_2', 'astd_51wan_99', 'astd_uoyoo_90']
to
{
'10.6.20.1':['astd_37wan_2', 'astd_51wan_99'],
'10.6.20.2':['astd_uoyoo_90']
}
"""
if not all_gameServer_info:
all_gameServer_info = self.all_gameServer_info
IPS = list(set([ all_gameServer_info[each] for each in gameServers ]))
locate_game_servers = { each:[] for each in IPS }
for each in gameServers:
locate_game_servers[all_gameServer_info[each]].append(each)
return locate_game_servers
# def sql_content_exec(self, gameServers, sql_content, backup='Yes', remote_dir=REMOTE_DIR):
# locate_game_servers = self.transform(gameServers)
# ips = locate_game_servers.keys()
#
# def _sql_content_exec(sql_content, locate_game_servers, backup):
# for gameServer in locate_game_servers[env.host_string]:
# backup_dir = '{}/{}'.format(remote_dir, gameServer)
# run('[ -d {0} ] || mkdir -p {0}'.format(backup_dir))
# if backup.lower() == 'yes':
# run('pandora --dump --opt -R {0} >{1}/rollback_{0}.sql'.format(gameServer, backup_dir))
# run('''pandora --update {} -e '{}' '''.format(gameServer, sql_content))
#
# execute(_sql_content_exec, sql_content, locate_game_servers, backup=backup, hosts=ips)
#
def mkdir(self, remote_dir):
@hosts(self.int_ip)
def _mkdir():
run(' [ -d {0} ] || mkdir -p {0} '.format(remote_dir))
execute(_mkdir)
def dump_db(self, remote_dir, timestamp=TIMESTAMP):
dest = '{}/{}.sql.rb{}'.format(remote_dir, self.name, timestamp)
self.mkdir(os.path.dirname(dest))
@hosts(self.int_ip)
def _dump_db():
run('''pandora --dump --opt -R {} >{}'''.format(self.name, dest))
return dest
result = execute(_dump_db)
return result[self.int_ip]
def _operation(self, action):
def _op():
run('set -m; /app/{}/backend/bin/startup.sh {} && sleep 0.2'.format(self.name, action), warn_only=True)
execute(_op, hosts=[self.int_ip])
def remove(self, remote_dir=None):
"""????????????????(nginx, backstage)"""
if remote_dir is None:
release_type = 'game_backup'
remote_dir = '/app/opbak/{}_{}'.format(release_type, TIMESTAMP)
self.stop()
@hosts(self.int_ip)
def _remove_game_server():
mk_remote_dir(remote_dir)
with cd('/app'):
run('mv {} {}/'.format(self.name, remote_dir))
with cd(remote_dir):
run('pandora --dump --opt -R {0}>{0}.sql.rb{1}'.format(self.name, TIMESTAMP))
run('mv /app/nginx/conf/vhost/{}.conf ./'.format(self.name))
reload_nginx()
run('pandora --update -e "DROP DATABASE {}"'.format(self.name))
with cd('/app/{}_backstage'.format(self.game)):
run('cp socket_gameserver.ini {}/'.format(remote_dir))
run("sudo -u agent sed -i '/\\b{}\\b/d' socket_gameserver.ini".format(self.name))
run("set -m; sudo -u agent /bin/bash start.sh restart")
execute(_remove_game_server)
def upload_log(self, logtype=None, date=None, logfile=None, ftp_ip=None):
"""
An example: pandora --ftp -r 30 -t 1200 -z -m 42.62.119.164 /tjmob_log/tjmob_37wan_1 /app/tjmob_37wan_1/backend/logs/game/dayreport/dayreport_2015-05-03.log.bz2*
"""
from bible.utils import BZIP2
ftp_log_path = '/{}_log/{}'.format(self.game, self.name)
logtypes = ['dayreport', 'rtreport']
date = date if date else time.strftime('%Y-%m-%d')
ftp_ip = ftp_ip if ftp_ip else '42.62.119.164'
if logfile:
logfiles = [logfile]
else:
if logtype:
logfiles = ['/app/{0}/backend/logs/game/{1}/{1}_{2}.log'.format(self.name, logtype, date)]
else:
logfiles = ['/app/{0}/backend/logs/game/{1}/{1}_{2}.log'.format(self.name, each_logtype, date) for each_logtype in logtypes]
@hosts(self.int_ip)
def _upload_log():
for each_log in logfiles:
dir, filename = os.path.split(each_log)
with cd(dir):
file_bz2 = '{}.bz2'.format(filename)
file_md5 = '{}.MD5'.format(file_bz2)
run('[ -f {0} ] && echo "{0} already exists" || {1} {2}'.format(file_bz2, BZIP2, filename))
run('[ -f {0} ] && echo "{0} already exists" || md5sum {1} >{0}'.format(file_md5, file_bz2))
run('''pandora --ftp -r 30 -t 1200 -z -m {} {} {}.bz2*'''.format(ftp_ip, ftp_log_path, each_log) )
execute(_upload_log)
#End class GameServer
###############################################
def dnsapi(game, action, domain, line, ip, debug=False):
if not debug: #??????debug????
from fabric.api import output
output.everything = False
@hosts(DNS_SERVER)
def _dnsapi():
result = run('/app/opbin/dns/dnsapi -g {game} -a {action} -d {domain} -l {line} -i {ip}'.format(game=game, action=action, domain=domain, line=line, ip=ip))
print(result)
execute(_dnsapi)
def print_help():
with quiet():
@hosts(DNS_SERVER)
def _dnsapi():
result = run('/app/opbin/dns/dnsapi -h')
print(result)
execute(_dnsapi)
def template_matchServer_running(template_matchServer_ip, template_matchServer_id=1):
template_matchServer = '{}_match_{}'.format(GAME, template_matchServer_id)
@hosts(template_matchServer_ip)
def _template_matchServer_running():
with quiet():
running = run('ps x | grep "[j]ava -Dstart.home=/app/{}/backend"'.format(template_matchServer)).succeeded
if not running:
raise Exception("Can't find the running java process for {}".format(template_matchServer))
execute(_template_matchServer_running)
def matchServer_exists(matchServer, ip):
with quiet():
exists = local('''grep "\\b{}\\b" /etc/hosts '''.format(matchServer)).succeeded
if exists:
raise Exception('''The match server {} already exists in /etc/hosts'''.format(matchServer))
else:
matchServer_dir_exists = execute(remote_dir_exists, '/app/{}'.format(matchServer), hosts=[ip])[ip]
if matchServer_dir_exists:
raise Exception('''The match dir: /app/{} already exists on {}'''.format(matchServer, ip))
#def create_nginx_conf(remote_dir):
# server_name = 'match_download_{}'.format(TIME)
# conf_name = 'download_{}.conf'.format(TIME)
# with cd('/app/nginx/conf/vhost'):
# run('''echo -e "server {\\n listen 80;\\n server_name %s;\\n root %s;\\n index Main.html;\\n access_log logs/default.access.log main;\\n location / {\\n expires 0;\\n }\\n\\n error_page 404 500 502 503 504 /404.html;\\n}" >%s''' % (server_name, remote_dir, conf_name))
def job_on_template_server(self):
@hosts(self.template_matchServer_ip)
def _job_on_template_server():
mk_remote_dir(self.remote_dir)
print('???{}????????????????{}/package.tgz ...'.format(self.template_matchServer, self.remote_dir))
packaging_data(self.template_matchServer, self.remote_dir)
#print('??????????...')
#create_nginx_conf(self.remote_dir)
#reload_nginx()
#ext_ip = run('''curl -s ipip.net |awk '{split($2,x,"?");print x[2]}' ''')
#return ext_ip
#self.template_matchServer_ip = execute(_job_on_template_server)[self.template_matchServer]
execute(_job_on_template_server)
def add_match_to_gw(self):
@hosts('{}_gw'.format(GAME))
def _add_match_to_gw():
gw_db_name = '{}_gw'.format(GAME)
mk_remote_dir(self.remote_dir)
with cd(self.remote_dir):
run('''pandora --dump --opt -R {0} match_server_info >{0}.match_server_info.sql.rb{1}'''.format(gw_db_name, TIME))
run('''pandora --update {} -e 'INSERT INTO match_server_info (type,match_adress,match_id,match_name) VALUES (1,"{}:8092",{},"{}_match_{}");' '''.format(gw_db_name, self.dns, self.id, GAME, self.id))
result = run('''pandora {} -e 'SELECT * FROM match_server_info' '''.format(gw_db_name))
print('?????\n??GW?????match??:\n{}'.format(result))
execute(_add_match_to_gw)
def upload(local_path, remote_path, ip):
@hosts(ip)
def _inner_task():
run('mkdir -p {}'.format(remote_path))
put(local_path, remote_path)
execute(_inner_task)
def load_file(game_servers, local_file, remote_file, load_type='upload'):
test_server_info = get_test_server_info(GAME)
check_game_servers(game_servers, test_server_info)
locate_game_servers = transform_gameservers(game_servers, test_server_info)
ips = locate_game_servers.keys()
@hosts(ips)
def _upload_file():
upload(local_file, REMOTE_DIR, env.host_string)
for game_server in locate_game_servers[env.host_string]:
replace_file(game_server, remote_file)
@hosts(ips)
def _download_file():
for game_server in locate_game_servers[env.host_string]:
local_path = '{}/{}/'.format(local_root_path, game_server)
local('su - astd -c "mkdir -p {}"'.format(local_path))
target_file = '/app/{}/{}'.format(game_server, remote_file)
with quiet():
target_file_exists = run('test -f {}'.format(target_file)).succeeded
if target_file_exists:
get(target_file, local_path)
else:
raise Exception('File {} NOT exists on {}'.format(target_file, game_server))
local('chown -R astd.astd {}'.format(local_root_path))
if load_type == 'upload':
ftp_file_check(local_file)
file_name_consistence_check(local_file, remote_file)
execute(_upload_file)
print('{} was uploaded to {} successfully.'.format(local_file, game_servers))
elif load_type == 'download':
ftp_path = 'download/{}/{}'.format(GAME, TIMESTAMP)
local_root_path = '/app/online/{}'.format(ftp_path)
execute(_download_file)
print('Downloaded remote file: {} to FTP: {}/'.format(remote_file, ftp_path))
def export_db(game_servers, export_type='data'):
test_server_info = get_test_server_info(GAME)
check_game_servers(game_servers, test_server_info)
locate_game_servers = transform_gameservers(game_servers, test_server_info)
ips = locate_game_servers.keys()
ftp_path = 'download/{}/{}'.format(GAME, TIMESTAMP)
local_root_path = '/app/online/{}'.format(ftp_path)
@hosts(ips)
def _export_db():
for game_server in locate_game_servers[env.host_string]:
local_path = '{}/{}/'.format(local_root_path, game_server)
local('su - astd -c "mkdir -p {}"'.format(local_path))
run('mkdir -p {}'.format(REMOTE_DIR))
sql_name = '{}.sql.rb{}'.format(game_server, TIMESTAMP)
if export_type == 'no-data':
run('pandora --dump -R --opt -d {} >{}/{}'.format(game_server, REMOTE_DIR, sql_name))
elif export_type == 'data':
run('pandora --dump -R --opt {} >{}/{}'.format(game_server, REMOTE_DIR, sql_name))
with cd(REMOTE_DIR):
run('tar zcf {0}.tgz {0}'.format(sql_name))
target_file = '{}/{}.tgz'.format(REMOTE_DIR, sql_name)
get(target_file, local_path)
local('chown -R astd.astd {}'.format(local_root_path))
print('Start dumping db...')
sys.stdout.flush()
execute(_export_db)
print('Downloaded db to FTP: {}/'.format(ftp_path))
def __new__(cls, *args, **kwargs):
self = super(Tasks, cls).__new__(cls)
for attr in dir(cls):
attr_value = getattr(cls, attr)
if is_task_object(attr_value):
task_decorator = fab.task(
default=attr_value.is_default,
name=attr_value.name,
aliases=attr_value.aliases,
task_class=attr_value.__class__,
)
bounded_task = functools.partial(attr_value.wrapped, self)
task = task_decorator(functools.wraps(attr_value)(bounded_task))
for wrapped_attr in [
'parallel',
'serial',
'pool_size',
'hosts',
'roles',
]:
if hasattr(attr_value.wrapped, wrapped_attr):
setattr(
task.wrapped,
wrapped_attr,
getattr(attr_value.wrapped, wrapped_attr),
)
setattr(self, attr, task)
return self
def __init__(self, roles=(), hosts=(), create_default_roles=True):
if create_default_roles:
for role in roles:
fab.env.roledefs.setdefault(role, [])
for task in self:
if not hasattr(task, 'roles'):
task.roles = roles
if not hasattr(task, 'hosts'):
task.hosts = hosts
def send_client_confile(confile):
put(confile, 'tempfile')
run('mv tempfile ~/.bigchaindb')
print('For this node, bigchaindb show-config says:')
run('simplechaindb show-config')
# Initialize BigchainDB
# i.e. create the database, the tables,
# the indexes, and the genesis block.
# (The @hosts decorator is used to make this
# task run on only one node. See http://tinyurl.com/h9qqf3t )
def set_node(host,password):
env['passwords'][host]=password
env['hosts']=env['passwords'].keys()
###################
# Install Collectd
def transfer(self, files, dest_dir):
md5 = {}
def md5sum(file):
return run("md5sum %s | awk '{print $1}'" % file)
def wget_files(filenames, dest_dir):
mk_remote_dir(dest_dir)
with cd(dest_dir):
for each_filename in filenames:
#?????????????????ip?????????????????????md5??????????md5?????????????????????????wget -O?????!!)????????????????
file_exits = file_exists_check(each_filename)
if file_exits:
if md5[each_filename] == md5sum(each_filename):
break
run('''{0} -O {1} --header="Host:{2}" http://{3}/{1}'''.format(WGET, each_filename, self.server_name, self.source_ext_ip))
@hosts(self.source_ip)
def _transfer(files, dest_dir):
filenames = retrieve_file_names(files)
root_dir = '/app/opbak/download_{}_{}'.format(TIMESTAMP, self.server_name)
with setting_trans_env(self.server_name):
for each_file in files:
filename = os.path.basename(each_file)
md5[filename] = md5sum(each_file)
with cd(root_dir):
run('ln -sf {} {}'.format(each_file, filename))
execute(wget_files, filenames, dest_dir, hosts=[self.target_ip])
@hosts(self.source_ip)
def _copy(files, dest_dir):
for each_file in files:
run('{} {} {}/'.format(RSYNC, each_file, dest_dir))
def _execute_transfer():
if self.source_ip == self.target_ip:
execute(_copy, files, dest_dir)
else:
execute(_transfer, files, dest_dir)
if self._debug:
_execute_transfer()
else:
with settings(hide('everything')):
_execute_transfer()
#End class Uploader
########################################################################
def upload_log(self, logtype=None, date=None, logfile=None, ftp_ip=None):
"""
An example: pandora --ftp -r 30 -t 1200 -z -m 42.62.119.164 /tjmob_log/tjmob_37wan_1 /app/tjmob_37wan_1/backend/logs/game/dayreport/dayreport_2015-05-03.log.bz2*
"""
from bible.utils import BZIP2
ftp_log_path = '/{}_log/{}'.format(self.game, self.name)
logtypes = ['dayreport', 'rtreport']
date = date if date else time.strftime('%Y-%m-%d')
ftp_ip = ftp_ip if ftp_ip else '42.62.119.164'
if logfile:
logfiles = [logfile]
else:
if logtype:
logfiles = ['/app/{0}/backend/logs/game/{1}/{1}_{2}.log'.format(self.name, logtype, date)]
else:
logfiles = ['/app/{0}/backend/logs/game/{1}/{1}_{2}.log'.format(self.name, each_logtype, date) for each_logtype in logtypes]
@hosts(self.int_ip)
def _upload_log():
for each_log in logfiles:
dir, filename = os.path.split(each_log)
with cd(dir):
file_bz2 = '{}.bz2'.format(filename)
file_md5 = '{}.MD5'.format(file_bz2)
run('[ -f {0} ] && echo "{0} already exists" || {1} {2}'.format(file_bz2, BZIP2, filename))
run('[ -f {0} ] && echo "{0} already exists" || md5sum {1} >{0}'.format(file_md5, file_bz2))
run('''pandora --ftp -r 30 -t 1200 -z -m {} {} {}.bz2*'''.format(ftp_ip, ftp_log_path, each_log) )
execute(_upload_log)
#class Resource(object):
# """
# ????????????????????????????????
# ?????????????????
#
# """
# def __init__(self,
#
# def upload(self, file):
# dir, filename = os.path.split(file)
# resource_dir = '/app/www/{}/{}/{}'.format(game, RELEASE_TYPE, TIMESTAMP)
# resource_ip = gameOption('www_ssh_ip')
# execute(mk_remote_dir, resource_dir, hosts=[resource_ip])
# local('rsync -aP {}/{{{},md5.txt}} {}:{}/'.format(dir, filename, resource_ip, resource_dir))
#
# def download(self, file):
# remote_dir, filename = os.path.split(file)
# mk_remote_dir(REMOTE_DIR)
# with cd(remote_dir):
# wget = 'wget -c -t 10 -T 10 -q'
# server_name = gameOption('www_header')
# for each_file in [filename, 'md5.txt']:
# run('''{} --header="Host:{}" http://{}/{}/{}/{}/{}'''.format(wget, server_name, gameOption('www_ip'), game, RELEASE_TYPE, TIMESTAMP, each_file))
# run('dos2unix md5.txt && md5sum -c md5.txt')