groovy syntax in jenkins pipeline for shell commands - jenkins

I am tring to run an ansible shell script thorugh a groovy script in Jenkins. But I am getting weird syntax error when I use special characters like $ or . I tried to use the escape sequence but still getting an error. It works fine if I remove the JAVA_OPTS variable.
batch_service_url="http://DEV:8080/test"
JAVA_OPTS="\$JAVA_OPTS -Dactivemq.tcp.url=failover:\(tcp://DEV1:61616,tcp://DEV1:61616\)?nested.wireFormat.maxInactivityDuration=30000"
def test(){
sh """sudo w360ansibleint <<EOF
ansible-playbook -i ansible/ANS-5.2.0/hosts ansible/ANS-5.2.0/app_config.yml -e '{
"ansible_hostname":"${ansible_hostname}",
"tomcat_app_parameters":"base",
"batch_service_url":"${batch_service_url}",
"tomcat_setenv_extra": ["\\$JAVA_OPTS"]
}'
EOF
"""
}

Related

Jenkins Pipeline: How to replace part of a sh command arg with a variable

I am unsure about some syntax I am putting together for a Jenkins pipeline step where I want to replace part of a command line arg (for a filename) in a shell script with a variable I have defined
sh "npx cypress run --config-file cypress/cypress.$e2eEnvironment.json --env $envCredentials || true"
I think what I have above will look for a variable $e2eEnvironment.json but I dont want that as I need to keep the .json as is in the cli arg. E.g. if I have an $e2eEnvironment value set to integration then the value should get built as cypress/cypress.integration.json
Can someone guide me here please?
You can enforce the exact name of a variable resolution in string interpolation with ${<varName>} syntax in Groovy. In your example:
sh "npx cypress run --config-file cypress/cypress.${e2eEnvironment}.json --env $envCredentials || true"
will resolve to:
sh "npx cypress run --config-file cypress/cypress.integration.json --env $envCredentials || true"
as desired, instead of resolving the assigned value for a variable name e2eEnvironment.json.

How do you properly escape a sed command in a Jenkinsfile

I can run this command from the command line to get the value for the latest release in a GitHub repo:
curl --silent "https://api.github.com/repos/MyOrg/MyRepo/releases/latest"|grep "tag_name"|sed -E 's/."([^"]+)"./\1/'
I'd like to use this in a Jenkinsfile, but I can't seem to properly escape the special characters.
pipeline {
agent any
stages {
stage('Test') {
steps {
sh """
latest=`curl --silent \\\"https://api.github.com/repos/MyOrg/MyRepo/releases/latest\\\"|
grep \\\"tag_name\\\"|
sed -E \\\'s/.*\\\"([^\\\"]+)\\\".*/\1/\\\'`
""".stripIndent()
}
}
}
}
When run in a pipeline, I get the following error:
[Pipeline] sh
curl --silent "https://api.github.com/repos/MyOrg/MyRepo/releases/latest"
grep "tag_name"
sed -E 's/.*"
sed: -e expression #1, char 1: unknown command: `''
instead of wrapping the large expression in backticks, try instead wrapping it in
$(command_1 | command_2 | command_3)
Also add, at the start of the shell command:
set -x;
and you'll get debug output in the console output (possibly). You should then see how your script is being evaluated.

Jenkins Pipeline ${params.Environment} bad substitution

