call parameter value jenkins from shell - jenkins

I want to be able to call the parameters value from the shell and use it in my shell script. My priority is to not use If for every value selected in the params, but rather it choose the active choice. Is it possible as am having issue with this error?
line 4: ${params.prime_server}: bad substitution
#!/usr/bin/env groovy
properties([
parameters([
choice(
name: 'prime_server',
choices: ['','choice1', 'choice2', 'choice3','choice4'],
description: 'Name choice'
),
choice(
name: 'old_server',
choices: ['','choice1', 'choice2', 'choice3','choice4'],
description: 'Name choice'
)
])
])
stage('stage1') {
environment{
}
node("master") {
sh '''
echo -e "-------------------------------Calling the params value into shell----------------------------"
echo "${params.prime_server}"
echo "${params.old_server}"
oldserver="${params.old_server}"
primeserver="${params.prime_server}"
echo "${oldserver}"
echo "${primeserver}"
sed -i -e "0,/${oldserver}/ s/${oldserver}/${primeserver}/g" test.xml
'''.stripIndent()
}
}
Is there anyway to call this param value and assign it to variables in shell

Shell block with single quotes does not take variables into consideration, so double quotes must be used.
Example:
sh """
<your code>
"""

You should be using double quotes if you want Groovy to do string interpolation. So change your shell block like below.
sh """
echo -e "-------------------------------Calling the params value into shell----------------------------"
echo "${params.prime_server}"
echo "${params.old_server}"
oldserver="${params.old_server}"
primeserver="${params.prime_server}"
echo "\${oldserver}"
echo "\${primeserver}"
sed -i -e "0,/${oldserver}/ s/${oldserver}/${primeserver}/g" test.xml
""".stripIndent()

Related

Jenkins Pipeline: I cannot add a variable from a concatenated command in bash script

I have created several bash scripts that work perfect in the Linux shell, but when I try to incorporate them in a Jenkins Pipeline I get multiple errors, I attach an example of my Pipeline where I just want to show the value of my variables, the pipeline works fine except when I added in line 5 the environment, you can see that there are special characters that are not interpreted by Groovy as the Bash does.
pipeline {
agent {
label params.LABS == "any" ? "" : params.LABS
}
environment{
PORT_INSTANCE="${docker ps --format 'table {{ .Names }} \{{ .Ports }}' --filter expose=7000-8999/tcp | (read -r; printf "%s\n"; sort -k 3) | grep web | tail -1 | sed 's/.*0.0.0.0.0://g'|sed 's/->.*//g'}"
}
stages {
stage('Setup parameters') {
steps {
script {
properties([
parameters([
choice(
choices: ['LAB-2', 'LAB-3'],
name: 'LABS'
),
string(
defaultValue: 'cliente-1',
name: 'INSTANCE_NAME',
trim: true
),
string(
defaultValue: '8888',
name: 'PORT_NUMBER',
trim: true
),
string(
defaultValue: 'lab.domain.com',
name: 'DOMAIN_NAME',
trim: true
)
])
])
}
sh """
echo '${params.INSTANCE_NAME}'
echo '${params.PORT_NUMBER}'
echo '${params.DOMAIN_NAME}'
echo '${PORT_INSTANCE}
"""
}
}
}
}
I already tried the same thing from the sh section """ command """ and they throw the same errors.
Can someone help me to know how to run advanced commands that work in the linux shell (bash), that is, is there any way to migrate scripts from bash to Jenkins?
Thank you very much for your help ;)
I want to be able to create a variable from a bash script command from the Pipeline in Jenkins
PORT_INSTANCE="${docker ps --format 'table {{ .Names }} {{ .Ports }}' --filter expose=7000-8999/tcp | (read -r; printf "%s\n"; sort -k 3) | grep web | tail -1 | sed 's/.0.0.0.0.0://g'|sed 's/->.//g'}"
I believe that you can't execute a bash script in the environment step based on the documentation.
You can create a variable from a bash script using the sh step with returnStdout set to true. Declarative pipeline doesn't allow you to assign the retrun value to a variable, so you will need to call sh inside a script like this:
stage('Calculate port') {
steps {
script {
// When you don't use `def` in front of a variable, you implicitly create a global variable
// This means that the variable will exist with a value, and can be used in any following line in your scipt
PORT_INSTANCE = sh returnStdout: true, script: "docker ps --format 'table {{ .Names }} \{{ .Ports }}' --filter expose=7000-8999/tcp | (read -r; printf \"%s\n\"; sort -k 3) | grep web | tail -1 | sed 's/.*0.0.0.0.0://g'|sed 's/->.*//g'"
// Shell output will contain a new line character at the end, remove it
PORT_INSTANCE = PORT_INSTANCE.trim()
}
}
}
I would add a stage like this, as the first stage in my pipeline.
Note that I didn't run the same shell command as you when I was testing this, so my command may have issues like un-escaped quotes.

Accessing jenkins shell variables within a k8s container

