我使用Jenkins来触发多个服务的部署(使用部署脚本)总共有6个服务,并且已经使用JenkinsBoolean Parameter
来选择要部署的服务。
因此,如果要部署第1、第4和第5个服务,则部署脚本的输入如下所示,在Jenkins Execute shell选项卡中:
#!/bin/bash
sshpass -p <> ssh username@host "copy the deployment script to the deployment VM/server and give execute persmission...."
sshpass -p <> ssh username@host "./mydeploy.sh ${version_to_be_deployed} ${1st_service} ${4th_service} ${5th_service}"
注意:部署发生在访问受限的不同服务器上,因此部署脚本-mydeploy.sh
必须从Jenkins从服务器复制到部署服务器,然后使用各自的参数执行。
我怎样才能使这个设置更健壮和优雅?如果所有6个服务都被选中,我不想传递6个参数。有什么更好的方法呢?
数组可以帮上忙。
#!/bin/bash
#hardcoded for demo purposes, but you can build dynamically from arguments
services_to_deploy=( 1 4 5 )
sshpass -p <> ssh username@host "copy the deployment script to the deployment VM/server and give execute persmission...."
sshpass -p <> ssh username@host "./mydeploy.sh ${version_to_be_deployed} ${services_to_deploy[@]}"
${services_to_deploy[@]}
将扩大到所有你想要部署的服务的列表,这样你不需要为每一个设置一个独特的变量。
需要注意的是,通过ssh运行命令与使用eval
运行命令类似,因为远程shell将在执行之前重新解析通过的任何命令。如果你的服务有简单的名字,这可能无关紧要,但如果你有一个假设的Hello World
服务,那么远程脚本会把Hello
和World
作为两个单独的参数,因为分词,这可能不是你想要的。
如果这对你来说是一个问题,你可以用printf %q
(大多数Bash shell支持)来解决这个问题,或者如果你有Bash 4.4或更高版本,可以将数组扩展为"${services_to_deploy[@]@Q}"
。
使用printf %q
的示例如下:
#!/bin/bash
services_to_deploy=( 1 4 5 )
remote_arguments=()
for s in "${services_to_deploy[@]}" ; do
remote_arguments+=( "$( printf '%q' "${s}" )" )
done
sshpass -p <> ssh username@host "copy the deployment script to the deployment VM/server and give execute persmission...."
sshpass -p <> ssh username@host "./mydeploy.sh ${version_to_be_deployed} ${remote_arguments[@]}"
不如改进一下你的脚本,并引入一些标志。
# --all : Deploys all services
./mydeploy.sh --version 1.0 --all
# --exclude : Deploys all services other than 5th_service and 4th_service (Excludes 4th and 5th)
./mydeploy.sh --version 1.0 --exclude ${5th_service} ${4th_service}
# --include : Deploys just 4th_service and 5th_service
./mydeploy.sh --version 1.0 --include ${5th_service} ${4th_service}