Shell实战【利用Shell脚本自定义SaltStack部署Java程序包】

一、简介

这是一篇关于利用Shell脚本编程实现调用SatlStack自动化运维工具批量部署Java程序包的实战文章。在前些篇文章和知识的积累下,我们已经可以使用SaltStack自动化运维工具完成一些程序和配置的自动化批量部署。
但是在实际运维工作中,我们每次部署程序包的机器、程序包的位置、程序包的名称可能都不同,那么每次都要繁琐的修改这些SLS文件中的参数配置是不是很麻烦?我们是不是可以利用Shell编程写一个通用脚本,像使用其他命令一样,每次只需在命令后加一些参数,如 部署的节点组、部署的路径、程序包的名称等,这样是不是大大的减少了工作量,使程序看上去更加智能化?这就是此脚本诞生的初衷。
本文将着重讲解此shell脚本的设计思路和逻辑,致在传达作者Shell脚本编写的想法,使用的也都是一些初级的IF、CASE等语句,如有更好的建议可反馈给作者,大家共同学些和进步。

二、设计思路

1、建立一个SLS模版文件,每次运行shell脚本时自动根据配置参数生成新的SLS文件,这样就可以实现SLS配置的参数化。
2、把每次部署java程序包所需要的信息都参数化,如部署的节点组(部署到那些机器)、部署的路径(JAVA程序包放在哪里?)、JAVA程序包的名称。把这三个每次需要修改的信息都参数化,并根据输入的参数动态生成SLS文件,在top.sls中调用新生成的SLS文件。
3、检查参数是否合法,如输入的参数个数、输入的群组名称是否存在、部署的路径是否输入正确、输入的程序包名称是否正确等
4、还要增加SaltStack 的test=True 选项,方便批量部署的调试工作。
5、部署前备份原来的JAVA程序包。

三、实现

top.sls的内容如下: 这里引用的SLS文件名就是一会将要动态生成的文件名

[root@server01 salt]# cat top.sls
tomcatservice:
 '*':
  - devwar_temp

1、建立模版文件 devwar.sls

[root@server01 tomcatservice]# cat devwar.sls 
/srv/salt/tomcatservice:
 file.managed:
  - name: /usr/local/tomcatpath/webapps/warname
  - source: salt://warname

inittomcat:
 service.running:
  - watch:
    - file: /usr/local/tomcatpath/webapps/warname

2、动态生成SLS文件
这里我们对shell脚本定义了4个位置参数
$1 组名称(java包要部署到的节点集群)
$2 部署的路径(要将程序包部署到的具体路径,可能会存在一台机器上同时跑两个或多个tomcat的情况)
$3 程序包名称 (程序包是否存在)
$4 test=True (如果增加test=True 参数将是调试模式,否则为正常模式,其实就是SaltStack的 test=True)
根据每次脚本后跟的参数动态生成对应的SLS文件,这里需要动态生成的信息只会用到 $2 和 $3 ,这部分代码如下:

TOMCATPATH8080=/usr/local/apache-tomcat-8.0.24
TOMCATPATH9090=/usr/local/apache-tomcat-8.0.24-9090
WARPATH=/srv/salt/tomcatservice
PATH=$PATH
DEVTEMP=devwar_temp.sls


export TOMCATPATH8080
export TOMCATPATH9090
export WARPATH
export PATH
export DEVTEMP

### 创建devwar_emp.sls 临时文件,每次都覆盖
cat $WARPATH/devwar.sls > $WARPATH/$DEVTEMP
### 判断参数2  表示war包的部署路径,用于一台机有2个tomcat 8080 和 9090 端口
if [ "$2" = "tomcat8080" ]
  then 
	sed -i 's#inittomcat#'$2'#' $WARPATH/$DEVTEMP
      	sed -i 's#tomcatpath#apache-tomcat-8.0.24#' $WARPATH/$DEVTEMP
elif [ "$2" = "tomcat9090" ]
  then 
	sed -i 's#inittomcat#'$2'#' $WARPATH/$DEVTEMP
      	sed -i 's#tomcatpath#apache-tomcat-8.0.24-9090#' $WARPATH/$DEVTEMP
