fabric同步文件

原始

之前編寫了一個(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()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末砚著,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子痴昧,更是在濱河造成了極大的恐慌稽穆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赶撰,死亡現(xiàn)場離奇詭異舌镶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)豪娜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門餐胀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瘤载,你說我怎么就攤上這事否灾。” “怎么了鸣奔?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵墨技,是天一觀的道長。 經(jīng)常有香客問我挎狸,道長扣汪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任锨匆,我火速辦了婚禮崭别,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恐锣。我一直安慰自己茅主,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布土榴。 她就那樣靜靜地躺著诀姚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鞭衩。 梳的紋絲不亂的頭發(fā)上学搜,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天娃善,我揣著相機(jī)與錄音论衍,去河邊找鬼。 笑死聚磺,一個(gè)胖子當(dāng)著我的面吹牛坯台,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瘫寝,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼蜒蕾,長吁一口氣:“原來是場噩夢啊……” “哼稠炬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咪啡,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤首启,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后撤摸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毅桃,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年准夷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钥飞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡衫嵌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情童叠,我是刑警寧澤辩诞,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站墓律,受9級(jí)特大地震影響膀估,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耻讽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一察纯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧针肥,春花似錦饼记、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至具帮,卻和暖如春博肋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜂厅。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工匪凡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掘猿。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓病游,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稠通。 傳聞我的和親對(duì)象是個(gè)殘疾皇子衬衬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349