Deploy.py:
#!/usr/bin/python
#-*- coding:utf-8 -*-
import os
import sys
import commands
import config
import subprocess
import time
import getpass
DEBUG = False
def debug_print(msg):
if DEBUG:
print msg
############################ 通用函数部分 ############################
# 输入的密码里有一些特殊字符的时候,会乱码
def trans_string(strinput):
strret = strinput.replace('\\','\\\\')
strret = strret.replace('!','\!')
return strret
# 调用本地shell命令
def DoShellCmd(cmd, show_result = True):
debug_print("DoShellCmd cmd: " + cmd)
(exitcode, outtext) = commands.getstatusoutput(cmd)
if exitcode != 0:
print outtext
#exit(exitcode)
elif show_result:
print outtext
return outtext
# 利用sshpass调用远程shell命令
def DoRemoteCmd(ip, passwd, user, rcmd):
cmd = "sshpass -p "+passwd+" ssh -p22 -o StrictHostKeyChecking=no "
cmd += "-l"+user+" "+ip+" \""+rcmd+"\" < /dev/null"
debug_print("DoRemoteCmd cmd: " + cmd)
return DoShellCmd(cmd)
# 利用sshpass工具拷贝文件到远程路径
def ScpFileToRemote(ip, passwd, user, src_file, dest_dir, compress = False):
scp_cmd = "sshpass -p " + passwd
if compress:
scp_cmd += " scp -P22 -C -o StrictHostKeyChecking=no "
else:
scp_cmd += " scp -P22 -o StrictHostKeyChecking=no "
scp_cmd += src_file + " " + user + "@" + ip + ":" + dest_dir + " < /dev/null"
debug_print("ScpFileToRemote cmd: " + scp_cmd)
DoShellCmd(scp_cmd, False)
# 判定本地和远程两文件是否一样
def RemoteLocalFileMd5Equal(svr_ip, svr_passwd, svr_user, remote_fullname, local_fullname):
remote_md5sum = DoRemoteCmd(svr_ip, svr_passwd, svr_user, "md5sum -b " + remote_fullname)
remote_md5sum = remote_md5sum.split()[0]
local_md5sum = DoShellCmd("md5sum -b " + local_fullname)
local_md5sum = local_md5sum.split()[0]
if local_md5sum == remote_md5sum:
return True
return False
def DoCopyFiles(cfg):
for (fname,tname) in cfg.copy_direct.items():
#print "k:[" + k + "]v:[" + v
if fname[0] == '/':
from_name = fname
else:
from_name = os.path.join(cfg.from_prefix, fname)
if tname[0] == '/':
to_name = tname
else:
to_name = os.path.join(cfg.to_prefix, tname)
# 如果md5相等,则不用拷贝
md5equal = RemoteLocalFileMd5Equal(cfg.server_ip, cfg.server_pass, cfg.server_user, to_name, from_name)
if md5equal:
continue
DoRemoteCmd(cfg.server_ip, cfg.server_pass, cfg.server_user, "mkdir -p " + os.path.dirname(to_name))
ScpFileToRemote(cfg.server_ip, cfg.server_pass, cfg.server_user, from_name, os.path.dirname(to_name))
for (fname,tname) in cfg.copy_compress.items():
#print "k:[" + k + "]v:[" + v
if fname[0] == '/':
from_name = fname
else:
from_name = os.path.join(cfg.from_prefix, fname)
if tname[0] == '/':
to_name = tname
else:
to_name = os.path.join(cfg.to_prefix, tname)
# 如果md5相等,则不用拷贝
md5equal = RemoteLocalFileMd5Equal(cfg.server_ip, cfg.server_pass, cfg.server_user, to_name, from_name)
if md5equal:
continue
DoRemoteCmd(cfg.server_ip, cfg.server_pass, cfg.server_user, "mkdir -p " + os.path.dirname(to_name))
ScpFileToRemote(cfg.server_ip, cfg.server_pass, cfg.server_user, from_name, os.path.dirname(to_name), True)
def Deploy():
#'检查参数'
if len(sys.argv) < 3:
print "Usage: python deploy.py configfilename [DEBUG]"
print "Options: "
print "[configfilename] : config.conf"
print "[DEBUG] : debug|DEBUG|Debug"
sys.exit(1)
configfilename = sys.argv[1]
if len(sys.argv) >= 3:
input_debug = sys.argv[2]
if input_debug.lower() == "debug":
global DEBUG
DEBUG = True
cfg = config.Config(configfilename)
# 如果密码没有设置,输入密码
if cfg.server_pass == "notset":
cfg.server_pass = trans_string(getpass.getpass("input password:"))
#不要做逻辑,只负责拷贝文件
DoCopyFiles(cfg)
DoRemoteCmd(cfg.server_ip, cfg.server_pass, cfg.server_user, "cd " + cfg.to_prefix + " && sh c.sh ")
############################################
Deploy()
config.py:
#!/usr/bin/python
#-*- coding:utf-8 -*-
class Config:
def __init__(self, cfg_filename):
self.__read_config(cfg_filename)
def __read_config(self, file_name):
self.copy_direct = {}
self.copy_compress = {}
print file_name
f = open(file_name, 'r')
lines = f.readlines()
for line in lines:
# 注释 注意不要在行尾注释
if line.find('#') != -1:
continue
line = line.replace(' ','')
line = line.replace("\t","")
line = line.replace("\n","")
# => 直接拷贝
if line.find("=>") > 0:
line_split = line.split("=>")
if len(line_split) == 2:
self.copy_direct[line_split[0]] = line_split[1]
continue
# =*> 压缩拷贝
if line.find("=*>") > 0:
line_split = line.split("=*>")
if len(line_split) == 2:
self.copy_compress[line_split[0]] = line_split[1]
continue
if line.find("=") > 0:
line_split = line.split("=")
if len(line_split) == 2:
if line_split[0] == "server_ip":
self.server_ip = line_split[1]
if line_split[0] == "server_user":
self.server_user = line_split[1]
if line_split[0] == "server_pass":
self.server_pass = line_split[1]
if line_split[0] == "from_prefix":
self.from_prefix = line_split[1]
if line_split[0] == "to_prefix":
self.to_prefix = line_split[1]
if line_split[0] == "remote_deploy_tmp_folder":
self.remote_deploy_tmp_folder = line_split[1]
f.close()
配置:
server_ip = 192.168.123.234
server_user = your_user_name
server_pass = notset
from_prefix = ../
to_prefix = ~/server/
# =*>表示压缩传输
# =>表示直接传输
# 以/开头的表示绝对路径
/home/AsynServ_Dev =*> /home/AsynServ_Dev
/home/ServerBench =*> /home/ServerBench
c.sh => c.sh
projectname.txt => projectname.txt
r.sh => r.sh
s.sh => s.sh
x.sh => x.sh
configs/data/AllConfigs.bytes => configs/data/AllConfigs.bytes
#ls
loginsvr/libloginsvr.so =*> loginsvr/libloginsvr.so
loginsvr/r.sh => loginsvr/r.sh
loginsvr/s.sh => loginsvr/s.sh
loginsvr/x.sh => loginsvr/x.sh
loginsvr/bench.conf.template => loginsvr/bench.conf.template
loginsvr/bind.conf.template => loginsvr/bind.conf.template
loginsvr/log/keepme.txt => loginsvr/log/keepme.txt
#gs
gamesvr/libgamesvr.so =*> gamesvr/libgamesvr.so
gamesvr/r.sh => gamesvr/r.sh
gamesvr/s.sh => gamesvr/s.sh
gamesvr/x.sh => gamesvr/x.sh
gamesvr/bench.conf.template => gamesvr/bench.conf.template
gamesvr/bind.conf.template => gamesvr/bind.conf.template
gamesvr/log/keepme.txt => gamesvr/log/keepme.txt
#ct
center/libcenter.so =*> center/libcenter.so
center/r.sh => center/r.sh
center/s.sh => center/s.sh
center/x.sh => center/x.sh
center/bench.conf.template => center/bench.conf.template
center/bind.conf.template => center/bind.conf.template
center/log/keepme.txt => center/log/keepme.txt