python的工作记录B
这次很强了。就差最后一步,判断一下SVN的版本是否是真的库里的。
#!/usr/bin/env python # -*- coding: utf-8 -*- import os,sys,commands,subprocess import re,time from optparse import OptionParser #SVN的仓库地址,其实都是同一个,但为了安全和区别,写入具体地址 svnUrl = "svn://XX" prefix = "/XX/" #定义远程更新文件的根目录,与测试和真实环境有关的判断,用字典简单实现 sitePathDic = {"X":"/XX", "X":"/XX"} #定义将SVN放入本地SALTSTACK的目录 updateFolder = "/srv/salt/XX/" #定义SALT-MINION客户端地址 saltMinionDic = {"rX":"X", "tX":"X"} #定义推送文件的saltstack-master的文件地址 saltMasterUrl = "salt://X/" #维护两个文件列表,一个本地,一个远程 localFileList = [] remoteFileList = [] def getSvnFile(rVersion): #清空上次更新的所有文件 delCmd = "rm -rf " + updateFolder + "*" os.system(delCmd) print '\033[0;32;40m' print "Delete old saltstack files..." #因为每次只更新固定版本的文件,所以,要先得到文件列表,再一个一个导出为和网站一样的标准目录结构 svnLogCmd ="svn log -v -r" + rVersion +" " + svnUrl + " --username " svnLogOut = subprocess.Popen(svnLogCmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) for line in svnLogOut.stdout.readlines(): #将输出命令的非标准行去掉 if len(line.strip())!=0 and line.startswith(" "): #将标准行中的A,C,M等字符去掉 svnFileName = line.split()[1] #替换为相对于网站的根目录 fileList = svnFileName.replace(prefix,'') #取出相对于根目录的文件夹,判断是否存在和建立 folderList = '/'.join(fileList.split('/')[:-1]) if not os.path.exists(updateFolder + folderList): mkdirCmd = "mkdir " + updateFolder + folderList + " -p" os.system(mkdirCmd) #print "Make a new dir: " + updateFolder + folderList #判断取出的最后的字段是目录还是文件,如果是文件夹,需要新建,这就需要规定文件夹不能包含.,而文件名必须包含.,否则无法进行这一步判定 #这个判断我很纠结,如果更新不涉及SVN新建目录,就省事多了。 if '.' not in fileList.split('/')[-1]: mkdirCmd = "mkdir " + updateFolder + fileList + " -p" os.system(mkdirCmd) #print "Make a new dir: " + updateFolder + fileList #将文件放入列表,方便在更新到正式网站之后,循环修改相关权限()。 localFileList.append(fileList) remoteFileList.append(sitePathDic[svnType] + '/' + fileList) svnExportCmd = "svn export " + svnUrl + '/' + fileList + " " + updateFolder + fileList subprocess.Popen(svnExportCmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) print "Finished export Svn File into salt-master " def backupFile(bFileName, str_now): #加强安装性,备份后缀加PHP suffix = str_now + ".old.php" saltCpCmdPre = "salt '" + saltMinionDic[svnType] + "' cmd.run " + "' cp -p " cpCmd = saltCpCmdPre + bFileName + " " + bFileName + suffix +"'" subprocess.Popen(cpCmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) def updateFile(localFile, remoteFile): #更新文件 saltGetFilePre = "salt '" + saltMinionDic[svnType] + "' cp.get_file " + saltMasterUrl saltCpCmd = saltGetFilePre + localFile + " " + remoteFile + " makedirs=True" subprocess.Popen(saltCpCmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) #由于新建文件夹,SALTSTACK的权限所有者的更新在第一次不起作用,故而在CP好文件之后,单独进行权限更新 def chOwnMod(remoteFile): saltChownCmdPre = "salt '" + saltMinionDic[svnType] + "' cmd.run " + "'chown X" saltChownCmd = saltChownCmdPre + remoteFile + "'" subprocess.Popen(saltChownCmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) saltChmodCmdPre = "salt '" + saltMinionDic[svnType] + "' cmd.run " + "'chmod X " saltChmodCmd = saltChmodCmdPre + remoteFile + "'" subprocess.Popen(saltChmodCmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) def main(): getSvnFile(svnRev) #统一更新备份的时间 now = time.localtime() str_now = time.strftime("%Y-%m-%d-%H-%M-%S", now) for file in remoteFileList: backupFile(file, str_now) print "Finished back file-" + str_now print '\033[0m' for local,remote in zip(localFileList,remoteFileList): updateFile(local,remote) print "update file : " + remote #由于新建文件夹的权限更新执行太快,会不成功,故而停五秒之后再确认权限 print "Wait 5 seconds to start update permission" time.sleep(5) for remoteFile in remoteFileList: chOwnMod(remoteFile) print '\033[0;32;40m' print "Finished. update success!" print '\033[0m' if __name__=="__main__": #定义命令行参数 usage = "usage: %prog [options] arg :X.py -rX -tXe" parser = OptionParser(usage) parser.add_option("-r", "--rev", dest="rev", help="input the rev number.") parser.add_option("-t", "--type", dest="type", help="input the update type") (options, args) = parser.parse_args() if options.rev: svnRev = options.rev else: print '\033[0;31;40m' print "input no svn Reversion" print '\033[0m' sys.exit(1) if options.type: svnType = options.type regex=ur"(Xe|rX)" #判断是否是特定参数 if re.search(regex, svnType): pass else: print '\033[0;31;40m' print "svn type is wrong,it must 'Xe' or 'reX'" print '\033[0m' sys.exit(1) else: print '\033[0;31;40m' print "input no svn update type" print '\033[0m' sys.exit(1) main()
python的工作记录B的更多相关文章
- python的工作记录A
马上进入工作自动化: [root@localhost ~]# cat svn_bbs.py import os,sys,commands,subprocess import re,time svnUr ...
- [工作记录] Android OpenGL ES: non-square texture - continue
previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...
- MySQL跨表更新字段 工作记录
工作中遇到两表查询,从user表中获取用户唯一id字段 写入到另外一张qiuzu表中的uid字段中; 二者可以关联起来的只有用户的手机号码tel字段; 了解需求后数据量稍多,不可能一个一个的手动修改 ...
- 最近的linux工作记录
最近的linux工作记录 最近公司走了一些同事,部分服务器交到了我的手里,总结一些常用的操作 注:大写的字符串一般是用来占位,需要替换 创建账户和使用密钥对登陆 1,账户系列 useradd 选项 用 ...
- 工作记录 - OBB的解决方案
之前关于OBB的内容: Android上使用native IO 最近工作中的问题笔记 工作记录[续] android OBB 自从用了Java来mount OBB, 再也没有遇到挂载的问题. 但最近在 ...
- Python爬虫个人记录(三)爬取妹子图
这此教程可能会比较简洁,具体细节可参考我的第一篇教程: Python爬虫个人记录(一)豆瓣250 Python爬虫个人记录(二)fishc爬虫 一.目的分析 获取煎蛋妹子图并下载 http://jan ...
- Python爬虫个人记录(二) 获取fishc 课件下载链接
参考: Python爬虫个人记录(一)豆瓣250 (2017.9.6更新,通过cookie模拟登陆方法,已成功实现下载文件功能!!) 一.目的分析 获取http://bbs.fishc.com/for ...
- 工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox
原文:工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox 1. 背景 因为最近在使用wpf开发桌面端应用,在查看页面需要把TextBox和Combox等控件设置为只读的.原本是个很简 ...
- 图书馆管理系统程序+全套开发文档(系统计划书,系统使用说明,测试报告,UML分析与设计,工作记录)
图书馆管理系统程序+全套开发文档(系统计划书,系统使用说明,测试报告,UML分析与设计,工作记录): https://download.csdn.net/download/qq_39932172/11 ...
随机推荐
- 用QtWebKit开发简单的浏览器
用QtWebKit开发简单的浏览器 1.代码实现 工程目录结构如下: AddressBar类包含了地址栏和按钮两个控件,将地址栏回车和按钮点击信号与goToSite()槽连接. 当回车和点击事件发生时 ...
- BZOJ1697: [Usaco2007 Feb]Cow Sorting牛排序
1697: [Usaco2007 Feb]Cow Sorting牛排序 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 387 Solved: 215[S ...
- 关于标准C语言的预定义宏
标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来.__LINE__ 当前 ...
- 关于百度地图InfoWindow响应自定义布局点击事件
大概讲解: 在百度地图上显示一个marker,当marker被点击后,显示自定义的View.当自定义的View被点击后,响应不同Button的点击事件.被百度这个infowindo里面的view坑惨了 ...
- javascript 中的location.reload
location.reload()是什么意思 location.reload() 括号内有一个参数 true/false , 为空和false的效果一样. 如果该方法没有规定参数,或者参数是 fals ...
- sqlyog v11.24注册码
ccbfc13e-c31d-42ce-8939-3c7e63ed5417 a56ea5da-f30b-4fb1-8a05-95f346a9b20b a0fe8645-3916-45d4-9976- ...
- openwrt network interface(openwrt中的网络接口)
这篇算是对openwrt网络接口的一个翻译吧,源地址:http://wiki.openwrt.org/doc/networking/network.interfaces network的接口类型:物理 ...
- 玩转Win32开发(2):完整的开发流程
上一篇中我给各位说了一般人认为C++中较为难的东西——指针.其实对于C++,难点当然不局限在指针这玩意儿上,还有一些有趣的概念,如模板类.虚基类.纯虚函数等,这些都是概念性的东西,几乎每一 ...
- Java可见性机制的原理
基本概念 可见性 当一个线程修改了共享变量时,另一个线程可以读取到这个修改后的值. 内存屏障(Memory Barriers) 处理器的一组指令,用于实现对内存操作的顺序限制. 缓冲行 CPU告诉缓存 ...
- (二)一个工作任务引起的乱战——C++程序编译为dll,让C#调用
C++程序编译为C#可调用的dll的过程: 1.新建一个Win32 Console Application 项目,项目名为:DLLDemo,下一步选择Application type为DLL; 2.在 ...