閱讀文檔系統(tǒng)說(shuō)明文檔授帕,發(fā)現(xiàn)精讀效果太差,建立的系統(tǒng)的信息基點(diǎn)不足浮梢□耸快速閱讀,先看目錄秕硝,然后看每篇文章的頭和尾芥映,主要關(guān)注概念與定義,不關(guān)注實(shí)現(xiàn)與功能細(xì)節(jié)远豺。閱讀完奈偏,在大腦中生成兩張圖,一張是文檔結(jié)構(gòu)圖躯护,一張是系統(tǒng)架構(gòu)圖
實(shí)踐操作惊来。操作過(guò)程主要包括:
1、把原目錄A下的文件AAA棺滞,遠(yuǎn)程傳輸?shù)街鳈C(jī)S1和S2的目錄B下裁蚁,并備份目錄B下的原文件。
2继准、繼續(xù)傳輸枉证,連續(xù)傳輸6個(gè)文件,使用File Zilla工具移必。
總耗時(shí)2個(gè)小時(shí)室谚。主要工作是:
1、檢查原目錄下的文件是否存在
2、ssh到遠(yuǎn)端檢查遠(yuǎn)程目錄是否存在秒赤,遠(yuǎn)程目錄文件是否存在猪瞬,備份遠(yuǎn)程目錄文件。6次檢查入篮,每次兩臺(tái)主機(jī)陈瘦,總共檢查12次
3、使用ftp工具上傳文件崎弃,上傳時(shí)設(shè)定本機(jī)目錄,設(shè)定遠(yuǎn)端目錄含潘,點(diǎn)擊上傳饲做。完全手工操作,容易出錯(cuò)遏弱。
4盆均、文件上傳之后,ssh到遠(yuǎn)程檢查文件是否是最新漱逸。相當(dāng)于重復(fù)步驟2
5泪姨、ssh遠(yuǎn)程主機(jī),在各個(gè)目錄下分別執(zhí)行kill和start命令饰抒,kill前檢查進(jìn)程是否存在肮砾,start后檢查是否啟動(dòng)完成,又是12次操作袋坑。
自動(dòng)化分析:
功能操作分解:本機(jī)檢查文件存在以及最新仗处,遠(yuǎn)程檢查目錄是否存在,遠(yuǎn)程備份文件枣宫,上傳文件婆誓,確認(rèn)遠(yuǎn)端文件正確上傳,確認(rèn)進(jìn)程是否存在也颤,停止進(jìn)程洋幻,啟動(dòng)進(jìn)程
編碼功能:
由于python豐富的運(yùn)維庫(kù),采用python語(yǔ)言來(lái)實(shí)現(xiàn)翅娶。采用paramiko實(shí)現(xiàn)
文件格式:
caltest.war,d:\pkg\version,/app/bjmbill/user,username,password,192.168.1.1
代碼如下:
import paramiko
import os
import time
import logging
date = time.strftime("%Y%m%d")
file_name ="oper_log_%s.log"%date
print(file_name)
logging.basicConfig(filename=file_name,
level=logging.DEBUG,filemode='w' ,
datefmt='%Y-%m-%d %H:%M:%S',
format? ='%(asctime)s? %(filename)s : %(levelname)s? %(message)s',
)
logger = logging.getLogger(__name__)
# 從文件中讀取文件名,本地目錄,遠(yuǎn)程目錄,用戶名
# caltest.war , d:\pkg\version\ , /home/emer/toma/, emer
def get_file_info(file_name):
result = {}
with open(file_name) as f:
for (num, value) in enumerate(f):
#? ? ? ? ? ? value = value.strip()
? ? ? ? ? ? if not len(value):
continue
? ? ? ? ? ? result[num] = {'file_name': value.split(',')[0],'local_dir': value.split(',')[1],
'remote_dir': value.split(',')[2],'user_name': value.split(',')[3],
'password': value.split(',')[4],'ip': value.split(',')[5]
}
f.close()
? ? logger.info("打印文件內(nèi)容%s"%result)
? ? return result
# 遠(yuǎn)程操作類,在遠(yuǎn)程主機(jī)上的動(dòng)作
class RemoteOper(object):
# 根據(jù)協(xié)議選擇不同的連接方式,返回連接本身
# def 登錄遠(yuǎn)端(協(xié)議方法,用戶名,密碼,端口號(hào),密鑰串)
? ? def loginRomote(self, protocol_method, host_info):
ip,user_name,password,port,remote_file = host_info[0], host_info[1], host_info[2], host_info[3], host_info[
4]
if protocol_method =="SSH":
paramiko.util.log_to_file('sysLogin.txt')
? ? ? ? ? ? ssh = paramiko.SSHClient()
? ? ? ? ? ? ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
? ? ? ? ? ? ssh.connect(hostname="IP",username="user_name",password="password",key_filename="key_filename")
? ? ? ? ? ? return ssh
if protocol_method =="FTP":
t = paramiko.Transport("IP")
? ? ? ? ? ? t.connect(user_name="",password="")
? ? ? ? ? ? sftp = paramiko.SFTPClient.from_transport(t)
? ? ? ? ? ? return sftp
# def 執(zhí)行命令,exec_command(command),由于本機(jī)與遠(yuǎn)程執(zhí)行方法一樣,不單獨(dú)列出
# def 檢查文件是否存在(文件名),返回最新日期和屬性
? ? def checkFile(self, loginRomote, file_name):
file_info = loginRomote.exec_command("ls -l %s"%file_name)
? ? ? ? logger.info(file_info)
? ? # def 備份文件,返回備份后的文件屬性
? ? def backFile(self, host_info, file_name):
ip, user_name, password, port, remote_file = host_info[0], host_info[1], host_info[2], host_info[3], host_info[
4]
logger.info('待備份文件%s'%file_name)
? ? ? ? try:
ssh = paramiko.SSHClient()
? ? ? ? ? ? ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
? ? ? ? ? ? ssh.connect(hostname=ip,username=user_name,password=password)
? ? ? ? ? ? time_bak = time.strftime("%m%d")
? ? ? ? ? ? command1 ="cp -p -r %s %s" %(file_name, file_name +'_' + time_bak)
? ? ? ? ? ? logger.info("準(zhǔn)備開始執(zhí)行命令%s" % command1)
? ? ? ? ? ? stdin, stdout, stderr = ssh.exec_command(command1)
? ? ? ? ? ? logger.info(stdout.read())
? ? ? ? ? ? command2 ="ls -l %s" %(file_name +'*')
? ? ? ? ? ? logger.info("準(zhǔn)備開始執(zhí)行命令%s" % command2)
? ? ? ? ? ? stdin, stdout, stderr = ssh.exec_command(command2)
? ? ? ? ? ? logger.info(stdout.read())
? ? ? ? ? ? ssh.close()
? ? ? ? ? ? return 0
? ? ? ? except Exception as e:
ssh.close()
? ? ? ? ? ? logger.info("文件備份失敗失敗username=%s,password=%s,ip=%s,port=%s,file_name=%s,remote_dir=%s",
user_name, password, ip, port, file_name, remote_dir)
? ? ? ? ? ? return -1
? ? # def 檢查進(jìn)程存在(進(jìn)程名文留,數(shù)量)
? ? def checkProcess(self, loginRemote, process_name, num):
pro_num = loginRemote.exec_command("ps -ef|grep %s |wc -l"%process_name)
? ? ? ? if pro_num == num:
logger.info("進(jìn)程%s數(shù)量正常,為%s"%(process_name, pro_num))
? ? ? ? else:
logger.info("進(jìn)程%s數(shù)量異常,應(yīng)為%s,為%s"%(process_name, num, pro_num))
# 本地操作類,主要是檢查本地文件,與上傳
class LocalOper(object):
def listAllFile(self, dir_name):
def processDir(self, dir_name, file_names):
logger.info('Director', dir_name)
? ? ? ? ? ? for file_namein file_names:
logger.info("FIle", file_name)
? ? ? ? os.walk(dir_name, processDir,None)
? ? # def 檢查本地文件(文件名)
? ? def isFile(self, file_name):
if os.path.isfile(file_name):
logger.info("%s文件存在"%file_name)
? ? ? ? else:
logger.info("%s文件不存在"%file_name)
? ? ? ? # def 文件上傳
? ? def upFile(self, host_info, file_name):
ip,user_name,password,port,remote_file = host_info[0],host_info[1],host_info[2],host_info[3],host_info[4]
try:
t = paramiko.Transport(ip,port)
? ? ? ? ? ? t.connect(username=user_name,password=password)
? ? ? ? ? ? sftp = paramiko.SFTPClient.from_transport(t)
? ? ? ? ? ? sftp.put(file_name,remote_file)
? ? ? ? ? ? logger.info("文件上傳成功username=%s,password=%s,ip=%s,port=%s,file_name=%s,remote_dir=%s",
user_name, password, ip, port, file_name, remote_dir)
? ? ? ? ? ? logger.info(sftp.stat(remote_file))
? ? ? ? ? ? t.close()
? ? ? ? ? ? return 0
? ? ? ? except Exception as e:
t.close()
? ? ? ? ? ? logger.info("文件上傳失敗username=%s,password=%s,ip=%s,port=%s,file_name=%s,remote_dir=%s",
user_name, password, ip, port, file_name, remote_dir)
? ? ? ? ? ? return -1
? ? # 返回最新日期和屬性
if __name__ =='__main__':
#生成日志文件
? ? date = time.strftime("%Y%M%D")
? ? log_file_name ="oper_log_%s.log"%date
logging.basicConfig(filename=log_file_name,level=logging.DEBUG)
? ? fileInfo = get_file_info("testdeploy.txt")
? ? #文件格式內(nèi)容:caltest.war , d:\pkg\version\ , /home/emer/toma/, emer,192.168.1.1
# file_name local_dir remote_dir user_name? ip
#單文件調(diào)試
#文件上傳
? ? localOper = LocalOper();
key =0
? ? local_file_name = os.path.join(fileInfo[key]['local_dir'], fileInfo[key]['file_name']).strip(' ')
? ? file_name = fileInfo[key]['file_name']
local_dir = fileInfo[key]['local_dir']
remote_dir = fileInfo[key]['remote_dir']
user_name = fileInfo[key]['user_name']
password = fileInfo[key]['password']
ip = fileInfo[key]['ip'].strip()
? ? remote_file_name = remote_dir +'/' + file_name
logger.debug("列出當(dāng)前目錄下本地文件%s" %(fileInfo[key]['local_dir']))
? ? localOper.listAllFile(local_dir)
? ? logger.debug("檢查本地文件%s" % local_file_name)
? ? localOper.isFile(local_file_name)
? ? #ip, user_name, password, port, remote_dir,用戶名和密碼信息從文件中讀取
? ? host_info =[ip,user_name,password,22,remote_file_name]
#備份文件
? ? remoteOper = RemoteOper()
? ? if remoteOper.backFile(host_info,remote_file_name) !=0:
logger.error("文件備份失敗")
? ? #上傳文件
? ? if localOper.upFile(host_info, local_file_name) !=0:
logger.error("文件上傳失敗")
? ? # 讀取文件竭沫,文件名厂庇,本地目錄,上傳目錄输吏,上傳用戶名(考慮自動(dòng)獲取叭酢)
# for 循環(huán)
#? 檢查本地文件
#? 登錄遠(yuǎn)端
#? 檢查遠(yuǎn)端文件
#? 備份文件
#? 上傳文件
#? 比對(duì)文件
#
# 讀取文件,獲取進(jìn)程名
# 檢查進(jìn)程,停進(jìn)程拄氯,啟動(dòng)進(jìn)程躲查,檢查進(jìn)程