else
   echo "your parameter error ,please tomcat8080 or tomcat9090"
   exit 1
fi

### 判断参数3 表示war包文件是否存在
if [ -f "$PWD/$3" ]
   then
	sed -i 's#warname#'$3'#' $WARPATH/$DEVTEMP
else
	echo "war not esxit, please check"
	exit 1
fi

执行完脚本生成新的devwar_temp.sls

[root@server01 tomcatservice]# sh devwar.sh testtomcat tomcat8080 JavaProjectWeb.war

[root@server01 tomcatservice]# cat devwar_temp.sls 
/srv/salt/tomcatservice:
 file.managed:
  - name: /usr/local/apache-tomcat-8.0.24/webapps/JavaProjectWeb.war
  - source: salt://JavaProjectWeb.war

tomcat8080:
 service.running:
  - watch:
    - file: /usr/local/apache-tomcat-8.0.24/webapps/JavaProjectWeb.war

这个就是我们真正想要的用于salt的sls文件了,根据参数生成。
3、部署组的识别
实现功能,可以使用 -g 参数可以查看 目前系统中支持的组名称,
如果输入的是节点组名,那就更新整个组的节点机器。
如果输入的单个机器名称,那么就去更新单个机器。
如果输入的既不是组名,也不是机器名,那么将有salt程序发出错误信息。
这部分代码如下:

### 判断参数1 是否输入正确 单机或是部署组是否存在

if ! grep -w $1 /etc/salt/master.d/nodegroups.conf > /dev/null
  then
	echo "host or group not esxit,please check salt config"
	exit 1
fi

##通过salt的 nodegroups.conf文件中定义的组名来抓去并格式化成下边case语句中想要的格式
嵌套了case语句,是为了在更新war包之前备份war包,运维最重要的是备份、备份、备份!!

NODEGROUPS=$(awk '{ print $1 }' /etc/salt/master.d/nodegroups.conf | sed -e '1d' -e 's/:/|/g' |tr -d '\n'| sed 's/|$//')
export NODEGROUPS
#echo $NODEGROUPS
shopt -s extglob
case $1 in
@($NODEGROUPS) )
        ## 更新前备份原war包
        case $2 in
        tomcat8080)
                salt -N "$1" cmd.run "cp $TOMCATPATH8080/webapps/$3 /opt/warbak/$3.$(date +%y%m%d%y%m%d%k%M%S)"
                ;;
        tomcat9090)
                salt -N "$1" cmd.run "cp $TOMCATPATH9090/webapps/$3 /opt/warbak/$3.$(date +%y%m%d%y%m%d%k%M%S)"
                ;;
        esac
        salt -N "$1" state.highstate ${4:-}
        ;;
* )
        ## 更新前备份原war包
        case $2 in
        tomcat8080)
                salt "$1" cmd.run "cp $TOMCATPATH8080/webapps/$3 /opt/warbak/$3.$(date +%y%m%d%y%m%d%k%M%S)"
                ;;
        tomcat9090)
                salt "$1" cmd.run "cp $TOMCATPATH9090/webapps/$3 /opt/warbak/$3.$(date +%y%m%d%y%m%d%k%M%S)"
                ;;
        esac
        salt "$1" state.highstate ${4:-}
        ;;
esac

4、输入参数的数量是否正确

###判断参数数量是否正确,参数数量为3个或是4个,如果数量不正确将退出,为什么是3个或4个?因为还有一个可选使用的test=True 参数
if [ "$#" -lt "3" ] || [ "$#" -gt "4" ]      
  then
        echo "Your parameter error,Please use the -h or --help for help"
        exit 1
fi

5、好了,基本的功能点都实现了,完整的脚本代码如下:

[root@server01 tomcatservice]# vi devwar.sh 

#!/bin/bash

## This is a Java package deployment scripts.
## Version 1.0.
## Founded in September 1, 2015.
## Founder Edsion.

##--------------------------------------------------------------------------------------------------
## Functionality

## Combining with the implementation Java package SaltStack automated deployment, and can according
## to each of the different input parameters, dynamically generated SLS file, don't have to manually
## modify the SLS file at a time, greatly improve the efficiency of application deployment and ease
## of use.
##--------------------------------------------------------------------------------------------------

