不通用版(从SVN取版本,通过MAVEN生成JAVA包,通过SALTSTACK传送到远程服务器并自动重启TOMCAT服务)PYTHON代码
从昨晚写到今天啊,
第一版测试成功了。
PHP和JAVA的更新相对来说,PHP的自动化更新是简单多啦~~
当然,这只是运维工作当中的一环~~

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os,sys,commands,subprocess
import re,time,logging
from optparse import OptionParser
#启动日志模块
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',
filename='updateSVN.log',
filemode='a')
#将输入的参数与相应的配置文件匹配,并形成特殊字典,方便后续取值
def get_svn_list(name, ip, version):
svn_update = {}
for line in open("data_svn_src_java"):
line_item = line.strip("\n").split("|")
if ip == line_item[0] and name == line_item[1]:
line_item = line.strip("\n").split("|")
svn_update["salt_minion_ip"] = line_item[0]
svn_update["svn_name"] = line_item[1]
svn_update["salt_master_dir"] = "/srv/salt/%s/" % line_item[0]
svn_update["server_dir"] = line_item[2]
svn_update["svn_dir"] = line_item[3]
svn_update["package_name"] = line_item[4]
svn_update["svn_version"] = version
if len(svn_update) != 7:
error_output("database have none item at your xargs.")
return svn_update
#统一错误输出,红色文字提示
def error_output(error_str):
print '\033[0;31;40m'
print error_str + "<br>"
print '\033[0m'
sys.exit(1)
#统一调用执行系统命令,并产生相应输出及日志记录
def exec_cmd(cmd):
str_now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
(status,output) = commands.getstatusoutput(cmd)
try:
if int(status) == 0:
print "%s %s is ---OK!<br>" % (str_now, cmd)
logging.info(cmd + " ---is OK!")
return output
else:
logging.info(cmd + " cant't finish...")
print "%s %s can't finish...<br>" % (str_now, cmd)
sys.exit(1)
except:
logging.info(cmd + " is Wrong")
print "%s %s --- is Wrong<br>" % (str_now, cmd)
sys.exit(1)
#在真正应用SALTSTACK之前,先测试是否正常连接
def salt_minion_test(salt_minion_ip):
if "True" not in exec_cmd("salt '%s' test.ping" % salt_minion_ip):
error_output("salt minion %s is not active,please restart this minion and execute is again. " % salt_minion_ip)
else:
print "salt minion ip %s is ok.<br>" % salt_minion_ip
#从SVN相应目录里取出文件,存放在SALTSTACK的相应目录里(以IP作为目录存放位置)
def get_svn_file(svn_dir, svn_version, salt_master_dir):
exec_cmd("rm -rf %s" % salt_master_dir)
exec_cmd("mkdir -p %s" % salt_master_dir)
svnLog_cmd ="svn co %s %s --username cheng168 --password chengcheng -r %s" % (svn_dir, salt_master_dir, svn_version)
output = exec_cmd(svnLog_cmd)
if svn_version not in output:
error_output("svn version is Wrong<br>")
sys.exit(1)
#用MAVEN生成相应的JAR或WAR包
def gen_package(salt_master_dir):
mvn_cmd = "mvn clean install -Dmaven.test.skip=true -Pprod -f %spom.xml" % (salt_master_dir)
exec_cmd(mvn_cmd)
#由于数据频道特殊,脚本会在解压之后生成一个备份。
def update_back():
print "back_pass"
#以下几个函数是为了区别consumer和provider的更新,主要是执行相关系统调用
def shutdown_consumer_tomcat(salt_minion_ip, server_dir):
tomcat_dir = '/'.join(server_dir.split('/')[:-3])
shutdown_A_cmd = "salt '%s' cmd.run 'su - tomcat -c %s/bin/shutdown.sh'" % (salt_minion_ip, tomcat_dir)
exec_cmd(shutdown_A_cmd)
time.sleep(2)
shutdown_B_cmd = """salt '%s' cmd.run "ps aufx|grep tomcat|grep %s/endorsed|grep -v grep|awk '{print $2}'|xargs kill -9" """% (salt_minion_ip, tomcat_dir)
exec_cmd(shutdown_B_cmd)
def shutdown_provider_java(salt_minion_ip, package_name):
shutdown_jar_cmd = """salt '%s' cmd.run "ps aufx|grep %s|grep -v grep|awk '{print $2}'|xargs kill -9" """ % (salt_minion_ip, package_name)
exec_cmd(shutdown_jar_cmd)
def startup_consumer_tomcat(salt_minion_ip, server_dir):
tomcat_dir = '/'.join(server_dir.split('/')[:-3])
startup_cmd = "salt '%s' cmd.run 'su - tomcat -c %s/bin/startup.sh'" % (salt_minion_ip, tomcat_dir)
#exec_cmd(startup_cmd)
#此处不能再调用exec_cmd,因为不能及时获取返回值,再开一个子进程,就流畅多啦。。
subprocess.Popen(startup_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def startup_provider_java(salt_minion_ip, server_dir, package_name):
#此处太过技巧化,希望以后能写成更好理解的,三引号的使用,切换用户帐号,后台执行服务器命令都全了。
startup_cmd = """salt '%s' cmd.run 'su - tomcat -c "java -jar %s%s &"'""" % (salt_minion_ip, server_dir, package_name)
print startup_cmd
#exec_cmd(startup_cmd)
subprocess.Popen(startup_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def update_consumer_package(salt_minion_ip, server_dir, package_name):
#几个变量主要是为了精简配置文件,将备份放在合适的目录
package_dir = ''.join(package_name.split('.')[0])
tomcat_dir = '/'.join(server_dir.split('/')[:-3])
salt_master_file = "salt://%s/target/%s" % (salt_minion_ip, package_name)
salt_minion_file = server_dir + package_name
back_minion_dir = tomcat_dir + "/backup/"
update_package_cmd = "salt '%s' cp.get_file %s %s makedirs=True" % (salt_minion_ip, salt_master_file, salt_minion_file)
exec_cmd(update_package_cmd)
unzip_cmd = "salt '%s' cmd.run 'unzip %s%s -d %s'" % (salt_minion_ip, server_dir, package_name, server_dir)
exec_cmd(unzip_cmd)
chown_cmd = "salt '%s' cmd.run 'chown tomcat:tomcat %s'" % (salt_minion_ip, server_dir)
exec_cmd(chown_cmd)
#小峤要求解压后删除WAR文件,便于后期直接更新静态文件,我在此处正好将它备份起来
mv_cmd = "salt '%s' cmd.run 'mv %s %s'" % (salt_minion_ip, salt_minion_file, back_minion_dir)
exec_cmd(mv_cmd)
#因为DUBBO的CONSUMER消费者为WAR包,服务提供者为JAR包,所以启动,关闭,更新上传都分成了两套函数
def update_provider_package(salt_minion_ip, server_dir, package_name):
salt_master_file = "salt://%s/target/%s" % (salt_minion_ip, package_name)
salt_minion_file = server_dir + package_name
update_package_cmd = "salt '%s' cp.get_file %s %s makedirs=True" % (salt_minion_ip, salt_master_file, salt_minion_file)
exec_cmd(update_package_cmd)
cp_cmd = "salt '%s' cmd.run 'cp %s %s.bak'" % (salt_minion_ip, salt_minion_file, salt_minion_file)
exec_cmd(cp_cmd)
chown_cmd = "salt '%s' cmd.run 'chown tomcat:tomcat %s*'" % (salt_minion_ip, server_dir)
exec_cmd(chown_cmd)
def main(name, ip, version):
svn_update = get_svn_list(name, ip, version)
salt_minion_test(svn_update["salt_minion_ip"])
get_svn_file(svn_update["svn_dir"], svn_update["svn_version"], svn_update["salt_master_dir"])
gen_package(svn_update["salt_master_dir"])
update_back()
#服务器和消费的前面操作都相同,但在此后,要分路径判断执行相应的操作
if svn_update["package_name"] == "consumer.war" :
shutdown_consumer_tomcat(svn_update["salt_minion_ip"], svn_update["server_dir"])
update_consumer_package(svn_update["salt_minion_ip"], svn_update["server_dir"], svn_update["package_name"])
startup_consumer_tomcat(svn_update["salt_minion_ip"], svn_update["server_dir"])
if svn_update["package_name"] == "provider.jar" :
shutdown_provider_java(svn_update["salt_minion_ip"], svn_update["package_name"])
update_provider_package(svn_update["salt_minion_ip"], svn_update["server_dir"], svn_update["package_name"])
startup_provider_java(svn_update["salt_minion_ip"], svn_update["server_dir"], svn_update["package_name"])
if __name__=="__main__":
#输入参数判断,如有输入不完,及早提示并退出
usage = "usage: %prog [options] arg :./update.py -v 12292 -n bbs -i 192.168.11.75"
parser = OptionParser(usage)
parser.add_option("-v", "--version", dest="version", help="input the version(Sample: 15435...).")
parser.add_option("-n", "--name", dest="name", help="input the svn name(consumer|provider)")
parser.add_option("-i", "--ip", dest="ip", help="input the ip address(1.4.8.25|11.14.7.2)")
(options, args) = parser.parse_args()
version = options.version
name = options.name
ip = options.ip
if version is None or name is None or ip is None :
error_output("you must input all args: ./update_svn_shuju.py -i xx -n xx -v xx")
main(name, ip, version)
不通用版(从SVN取版本,通过MAVEN生成JAVA包,通过SALTSTACK传送到远程服务器并自动重启TOMCAT服务)PYTHON代码的更多相关文章
- idea2020.1版本的maven项目报包不存在,找不到包错误
错误描述 idea创建maven项目,导入依赖都是成功,但是运行就会报找不到对应jar包的错误 解决办法: File -> Settings -> 搜索maven -> 展开mave ...
- SVN同步版本库与网站目录
如何创建SVN版本库及同步文件到WEB目录 来源:空谷 一 安装与配置SVN 1.安装subversion centos: yum install subversion ubuntu: apt-get ...
- AES加密解密通用版Object-C / C# / JAVA
1.无向量 128位 /// <summary> /// AES加密(无向量) /// </summary> /// <param name="plainByt ...
- 初学svn对版本进行控制 用post- commit钩子实现代码同步到web目录
这里只是一个记录,原文摘抄svn利用钩子实现代码同步到web目录 思路: 找 到SVN Server中的仓库(Repositories)文件夹的位置,在相应的项目文件夹中找到hooks文件夹.在该文件 ...
- C# 给某个方法设定执行超时时间 C#如何控制方法的执行时间,超时则强制退出方法执行 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)
我自己写的 /// <summary> /// 函数运行超时则终止执行(超时则返回true,否则返回false) /// </summary> /// <typepara ...
- 更新Delphi中SVN客户端版本的方法
Delphi从XE以后集成里SVN客户端, 安装完Delphi以后, 在bin\subversion下, 存放的就是SVN客户端文件, 可惜版本有点低(好像是1.7的) 如果想更新成高版本的客户端文件 ...
- 【转】NPAPI 插件无法在 Chrome 42 版及更高版本上正常运行
原文网址:https://support.google.com/chrome/answer/6213033 NPAPI 插件无法在 Chrome 42 版及更高版本上正常运行 您可以利用插件在浏览器中 ...
- C# 数据库并发的解决方案(通用版、EF版)
自ASP.NET诞生以来,微软提供了不少控制并发的方法,在了解这些控制并发的方法前,我们先来简单介绍下并发! 并发:同一时间或者同一时刻多个访问者同时访问某一更新操作时,会产生并发! 针对并发的处理, ...
- PHP进行安全字段和防止XSS跨站脚本攻击过滤(通用版)
废话不多说,直接贴使用方法和代码: 使用方式:1)写在公共方法里面,随时调用即可.2)写入类文件,使用是include_once 即可 代码: /* 进行安全字段和xss跨站脚本攻击过滤(通用版) - ...
随机推荐
- 缓存淘汰算法 (http://flychao88.iteye.com/blog/1977653)
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. ...
- Linux用户与用户组的详解
1,用户和用户组文件 在linux中,用户帐号,用户密码,用户组信息和用户组密码均是存放在不同的配置文件中的. 在linux系统中,所创建的用户帐号和其相关信息(密码除外)均是存放在/etc/ ...
- ORACLE功能GREATEST功能说明具体实例
1 语法 GREATEST(expr_1, expr_2, ...expr_n) 2 说明 GREATEST(expr_1, expr_2, ...expr_n ...
- Oracle EBS 入门
Oracle EBS 入门Oracle EBS全称是Oracle 电子商务套件(E-Business Suit),是在原来Application(ERP)基础上的扩展,包含ERP(企业资源计划管理). ...
- PHP 計算字符串長度函數
PHP內置的字符串長度函數strlen無法正確處理中文字符串,它得到的只是字符串所占的字節數.對於GB2312的中文編碼,strlen得到的值是漢字個數的2倍,而對於UTF-8編碼的中文,就是3倍的差 ...
- 第三篇:R语言数据可视化之条形图
条形图简介 数据可视化中,最常用的图非条形图莫属,它主要用来展示不同分类(横轴)下某个数值型变量(纵轴)的取值.其中有两点要重点注意: 1. 条形图横轴上的数据是离散而非连续的.比如想展示两商品的价格 ...
- EventLoop的设计
1. Event Loop作为一个IO线程,通过IO复用来处理事件 2. 为了保证线程安全,任何需要修改IO线程资源的工作都交给IO线程亲自来做 3. 为了IO线程与其他线程互调,需要设计一个even ...
- xUtils3源码分析(一):view的绑定
概述 xUtils3是国人开发的一款功能丰富的Android快速开发框架,值得研究下.zip包下载:[ZIP]xutils主要分以下几个模块 视图绑定模块 网络请求模块 数据库模块 图片加载模块 我们 ...
- HUD3336
/* 巧妙地使用fail数组 根据fail数组的定义 fail[i] 有 长度为i的子串最长公共前后缀为fail[i] 比如样例 fail 0 0 1 2 那么我们维护一个ans[i]表示到i位置的时 ...
- Linux SSH: key, agent, keychain
以前遇到过一个问题,在用有些 Linux 发行版时,用 ssh-keygen 产生好了密钥对并上传到了目标服务器,但每次登录都要重新输入. 这与 ssh-agent 有关,看如下 man ssh-ag ...