stages
{
stage('test')
{
steps
{
withCredentials([string(credentialsId: 'kubeconfigfile', variable: 'KUBECONFIG' )])
{
container('deploycontainer')
{
sh 'TEMPFILE=$(mktemp -p "${PWD}" kubeconfig.XXXXX)'
sh 'echo "${TEMPFILE}"'
}
}
}
}
}
I'm new to creating pipelines and am trying to covert a freestyle job over to a pipeline.
I'm trying to create a temp file for a kubeconfig file within the container.
I've tried everyway I could think of to access the vars for the shell and not a groovy var.
even trying the below prints nothing on echo:
sh 'TEMPFILE="foo"'
sh 'echo ${TEMPFILE}'
I've tried escaping and using double quotes as well as single and triple quote blocks.
How do you access the shell vars from within the container block/how do you make a temp file and echo it back out within that container block?
With Jenkinsfiles, each sh step runs its own shell. When each shell terminates, all of its state is lost.
If you want to run multiple shell commands in order, you can do one of two things.
You can have a long string of commands separated by semi-colons:
sh 'cmd1; cmd2; cmd3; ...'
Or you can use ''' or """ to extend the commands over multiple lines (note of course that if you use """ then groovy will perform string interpolation):
sh """
cmd1
cmd2
cmd3
...
"""
In your specific case, if you choose option 2, it will look like this:
sh '''
TEMPFILE=$(mktemp -p "${PWD}" kubeconfig.XXXXX)
echo "${TEMPFILE}"
'''
Caveat
If you are specifying a particular shebang, and you are using a multiline string, you MUST put the shebang immediately after the quotes, and not on the next line:
sh """#!/usr/bin/env zsh
cmd1
cmd2
cmd3
...
"""

How can all of a shell command be preserved when using variables in a Jenkinsfile

stage('build') {
environment {
WORKDIR="""${sh(
returnStdout: true,
script: 'pwd'
)}"""
}
steps {
timeout(time: 5, unit: 'MINUTES') {
sh "usermod -d ${WORKDIR} jenkins"
}
}
}
The result of the above gives
usermod -d /var/lib/jenkins/workspace/-www_feature_ci-integration-GWZMSYY6XHJA7QDBD4KWGXZCOVUKOBI35JMKYOQV76QXZTCYE6CA
Usage: usermod [options] LOGIN
What happened to the user jenkins that I specified, it seems to have been trimmed away from the command. Is there a way to preserve it?
When invoking a sh method with returnStdout: true, often a newline will be returned with the output. If you are assigning this output to a variable, then the resulting string value will also contain a newline character. This means your sh "usermod -d ${WORKDIR} jenkins" will be usermod -d /var/lib/jenkins/workspace/-www_feature_ci-integration-GWZMSYY6XHJA7QDBD4KWGXZCOVUKOBI35JMKYOQV76QXZTCYE6CA\n jenkins". The command will then execute without the jenkins user argument.
To fix this, you can make use of the .trim() method to remove the newline (and trailing whitespace).
This can most easily be done with either:
WORKDIR="""${sh(
returnStdout: true,
script: 'pwd'
).trim()}"""
during the assignment or:
sh "usermod -d ${WORKDIR.trim()} jenkins"
during the string interpolation.

Access a Groovy variable from within shell step in Jenkins pipeline

Using the Pipeline plugin in Jenkins 2.x, how can I access a Groovy variable that is defined somewhere at stage- or node-level from within a sh step?
Simple example:
node {
stage('Test Stage') {
some_var = 'Hello World' // this is Groovy
echo some_var // printing via Groovy works
sh 'echo $some_var' // printing in shell does not work
}
}
gives the following on the Jenkins output page:
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test Stage)
[Pipeline] echo
Hello World
[Pipeline] sh
[test] Running shell script
+ echo
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
As one can see, echo in the sh step prints an empty string.
A work-around would be to define the variable in the environment scope via
env.some_var = 'Hello World'
and print it via
sh 'echo ${env.some_var}'
However, this kind of abuses the environmental scope for this task.
To use a templatable string, where variables are substituted into a string, use double quotes.
sh "echo $some_var"
I am adding the comment from #Pedro as an answer because I think it is important.
For sh env vars we must use
sh "echo \$some_var"
You need to do something like below if a bash script is required :
Set this variable at global or local(function) level where from these can be accessible to sh script:
def stageOneWorkSpace = "/path/test1"
def stageTwoWorkSpace = "/path/test2"
In shell script call them like below
sh '''
echo ''' +stageOneWorkSpace+ '''
echo ''' +stageTwoWorkSpace+ '''
cp -r ''' +stageOneWorkSpace+'''/qa/folder1/* ''' +stageOneWorkSpace+'''/qa/folder2
'''
Make sure you start and end sh with three quotes like '''
I would like to add another scenario to this discussion.
I was using shell environment variables and groovy variables in the same script.
format='html'
for file in *.txt;
do mv -- "\$file" "\${file%.txt}.$format";
done
So here, What I have done is use \$ only for shell environment variables and use $ for groovy variables.
This is extension to #Dave Bacher's answer. I'm running multiple shell command in Groovy file & want to use output of one shell command to the next command as groovy variable. Using double quotes in shell command, groovy passes variable from one to another command but using single quotes it does not work, it returns null.
So use shell command like this in double quotes: sh "echo ${FOLDER_NAME}"
FOLDER_NAME = sh(script: $/
awk -F '=' '/CODE_COVERAGE_FOLDER/ {gsub("\"","");print$2}' ${WORKSPACE}/test.cfg
/$, returnStdout: true).trim()
echo "Folder: ${FOLDER_NAME}" // print folder name in groovy console
sh "mkdir -p ${WORKSPACE}/${FOLDER_NAME} && chmod 777 ${WORKSPACE}/${FOLDER_NAME}"

How to set variables in a multi-line shell script within Jenkins Groovy?

Suppose I have a Groovy script in Jenkins that contains a multi-line shell script. How can I set and use a variable within that script? The normal way produces an error:
sh """
foo='bar'
echo $foo
"""
Caught: groovy.lang.MissingPropertyException: No such property: foo for class: groovy.lang.Binding
You need to change to triple single quotes ''' or escape the dollar \$
Then you'll skip the groovy templating which is what's giving you this issue
I'm just putting a '\' on the end of line
sh script: """\
foo='bar' \
echo $foo \
""", returnStdout: true
This statement works on my script.

Resources