I am trying to send commands to a docker container within docker run via a Jenkins pipeline.
The Jenkins machine is at a different server and the docker image is in a different server.
When I hard code the environment param, the scripts execute as expected. But whenever I try to replace it with the params, it errors out saying :
bash: ${params.Environment} bad substitution
This is my pipeline script
pipeline {
agent any
parameters {
choice(
name: 'Environment',
choices: ['qa','dev'],
description: 'Passing the Environment'
)
}
stages {
stage('Environment') {
steps {
echo " The environment is ${params.Environment}"
}
}
stage('run') {
steps {
sh 'ssh 10.x.x.x \'sudo docker run --name docker_container_name docker_image_name sh -c "cd mytests ; pip3 install -r requirements.txt ; python3 runTests.py -env ${params.Environment} "\''
}
}
}
}
The sh command's parameters needs to have double quotes, or triple double quotes.
sh """ssh 10.x.x.x 'sudo docker run --name docker_container_name docker_image_name sh -c "cd mytests ; pip3 install -r requirements.txt ; python3 runTests.py -env ${params.Environment} "'"""
In the Groovy language used by pipeline scripts, single-quoted strings don't do any interpolation at all, so the ${params.Environment} string gets passed on as-is to the shell. Double-quoted strings do perform interpolation, so the Groovy engine substitutes ${params.Environment} before invoking the shell.
(You might look at the native support for Using Docker with Pipeline which can avoid the ssh 'sudo "..."' wrapping, though it requires Jenkins be able to run Docker itself on the worker nodes.)

Groovy shell script with a sed command in a Jenkins Pipeline

So writing Groovy with basic shell scripts seem to be much more difficult than it really should be.
I have a pipeline that needs to replace an entry in a file after running a packer command. It seems sensible to do this in the same shell script as the packer command as the variables are not available outside of the shell script even when exported.
The problem is that the sed command needs escape upon escape and still doesn't work. So this is what the Jenkins Pipeline Syntax generator suggested:
parallel (
"build my-application" : {
sh '''#!/bin/bash
export PATH=$PATH:~/bin
cd ${WORKSPACE}/platform/packer
packer build -machine-readable template.json | tee packer.out
AMI_APP=$(grep amazon-ebs,artifact,0,id,eu-west-2:ami- packer.out | awk -F: \'{ print $NF }\')
[[ ! ${AMI_APP} ]] && exit 1
sed -i.bak \'s!aws_ami_app = \\".*\\"!aws_ami_app = \\"\'"${AMI_APP}"\'\\"!\' ${WORKSPACE}/platform/terraform/env-${ENV}/env.auto.tfvars
'''
},
"build some-more-apps" : {
sh ''' *** same again different name ***
'''
}
)
What is the correct way to get a variable is a sed command working in a bash script running in groovy?
Any tips for the correct syntax going forward with Jenkins, groovy and bash - any documentation that actually helps?
EDIT
The original sed command that is running in a Jenkins Job shell is:
sed -i.bak 's!aws_ami_app = \".*\"!aws_ami_app = \"'"${AMI_APP}"'\"!' ${WORKSPACE}/platform/terraform/env-${ENV}/env.auto.tfvars
Because you put the shell script inside ''' which won't trigger Groovy String interpolation.
So you no need to escape any character, write the script as when you typing in Shell cmd window.
Below is example:
sh '''#!/bin/bash +x
echo "aws_ami_app = docker.xy.com/xy-ap123/conn:7et45u.1.23" > test.txt
echo "cpu = 512" >> test.txt
cat test.txt
AMI_APP=docker.xy.com/xy-ap123/conn:7et45u.1.25
sed -i 's,aws_ami_app.*,aws_ami_app = '"$AMI_APP"',' test.txt
cat test.txt
'''
Output in jenkins console:
[Pipeline] sh
[poc] Running shell script
aws_ami_app = docker.xy.com/xy-ap123/conn:7et45u.1.23
cpu = 512
aws_ami_app = docker.xy.com/xy-ap123/conn:7et45u.1.25
cpu = 512

How can I start a bash login shell in jenkins pipeline (formerly known as workflow)?

I am just starting to convert my Jenkins jobs into the new Jenkins Pipeline(workflow) tool, and I'm having trouble getting the sh command to use a bash login shell.
I've tried
sh '''
#!/bin/bash -l
echo $0
'''
but the echo $0 command is always being executed in an interactive shell, rather then a bash login shell.
#izzekil is right!!!! Thank you so much!
So to elaborate a little bit about what is going on. I used sh with ''' , which indicates a multiple line script. HOWEVER, the resulting shell script that gets dumped on to the jenkins node will be one line down, rather then the first line. So I was able to fix this with this
sh '''#!/bin/bash -l
echo $0
# more stuff I needed to do,
# like use rvm, which doesn't work with shell, it needs bash.
'''

Resources