## Grammar

## devwar.sh  nodegroup  path  warname [test=True]

TOMCATPATH8080=/usr/local/apache-tomcat-8.0.24
TOMCATPATH9090=/usr/local/apache-tomcat-8.0.24-9090
WARPATH=/srv/salt/tomcatservice
PATH=$PATH
DEVTEMP=devwar_temp.sls


export TOMCATPATH8080
export TOMCATPATH9090
export WARPATH
export PATH
export DEVTEMP

case $1 in
-h|--help)
        echo "devwar.sh help
        基本语法 devwar.sh 组名 部署路径 war包名称
        例如  sh devwar.sh zzatamcat tomcat8080 zza.war
        -h 或 --help  帮助
        -g 查看salt 组名
        第4个参数 可以加 test=True 开启salt 测试模式"
        exit 1
;;
-g)
        GROUPNAME=$(cat  /etc/salt/master.d/nodegroups.conf|sed '1d')
        export GROUPNAME
        echo "  组名      包含的主机(minion id)"
        echo " --------------------------------- "
        echo    "$GROUPNAME "
        exit 1
;;
esac
###判断参数数量是否正确,不正确将退出
if [ "$#" -lt "3" ] || [ "$#" -gt "4" ]
  then
        echo "Your parameter error,Please use the -h or --help for help"
        exit 1
fi

### 判断参数1 是否输入正确 部署组是否存在

if ! grep -w $1 /etc/salt/master.d/nodegroups.conf > /dev/null
  then
        echo "host or group not esxit,please check salt config"
        exit 1
fi
### 创建devwar.temp.sls 临时文件
cat $WARPATH/devwar.sls > $WARPATH/$DEVTEMP

### 判断参数2  表示war包的部署路径,用于一台机有2个tomcat 8080 和 9090 端口
if [ "$2" = "tomcat8080" ]
  then
        sed -i 's#inittomcat#'$2'#' $WARPATH/$DEVTEMP
        sed -i 's#tomcatpath#apache-tomcat-8.0.24#' $WARPATH/$DEVTEMP
elif [ "$2" = "tomcat9090" ]
  then
        sed -i 's#inittomcat#'$2'#' $WARPATH/$DEVTEMP
        sed -i 's#tomcatpath#apache-tomcat-8.0.24-9090#' $WARPATH/$DEVTEMP
else
   echo "your parameter error ,please tomcat8080 or tomcat9090"
   exit 1
fi

### 判断参数3 表示war包文件是否存在
if [ -f "$PWD/$3" ]
   then
        sed -i 's#warname#'$3'#' $WARPATH/$DEVTEMP
else
        echo "war not esxit, please check"
        exit 1
fi

NODEGROUPS=$(awk '{ print $1 }' /etc/salt/master.d/nodegroups.conf | sed -e '1d' -e 's/:/|/g' |tr -d '\n'| sed 's/|$//')
export NODEGROUPS
shopt -s extglob
case $1 in
@($NODEGROUPS) )
        ## 更新前备份原war包
        case $2 in
        tomcat8080)
                salt -N "$1" cmd.run "cp $TOMCATPATH8080/webapps/$3 /opt/warbak/$3.$(date +%y%m%d%y%m%d%k%M%S)"
                ;;
        tomcat9090)
                salt -N "$1" cmd.run "cp $TOMCATPATH9090/webapps/$3 /opt/warbak/$3.$(date +%y%m%d%y%m%d%k%M%S)"
                ;;
        esac
        salt -N "$1" state.highstate ${4:-}
        ;;
* )
        ## 更新前备份原war包
        case $2 in
        tomcat8080)
                salt "$1" cmd.run "cp $TOMCATPATH8080/webapps/$3 /opt/warbak/$3.$(date +%y%m%d%y%m%d%k%M%S)"
                ;;
        tomcat9090)
                salt "$1" cmd.run "cp $TOMCATPATH9090/webapps/$3 /opt/warbak/$3.$(date +%y%m%d%y%m%d%k%M%S)"
                ;;
        esac
        salt "$1" state.highstate ${4:-}
        ;;
esac

部署结果如下图:

发表评论