不通用版(从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)
复制代码
目录
相关文章
|
7月前
|
人工智能 JavaScript API
零基础构建MCP服务器:TypeScript/Python双语言实战指南
作为一名深耕技术领域多年的博主摘星,我深刻感受到了MCP(Model Context Protocol)协议在AI生态系统中的革命性意义。MCP作为Anthropic推出的开放标准,正在重新定义AI应用与外部系统的交互方式,它不仅解决了传统API集成的复杂性问题,更为开发者提供了一个统一、安全、高效的连接框架。在过去几个月的实践中,我发现许多开发者对MCP的概念理解透彻,但在实际动手构建MCP服务器时却遇到了各种技术壁垒。从环境配置的细节问题到SDK API的深度理解,从第一个Hello World程序的调试到生产环境的部署优化,每一个环节都可能成为初学者的绊脚石。因此,我决定撰写这篇全面的实
1739 67
零基础构建MCP服务器:TypeScript/Python双语言实战指南
|
5月前
|
安全 架构师 Java
Java LTS版本进化秀:从8到21的欢乐升级之旅
困惑于Java版本选择?轻松幽默地穿越Java LTS版本时光隧道,掌握从Java 8到21的关键特性。通过一家初创公司的系统升级故事,直观了解每个版本如何解决代码冗余、性能瓶颈等开发痛点,助你在技术选型中做出明智决策。
326 7
|
6月前
|
人工智能 自然语言处理 安全
Python构建MCP服务器:从工具封装到AI集成的全流程实践
MCP协议为AI提供标准化工具调用接口,助力模型高效操作现实世界。
1196 1
|
7月前
|
安全 Java API
Java 17 及以上版本核心特性在现代开发实践中的深度应用与高效实践方法 Java 开发实践
本项目以“学生成绩管理系统”为例,深入实践Java 17+核心特性与现代开发技术。采用Spring Boot 3.1、WebFlux、R2DBC等构建响应式应用,结合Record类、模式匹配、Stream优化等新特性提升代码质量。涵盖容器化部署(Docker)、自动化测试、性能优化及安全加固,全面展示Java最新技术在实际项目中的应用,助力开发者掌握现代化Java开发方法。
329 1
|
6月前
|
Cloud Native Java API
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
1238 0
|
8月前
|
缓存 安全 网络协议
如何使用Bluetown Cloud服务器及其CDN服务来掩护VPS的真实IP地址。
最终,通过Bluetown Cloud的CDN服务,你的VPS不仅仅是隐藏在一层又一层的保护之下,同时也因为CDN的全球节点而享受到加速访问的优势,无所不在又不被发现,像是一位能在互联网世界中自由穿梭的幽灵特工。
165 14
|
8月前
|
应用服务中间件 网络安全 数据安全/隐私保护
网关服务器配置指南:实现自动DHCP地址分配、HTTP服务和SSH无密码登录。
哇哈哈,道具都准备好了,咱们的魔术秀就要开始了。现在,你的网关服务器已经魔法满满,自动分配IP,提供网页服务,SSH登录如入无人之境。而整个世界,只会知道效果,不会知道是你在幕后操控一切。这就是真正的数字世界魔法师,随手拈来,手到擒来。
406 14
|
9月前
|
人工智能 安全 Shell
Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
Jupyter MCP服务器基于模型上下文协议(MCP),实现大型语言模型与Jupyter环境的无缝集成。它通过标准化接口,让AI模型安全访问和操作Jupyter核心组件,如内核、文件系统和终端。本文深入解析其技术架构、功能特性及部署方法。MCP服务器解决了传统AI模型缺乏实时上下文感知的问题,支持代码执行、变量状态获取、文件管理等功能,提升编程效率。同时,严格的权限控制确保了安全性。作为智能化交互工具,Jupyter MCP为动态计算环境与AI模型之间搭建了高效桥梁。
620 2
Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
|
7月前
|
安全 Linux 网络安全
Python极速搭建局域网文件共享服务器:一行命令实现HTTPS安全传输
本文介绍如何利用Python的http.server模块,通过一行命令快速搭建支持HTTPS的安全文件下载服务器,无需第三方工具,3分钟部署,保障局域网文件共享的隐私与安全。
1650 0
|
8月前
|
物联网
云服务器搭建rttys服务
RTTYS是一款基于Web的串口调试工具,分为服务端(rttys)和客户端(rtty)。服务端负责连接串口设备并提供接口,客户端通过浏览器访问实现远程串口调试。它具有跨平台、易部署的特点,适用于物联网、嵌入式开发等场景,极大提升调试效率。