I have a Jenkins step as below.
stage('Initialize Namespace') {
when {
expression { params.initNS }
}
steps {
script {
setBuildStatus(processing_test_context, 'Initializing namespace', 'PENDING');
}
sh """ #!/bin/bash
set -e
namespaces="\${kubectl get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{\"\n\"}{end}'}"
echo "\${namespaces}"
if [[ \$namespaces =~ \$NAMESPACE ]]
then
kubectl create namespace $NAMESPACE || true
else
echo "The namespace already exists. Will be using the same"
fi
"""
}
How do I store the output of the command kubectl get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' in a variable? Currently, the error I am getting is ${kubectl get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{" "}{end}'}: bad substitution.
How do I escape " in the command?
Here is a working shell block for the script you provided.
sh"""
#!/bin/bash
namespaces=\$(kubectl get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{\"\\n\"}{end}')
echo "\$namespaces"
if [[ \$namespaces =~ \$NAMESPACE ]]
then
echo "Creating Namespace"
kubectl create namespace \$NAMESPACE || true
else
echo "The namespace already exists. Will be using the same"
fi
"""
If you don't need variable substitution(String interpolation) in your sh block you can use 3 single quotes rather than using double quotes which will allow you to get rid of multiple escape characters.
On a different note, the following is a different way to get what you need. Here $NAMESPACE has to be not empty always.
sh'''
#!/bin/bash
NS=$(kubectl get namespace $NAMESPACE --ignore-not-found);
echo $NS
if [[ -z "$NS" ]]; then
echo "Creating namespace $NAMESPACE"
kubectl create namespace $NAMESPACE || true
else
echo "The namespace already exists. Will be using the same"
fi
'''
Related
I am trying to SSH into a machine from a Jenkins Execute shell, check to see if a file exists on the machine and if it does then fail the shell. I have the following code however I can seem to get Jenkins to recognize that the output of echo is "yes" or no"
Please let me know what you think...
sshpass -p ${ServerNodePw} ssh -T -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ${ServerNodeUser}#${ServerNodeIP} << EOSSH
(ls /Volumes/ServerHD/Users/username/Desktop/JenkinsVMbuild.lock && echo yes) || echo no
2>/dev/null 1>/dev/null
echo "$?"
if [ "$?" = yes ]
then
echo "File found"
exit 1
currentBuild.result = 'FAILURE'
else
echo "File not found"
fi
EOSSH
The value of $? is the exit status of the last executed command (or pipeline). In your case, it would always expand to 0.
You can use command substitution instead if you want to store the echoed string in a variable.
You will also need to properly escape (or quote) the script in your here document. Otherwise $var will be substituted by the caller before passing the script to ssh.
Doing Jenkins Declarative Pipeline,
So I'm looking for "Post" action that will send e-mail only if there is 1 file which exists and is biggger then 0kb.
Very similiar to bash function : if [-s]
I can do that in a bash script, but how is done in jenkins for POST BUILD:
See how is made in bash:
if [ -s "$file" ]
then
/usr/bin/mutt -s "Master Failed 3Days" $emails -a $file < /dev/null
exit 1
else
echo "$file is empty."
/usr/bin/mutt -s "Master Success 3Days" $emails_success -a $file < /dev/null
exit 0
fi
This approach is working:
1. You are doing a global variable with your shell script in stage
result = sh(script: '''
if [ -s "$file" ]
then
/usr/bin/mutt -s "Master Failed 3Days" $emails -a $file < /dev/null
echo 'found'
else
echo "$file is empty."
/usr/bin/mutt -s "Master Success 3Days" $emails_success -a $file < /dev/null
echo 'not'
fi
''', returnStdout: true).trim()
You are adding post definitions
post {
always {
script {
if (result.contains('found')) {
<your logic to sending email>
}
}
}
}
I'm trying to get the result of a command into a boolean variable in my Jenkinsfile. The command is: curl -o/dev/null -sfI "$url", which can be used in sh like this:
if ( curl -o/dev/null -sfI "$url" ); then
echo "URL exists"
else
echo "URL does not exist"
fi
So, I need this condition in my jenkinsfile but I don't know how to recreate it. This is what I've tried:
def fileAlreadyExists = sh(
script: "curl -o/dev/null -sfI \"$url\"",
returnStdout: true
)
But seems to return false always.
Your command does not return any output due to -o /dev/null switch. If you want to catch exit code you would have to set returnStatus and not returnStdout option, like:
def fileAlreadyExists = sh(
script: "curl -o/dev/null -sfI \"$url\"",
returnStatus: true
)
Alternatively you could extend your Bash command to do echo $? after the curl command to echo last command exit code:
def fileAlreadyExists = sh(
script: "curl -o/dev/null -sfI \"$url\"; echo \\\$?",
returnStdout: true
) as Integer // explicit casting needed, because it returns String
The variable fileAlreadyExists stores an integer value, so you can use it in if () statement (Groovy evalutes if (0) to false, so if you expect 0 exit code then it is good idea to make this comparison explicit like:
if (fileAlreadyExists == 0) { /* exists */ } else { /* not exist */ }
As a side note: remember to escape \ if you want to pass it to the sh command - Jenkins strips single escape character, so if you want to pass e.g. double quote the underlying script then you have to escape it in the following way: \\\".
I am having problems figuring out how to pass some variables into the parallel runs in the Jenkins groovy script below:
#!/usr/bin/env groovy
def call(version, project) {
sh '''#!/bin/bash
[[ ! -e ${WORKSPACE}/target/rpm/${project}/RPMS/ ]] && mkdir -p ${WORKSPACE}/target/rpm/${project}/RPMS/
(( $(ls ${WORKSPACE}/target/rpm/${project}/RPMS/*.rpm | wc -l) != 0 )) && rm ${WORKSPACE}/target/rpm/${project}/RPMS/*.rpm
cd ${WORKSPACE}/scripts/fpm_requirements && bundle install && bundle show fpm
'''
parallel (
"package foo": {
sh '''#!/bin/bash
export PATH=$PATH:~/bin:~/.gem/ruby/gems
cd ${WORKSPACE}/scripts/fpm_requirements
echo Project is ${project}
echo Version is ${version}
echo Iteration is $(echo ${version} | cut -d . -f 3)
'''
},
"package bar": {
sh '''#!/bin/bash
export PATH=$PATH:~/bin:~/.gem/ruby/gems
cd ${WORKSPACE}/scripts/fpm_requirements
echo Project is ${project}
echo Version is ${version}
echo Iteration is $(echo ${version} | cut -d . -f 3)
'''
}
)
}
So the version and project variables are populated in the first shell that is called but when they hit the two parallel runs they are not being pulled in.
I have tried a few different options to pass them in but none have worked.
Does anyone have any relevant ideas that might help?
You should change the ''' to """. In Groovy, string inside single/triple quote won't trigger string interpolation, but string inside single/triple double quote will do that.
So the ${version} and ${project} in your Shell script will be treated as variable from Shell context, but actually they are exist in Groovy context.
More about Groovy String at here, Below option 2 more suitable for your issue.
Option 1) using "" or """
"package foo": {
sh """#!/bin/bash
export PATH=\$PATH:~/bin:~/.gem/ruby/gems
cd \${WORKSPACE}/scripts/fpm_requirements
echo Project is ${project}
echo Version is ${version}
echo Iteration is \$(echo ${version} | cut -d . -f 3)
"""
},
"package bar": {
sh """#!/bin/bash
export PATH=\$PATH:~/bin:~/.gem/ruby/gems
cd \${WORKSPACE}/scripts/fpm_requirements
echo Project is ${project}
echo Version is ${version}
echo Iteration is \$(echo ${version} | cut -d . -f 3)
"""
}
Attention: need to escape the $ ahead of ${WORKSPACE} and $(echo ..), because we hope $ be kept after interpolation.
Option 2) using ' or ''' and inject version and project into Environment Variables of Shell context.
def call(version, project) {
env.version=version
env.project=project
// Groovy env api used to inject groovy value into environment variable
// so that you can refer groovy value later in shell script
// still use ''' in following code, no need to change
...
The following doesn't work in my Dockerfile:
RUN if $SSH_PRIVATE_KEY -eq ""; then echo "SSH key is not set, aborting"; exit 1; else echo "SSH key is set"; fi
I get the following error:
Step 4/15 : RUN if $SSH_PRIVATE_KEY -eq ""; then echo "SSH key is not set, aborting"; exit 1; else echo "SSH key is set"; fi
---> Running in 3bd29320f0e3
/bin/sh: -eq: command not found
I would like to check if the $SSH_PRIVATE_KEY variable contains anything at all.
Add quotes around your variable (if it might have spaces in it) and simply use = operator for string comparison.
In Bourne shell it would be :
if [ "$SSH_PRIVATE_KEY" = "" ]; then echo "SSH key is not set, aborting"; exit 1; else echo "SSH key is set"; fi
You have to put square brackets there.. Otherwise to test an empty variable is better -z switch.
RUN if [ -z "$SSH_PRIVATE_KEY" ]; then echo "SSH key is not set, aborting"; exit 1; else echo "SSH key is set"; fi