原始
之前編寫了一個(gè)工具撵彻,用于從windows里面根據(jù)svn修改狀態(tài)墙贱,篩選一系列的文件艺演;計(jì)算本地文件和遠(yuǎn)程linux文件的md5差異却紧,上傳有差異的文件到遠(yuǎn)程。
#!/usr/bin/python
# encoding: utf-8
# pip install svn
# pip install fabric
#
import logging
import os
import svn.local
from fabric import Connection
import hashlib
logging.basicConfig(level=logging.INFO,format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',datefmt='%a, %d %b %Y %H:%M:%S')
# 指定遠(yuǎn)程的服務(wù)器目錄地址
path_remoate = "/home/cq/work/server/"
# 計(jì)算本地文件md5碼
def GetFileMd5(filename):
if not os.path.isfile(filename):
return
myhash = hashlib.md5()
f = open(filename,'rb')
while True:
b = f.read(8096)
if not b :
break
myhash.update(b)
f.close()
return myhash.hexdigest()
def main():
# 鏈接遠(yuǎn)程服務(wù)器的配置
c = Connection(host="xxx.xxx.xxx.xxx",
user="username",
connect_kwargs={"key_filename": "E:/software/keyfile/id_rsa_abel",})
c.open()
logging.info(c.is_connected)
# 測試執(zhí)行執(zhí)行指令
c.run("pwd")
# 獲取本地svn文件狀態(tài)
l = svn.local.LocalClient('./')
entries = l.status()
for filename in entries:
# 選擇“修改”胎撤、“添加”狀態(tài)的文件
if filename.type_raw_name=='modified' or 'added' == filename.type_raw_name:
name = filename.name
name = name.replace("\\","/")
logging.info("put name: {0}".format(name))
# 通過Linux指令計(jì)算出遠(yuǎn)程的文件md5晓殊,并且賦值給retstr
cmd = "md5sum {0}{1}".format(path_remoate,name) + "|awk '{print $1}'"
retstr = c.run(cmd)
# 計(jì)算本地m5,并且匹配
selfmd5 = GetFileMd5(name)
print(selfmd5)
# 命令行返回的md5將會(huì)帶一個(gè)\n伤提,需要去除
if retstr.stdout[:-1] == selfmd5:
print("match")
else:
print("not match")
# 不匹配的情況下巫俺,將會(huì)開始使用fabric的put命令上傳文件
c.put(name,"{0}{1}".format(path_remoate,name))
c.close()
if __name__ == '__main__':
main()
改造
修改的版本主要是將其中的配置信息抽出來,寫成一個(gè)json配置文件肿男,接受輸入?yún)?shù)识藤。
配置文件內(nèi)容
{
"r_ip" : "xxxxxxxxxxxxx",
"r_usr" : "root",
"r_path": "/root/upload",
"keyfile" : "C:/Users/abel/Documents/keyfile/id_rsa",
"l_path" : "C:/main/code/"
}
上傳腳本
#!/usr/bin/python
# encoding: utf-8
#
# 先安裝這些插件
# pip install fabric==2.5.0
# pip install pypiwin32
#
import logging
import os
from fabric import Connection
import hashlib
import json
import sys
import glob
logging.basicConfig(level=logging.INFO,format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',datefmt='%a, %d %b %Y %H:%M:%S')
class r_sync(object):
def __init__(self,_cfg_file):
super().__init__()
self.cfg_file_ = _cfg_file
self.load_cfg()
def work(self):
self.open_conn()
self.check_sync()
self.close_conn()
pass
def load_cfg(self):
self.j_obj_ = None
with open(self.cfg_file_, 'r') as jsonFile:
self.j_obj_ = json.load(jsonFile)
self.r_ip_ = self.j_obj_["r_ip"]
self.r_usr_ = self.j_obj_["r_usr"]
self.r_path_ = self.j_obj_["r_path"]
self.keyfile_ = self.j_obj_["keyfile"]
self.l_path_ = self.j_obj_["l_path"]
def open_conn(self):
# 鏈接遠(yuǎn)程服務(wù)器的配置
self.conn_ = Connection(host=self.r_ip_,
user=self.r_usr_,
connect_kwargs={"key_filename": self.keyfile_,})
self.conn_.open()
logging.info(self.conn_.is_connected)
def check_sync(self):
old_cwd = os.getcwd()
os.chdir(self.l_path_)
self.recursion_path("./")
os.chdir(old_cwd)
def recursion_path(self,_path):
logging.info("dir: {0}".format(_path))
for root,dirs,files in os.walk(_path):
for dn in dirs:
sub_d = self.win2linux(str(_path) +"/"+ str(dn))
if os.path.exists(sub_d) and os.listdir(sub_d):
self.recursion_path(sub_d)
for fn in files:
fn = self.win2linux(str(_path) +"/"+ str(fn))
if os.path.exists(fn):
self.check_single_file(fn)
def check_single_file(self,_filename):
lmd5 = self.get_l_md5(_filename)
rmd5 = self.get_r_md5(_filename)
logging.info("local file: {0}, \nlmd5: {1}".format(_filename,lmd5))
logging.info("rmd5: {0}".format(rmd5))
if lmd5 != rmd5:
self.put_file(_filename)
def close_conn(self):
self.conn_.close()
def win2linux(self, _path):
_path = _path.replace("\\","/")
_path = _path.replace("/./","/")
_path = _path.replace("http://","/")
return _path
def get_r_md5(self,_name):
r_p = self.win2linux("{0}/{1}".format(self.r_path_,_name))
cmd="mkdir -p {0}".format(os.path.dirname(r_p))
self.conn_.run(cmd)
cmd = "md5sum {0}".format(r_p) + "| awk '{print $1}'"
retstr = self.conn_.run(cmd)
return retstr.stdout[:-1]
def get_l_md5(self, _name):
if not os.path.isfile(_name):
return None
myhash = hashlib.md5()
f = open(_name,'rb')
while True:
b = f.read(8096)
if not b :
break
myhash.update(b)
f.close()
return myhash.hexdigest()
def put_file(self, _name):
self.conn_.put(_name,self.win2linux("{0}/{1}".format(self.r_path_,_name)))
def main():
if len(sys.argv) == 1:
r = r_sync("./config.json")
r.work()
pass
else:
for cfg_name in sys.argv[1:]:
r = r_sync(cfg_name)
r.work()
if __name__ == '__main__':
main()