1. 程式人生 > >python 檔案自動配置&部署指令碼

python 檔案自動配置&部署指令碼

背景:

一個專案有時候要上傳到測試機,有時候要上傳到正式機。

有一次因為配置錯了環境,白忙活了一整天,決定這種事還是交給指令碼來實現吧。

思路:

1、先用正則表示式把環境變數給抓出來,然後修改成要上傳伺服器的環境變數後寫回檔案。

2、拋棄一些子目錄如log,venv等(雖然不要裡面的內容,但要把它們本身這個空目錄加入tar),開始tar打包。

3、計算打包後文件的md5。

4、用SFTP協議傳到伺服器,具體用python的第三方lib:paramiko,博主自己寫了個類封裝。

5、計算傳輸後文件的md5,比對兩者md5,如果相同則說明資料完整,可以繼續,否則exit。

6、用paramiko中的exec_command()可以操控伺服器執行我們的cmd。

7、之後做些收尾工作,比如複製好virtualenv、重啟supervisor呀之類的。

# coding=utf-8
import os
import shutil
import time
import re
import tarfile
import hashlib

import paramiko

src_root = 'g:\\projects\\myApp\\'
des_root = 'g:\\projects\\myapp_helper\\'
linux_root = '/home/www/myapp_uploads/'

today = time.strftime('%Y-%m-%d-%H-%M', time.localtime(time.time()))
des_target = os.path.join(des_root, 'test_myapp%s\\' % today)
print u'目標根目錄:', des_target


class MySSH(object):
    def __init__(self, host, username, password):
        self.host = host
        self.username = username
        self.password = password
        self.ssh_fd = None
        self.sftp_fd = None

        self.ssh_connect()
        self.sftp_open()

    def ssh_connect(self):
        try:
            print u'連線SSH...'
            self.ssh_fd = paramiko.SSHClient()
            self.ssh_fd.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.ssh_fd.connect(self.host, 22, username=self.username, password=self.password)

            stdin, stdout, stderr = self.ssh_fd.exec_command("mkdir %s" % linux_root)
            print stdout.readlines()
            print u'連線SSH 成功...'
        except Exception, ex:
            print 'ssh %
