Home > front end >  Efficiently handle multiple arguments
Efficiently handle multiple arguments

Time:07-01

I use Jenkins to trigger a deployment of multiple services (using a deployment script) There are 6 services in total and have used Jenkins Boolean Parameter to select which services to be deployed.

So, if 1st, 4th and 5th services are to be deployed, the input to the deployment script looks like below in the Jenkins Execute shell tab.

#!/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}"

Note: Deployment happens in a differnt server with very restricted access, so the deployment script - mydeploy.sh has to be copied from the Jenkins slave to the deployment server, then executed with the respective arguments.

How can I make this setup more robust and elegant. I dont want to pass 6 arguments, if all the 6 services are selected. What's the better way to do it ?

CodePudding user response:

An array would help here.

#!/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[@]} will expand to the list of all the services you want to deploy so that you don't have to set a unique variable for each one.

One caveat though is that running a command over ssh is similar to running a command using eval because the remote shell will reparse whatever comes through before executing it. If your services have simple names this might not matter, but if you had a hypothetical Hello World service then the remote script would treat Hello and World as two separate arguments due to Word Splitting which probably isn't what you want.

If this is a problem for you, you could fix this with either printf %q (supported by most Bash shells) or by expanding the array as "${services_to_deploy[@]@Q}" if you have Bash 4.4 or higher.

An example using printf %q might look like:

#!/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[@]}"

CodePudding user response:

How about you improve your script and introduce some flags.

# --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}
  • Related