[email protected]
%s: %s' % (self.username, self.host, ex) exit() def sftp_open(self): print u'開啟SFTP 成功...' self.sftp_fd = self.ssh_fd.open_sftp() def sftp_put(self, from_path, to_path): ''' 上傳檔案到遠端伺服器 ''' return self.sftp_fd.put(from_path, to_path) def sftp_get(self, from_path, to_path): ''' 從遠端伺服器下載檔案 ''' return self.sftp_fd.get(from_path, to_path) def exe(self, cmd): ''' 讓遠端伺服器執行cmd ''' stdin, stdout, stderr = self.ssh_fd.exec_command(cmd) print u'執行%s:' % cmd print stderr.readlines() if cmd.find('md5') == 0: return stdout.readline() def close(self): self.sftp_fd.close() self.ssh_fd.close() print u'關閉SSH連線...成功' def __del__(self): self.close() def copy_project(): ''' 1、先把src專案拷貝到des下 2、除去某些子目錄:discard_dirs = ['myproto', 'log', 'myapp_env', 'test', 'tmp', 'upload', '.idea', '.git'] 3、除去某些不需要的檔案: .gitignore, README.md 4、遇到配置檔案,把環境變數改成測試環境...api_status = 2 ''' if not os.path.exists(des_target): print u'建立根目錄:', des_target os.makedirs(des_target) discard_dirs = ['myproto', 'log', 'myapp_env', 'test', 'tmp', 'upload', '.idea', '.git', 'uploads'] for root, dirs, files in os.walk(src_root, topdown=False): t_root = root.replace(src_root, des_target) for dir in dirs: t_dir = os.path.join(t_root, dir) # print t_dir if len(list(set(t_dir.split('\\')).intersection(set(discard_dirs)))) > 0: continue if not os.path.exists(t_dir): print u'目錄安全,建立...',t_dir os.makedirs(t_dir) if not os.listdir(t_dir): print u'目錄為空,刪除...',t_dir os.removedirs(t_dir) for file in files: if file.endswith('.pyc'): continue if file in ['.gitignore', 'README.md']: continue src_file = os.path.join(root, file) des_file = os.path.join(t_root, file) if len(list(set(src_file.split('\\')).intersection(set(discard_dirs)))) > 0: continue des_folder = des_file[0: -len(des_file.split('\\')[-1])] if not os.path.exists(des_folder): print u'目錄安全,建立...',des_folder os.makedirs(des_folder) # print src_file, ' > ', des_file if file != 'settings.py': shutil.copy(src_file, des_file) else: out = open(des_file, 'w') datas = open(src_file, 'r') pattern = re.compile(r'api_status\s*=\s*\d') for line in datas.readlines(): if pattern.match(line): line = 'api_status = 2\n' out.write(line) datas.close() out.close() # 補全 print des_target+'log' os.mkdir(des_target+'log') os.mkdir(des_target+'uploads') def tar_project(dir_path): ''' 1、用tarfile來打包,按照這種方法打包是會忽略空目錄的。 2、在tar中加入空目錄。 dir_path = g:\projects\chanzai_helper\test_chanzai2016-11-22-11-09 return filename, filepath ''' # 建立壓縮包名 tar_name = "%s.tar.gz" % dir_path.split('\\')[-2] tar_fullpath = des_root+tar_name print u'壓縮包名字:', tar_fullpath tar = tarfile.open(tar_fullpath, "w:gz") # 建立壓縮包 for root, dirs, files in os.walk(dir_path): for file in files: fullpath = os.path.join(root, file) # print u'壓縮:', fullpath filename = fullpath.replace(des_target, '') tar.add(fullpath, arcname=filename) tar.add(des_target+'log', arcname="log/") tar.add(des_target+'uploads', arcname="uploads/") tar.close() return tar_name, tar_fullpath def CalcMD5(filepath): ''' 獲取檔案md5, 用來檢驗檔案傳輸完整性 ''' with open(filepath, 'rb') as f: md5obj = hashlib.md5() md5obj.update(f.read()) hash = md5obj.hexdigest() return hash copy_project() filename, filepath = tar_project(des_target) from_md5 = CalcMD5(filepath) print u'壓縮檔案md5 = %s' % from_md5 # 刪除本地的資料夾 shutil.rmtree(des_target) ssh = MySSH('xxx.xx.xx.xxx', 'your_name', 'your_pass') print u'傳輸:', filename ssh.sftp_put(filepath, linux_root + filename) # 獲取linux那邊檔案的md5 cmd = "md5sum %s%s|cut -d ' ' -f1" % (linux_root, filename) to_md5 = ssh.exe(cmd) print u'傳輸過去的檔案md5 = %s' % to_md5 to_md5 = to_md5.strip('\n') if from_md5 != to_md5: print len(from_md5), len(to_md5) print u'ERROR: 檔案傳輸不完整...' exit() else: print u'OK: 檔案傳輸完整!' # 解壓縮 tar 包 folder = filename.split('.')[0] cmd = 'mkdir %s%s;cd %s%s;tar -zxvf %s%s' % (linux_root, folder, linux_root, folder, linux_root, filename) ssh.exe(cmd) # 刪除linux - tar包 cmd = 'cd %s; rm -rf %s%s' % (linux_root, linux_root, filename) err = ssh.exe(cmd) if err: print err exit() # 刪除/home/www/myAppbak cmd = 'cd /home/www; rm -rf /home/www/myAppbak' err = ssh.exe(cmd) if err: print err exit() # 交換當前工作目錄 cmd = 'mv /home/www/myApp /home/www/myAppbak' err = ssh.exe(cmd) if err: print err exit() cmd = 'mv %s%s /home/www/myApp' % (linux_root, folder) err = ssh.exe(cmd) if err: print err exit() # 把 虛擬環境複製過去 cmd = 'cp -r /home/www/myAppbak/myapp_env /home/www/myApp/myapp_env' err = ssh.exe(cmd) if err: print err exit() # 在supervisor中重啟 cmd = 'supervisorctl restart myapp' err = ssh.exe(cmd) if err: print err exit()


相關推薦

python 檔案自動配置&部署指令碼

背景: 一個專案有時候要上傳到測試機,有時候要上傳到正式機。 有一次因為配置錯了環境,白忙活了一整天,決定這種事還是交給指令碼來實現吧。 思路: 1、先用正則表示式把環境變數給抓出來,然後修改成要上傳伺服器的環境變數後寫回檔案。 2、拋棄一些子目錄如log,venv等(雖

Shell程式檔案上傳以及自動備份部署指令碼

DMZ機器程式檔案上傳到伺服器指定目錄指令碼 #!/bin/bash #author Pine Chown #任務分發指令碼 #2017-08-25 instance1=gcharging1-inside deploy_file=gcharging.zip TIME=`date +%F

利用Python實現自動掃雷小指令碼

自動掃雷一般分為兩種,一種是讀取記憶體資料,而另一種是通過分析圖片獲得資料,並通過模擬滑鼠操作,這裡我用的是第二種方式。  一、準備工作 1.掃雷遊戲 我是win10,沒有預設的掃雷,所以去掃雷網下載 http://www.saolei.net/BBS/

Python實現自動掛機指令碼(基礎篇)

不知不覺肝陰陽師也快一年了,對這遊戲真是又愛又恨,最近剛剛釋出了PC版,突然很想嘗試著寫個指令碼掛機,話不多說進入正題。 簡單的滑鼠操作 遊戲掛機指令碼,無非就是自動移動滑鼠,自動點選,進行重複操作,所以,第一步就是如何控制滑鼠 import wi

[Vim]新建python檔案自動新增python header

使用vim指令碼來實現的,使用了模板,幾行程式碼就能實現很實用。 ~/.vimrc 中的程式碼 "auto add pyhton header --start autocmd BufNewFil

Linux學習之自動配置部署——初用expect

pro 出現 expec 用戶 部署 inux 臨時文件 spa 內容 主機A連接主機B       免密登陸 + 自動部署expect實現自動的交互式任務     ——— send         向進程發送字符串(輸入)

nginx+tomcat負載均衡配置+python自動化部署指令碼

nginx+tomcat負載均衡配置 1、網路拓撲      2、nginx安裝配置 1.安裝nginx伺服器,實現OSI網路模型第七層(應用層)負載均衡及反向代理:       安裝nginx 1.6.1 stable version,  stable version版

SpringBoot熱部署devtool和配置檔案自動注入(SpringBoot2.0系列-二)

1、SpringBoot2.x使用Dev-tool熱部署 簡介:什麼是熱部署,使用springboot結合dev-tool工具,快速載入啟動應用 核心依賴包: <dependency> <groupId>o

python flask 解析配置檔案與寫日誌

test.conf   [kafka]kafka_sys_topic = test-sys-infokafka_sys_group = test-consumer-groupzookeeper_server = 192.168.1.1:2181,192.168.1.2:2181,192.168.1

微服務+Jenkins 簡單的linux自動部署指令碼

No.1  啟停指令碼 #!/bin/bash ## 載入配置,避免獲取不到java_home  source /etc/profile SERVICE_HOME=專案路徑 SERVICE_NAME=服務名稱 cd $SERVICE_HOME/$SERVICE_NAM

FastDFS分散式檔案系統配置部署

一文搞定FastDFS分散式檔案系統配置與部署 閱讀目錄 1 分散式檔案系統介紹 2 系統架構介紹 3 FastDFS效能方案 4 Linux基本命令操作 5 安裝VirtualBox虛擬機器並配置Ubuntu

SpringMVC配置部署xml檔案

                                  SpringMVC配置部署xml檔案 之前沒有用框架,初識

Python讀取、配置INI檔案

Python讀取、配置INI檔案 Python程式碼 讀取及配置ini檔案,儲存資料引數等資訊。 Python程式碼 import os,re import configparser class INI_object: def __i

如何在Linux系統中編寫指令碼檔案自動執行

        在叢集的部署和啟動過程中,往往要執行叫較多的命令,特別是已經部署成功在啟動的時候,總有一些初始化的工作要做。這個時候如果還是選擇一個一個去依次執行未免有些太浪費時間,因此選擇了指令碼的方式。並且指令碼的方式也便於向

過年過節真是一票難求!分享關於Python最新版12306自動搶票指令碼

為了方面和節約時間,本次使用的python編譯器和直譯器分別為pycharm,python3.6.1RC 逢年過節 有一個神奇的網站 你一定不陌生 “12306” 是不是總搶不到票啊 是不是觀察著餘票最新動態 告訴你一個新技能 賊666 12306自動搶票 前

python3+requests介面自動-配置檔案

1.cfg.ini開啟,這裡寫配置檔案內容 [email]smtp_server = smtp.qq.comport = 456sender = [email protected];psw是郵箱的授權碼psw = xxxreceiver = [email protected]2.用rea

解析配置檔案自動裝配 DataSource + AbstractRoutingDataSource + AOP 實現動態資料來源 上:原理解析,解析資料來源

spring boot 自動裝配會通過 spring.datasource.*為我們自動裝配資料來源,所以想要動態的切換資料來源,第一件事是配置資料來源,其次是怎麼切換?最後何時切換? 原理解析(使用 AbstractRoutingDataSource 實現) spring-jd

解析配置檔案自動裝配 DataSource + AbstractRoutingDataSource + AOP 實現動態資料來源 下:配置動態資料來源,AOP 進行使用

上篇文章中已經藉助 DynamicDataSourceBuilder 類從配置檔案中解析得到了預設資料來源和動態資料來源,接下來需要配置動態資料來源的“本體”,並藉助 AOP 動態的切換資料來源。 配置動態資料來源 AbstractRoutingDataSource 實現了 In

Spring Boot Cache + redis 設定有效時間和自動重新整理快取,時間支援在配置檔案配置

分享一下我老師大神的人工智慧教程吧。零基礎,通俗易懂!風趣幽默!http://www.captainbed.net/ 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

python操作ini配置檔案

一、資料準備 1.建一個config的資料夾 2.在config資料夾下,新建一個cfg.ini檔案 選中config資料夾,點選滑鼠右鍵,new----> file,在檔名稱輸入框中輸入cfg.ini,點選確定。 3.在cfg.ini中填入資料,如下圖 4.cf