Jenkins pipeline shell output not as expected - jenkins

can i know which part i am doing wrong. The file not in server but however, every time i execute it goes to true statement
pipeline {
agent any
stages{
stage('Test') {
steps{
script{
hasWar = sh(returnStdout: true, script: 'sshpass -p ${password} ssh ${username}#123.12.32.33 \'if [ -f /home/nityo/warFile1.war ]; then echo true; else echo false; fi\'')
if (hasWar) {
echo 'Has war'
} else {
echo 'No war files'
}
}
}
}
}
}

Assuming the script part echos true or false to the console in the expected conditions, there is one more thing you didn't take into account. In Groovy, every non-empty string evaluates to true when used in the context of the boolean variable. It's called Groovy Truth.
If you want to evaluate string value false to an appropriate boolean value, you have to use toBoolean() method that returns false if the string value stores false literal, and true if it stores true literal.
https://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/String.html#toBoolean()
Also, consider adding trim() to the sh() step so all whitespaces are trimmed from the output when you store it under the hasWar variable.
pipeline {
agent any
stages{
stage('Test') {
steps{
script{
hasWar = sh(returnStdout: true, script: 'sshpass -p ${password} ssh ${username}#123.12.32.33 \'if [ -f /home/nityo/warFile1.war ]; then echo true; else echo false; fi\'').trim()
if (hasWar.toBoolean()) {
echo 'Has war'
} else {
echo 'No war files'
}
}
}
}
}
}

Related

Jenkins script how to compare two string variables

def pname = "netstat -ntlp|grep 8080|awk '{printf \$7}'|cut -d/ -f2"
sh "echo $pname" \ java
if ("java".equals(pname)) { sh "echo 1111" }
The process corresponding to port 8080 is a java process, and the 2nd line print "java". But the body of the if statement just doesn't execute.
You seem to be not executing the command correctly. Please refer to the following sample. Please note the returnStdout: true to return output of the command.
pipeline {
agent any
stages {
stage('Test') {
steps {
script {
def pname = sh(returnStdout: true, script: "netstat -ntlp|grep 8080|awk '{printf \$7}'|cut -d/ -f2").trim()
if (pname == "java") {
echo "echo 1111"
}
}
}
}
}
}
try
"==" for equal
or you can read doc.
https://groovy-lang.org/operators.html#_relational_operators

Access a Groovy variable within shell step in Jenkins pipeline

SSHUER in stage one prints as required. But in stage two it doesn't print and gives me a null value. All three attempt statements in stage two are not working. I can't use script block as I have some special characters in the actual code. Any suggestions as to how to fetch the value of SSHUSER in stage two.
def SSHUSER
environment {
if(params.CLOUD == 'google') {
SSHUSER = "test1"
} else if (params.CLOUD == 'azure') {
SSHUSER = "test2"
}
}
pipeline {
stage('stage one') {
steps {
echo "first attempt '${SSHUSER}'"
}
}
stage('stage two') {
steps {
sh '''#!/bin/bash
echo "first attempt '${SSHUSER}'"
echo "second attempt \${SSHUSER}"
echo "thrid attempt \$SSHUSER"
if ssh \${SSHUSER}#$i 'test -e /tmp/test'";
then
echo "$i file exists "
fi
'''
}
}
}
your usage of the environment block is a bit weird, it should reside inside the pipeline block and variables should be initialized inside the environment block.
If it is defined outside the variables will not be passed to the shell script as environment variables.
If you want to use the environment block inside the `pipeline' block just define the parameters (as strings) you want and they will be available for all stages, and they will be passed as environment variables for the shell.
For example:
pipeline {
agent any
parameters{
string(name: 'CLOUD', defaultValue: 'google', description: '')
}
environment {
SSHUSER = "${params.CLOUD == 'google' ? 'test1' : 'test2'}"
}
stages {
stage('stage one') {
steps {
echo "first attempt '${SSHUSER}'"
}
}
stage('stage two') {
steps {
sh '''#!/bin/bash
echo "first attempt '${SSHUSER}'"
echo "second attempt \${SSHUSER}"
echo "thrid attempt \$SSHUSER"
if ssh \${SSHUSER}#$i 'test -e /tmp/test'";
then
echo "$i file exists "
fi
'''
}
}
}
}
If you don't want to use the environment block or mange the parameters by yourself you can do it outside the pipeline block using Global variables but then they will not be passed environment variables and you will need to use string interpolation (""" instead of ''') to calculate the values when passing the command to the shell:
SSHUSER = ''
if(params.CLOUD == 'google') {
SSHUSER = "test1"
} else if (params.CLOUD == 'azure') {
SSHUSER = "test2"
}
pipeline {
agent any
parameters{
string(name: 'CLOUD', defaultValue: 'google', description: 'Bitbucket Payload', trim: true)
}
stages {
stage('stage one') {
steps {
echo "first attempt '${SSHUSER}'"
}
}
stage('stage two') {
steps {
sh """#!/bin/bash
echo "first attempt '${SSHUSER}'"
echo "second attempt ${SSHUSER}"
echo "thrid attempt $SSHUSER"
if ssh ${SSHUSER}#\$i 'test -e /tmp/test'";
then
echo "\$i file exists "
fi
"""
}
}
}
}

jenkins Pipeline Script: How to get the return value from shell script

I have a jenkins pipeline where I am executing different scripts at different stages. However in one stage I want to get the output of the stage to a variable where I want to pass that variable as an input to next stage . Here is my code in Jenkinsfile
timestamps
{
node('cf_slave')
{
checkout scm
stage('Download HA image from GSA')
{
withCredentials(usernamePassword(credentialsId: 'ssc4icp_GSA', usernameVariable: 'GSA_USERNAME', passwordVariable: 'GSA_PASSWORD')
{
environment {
script {
OUTPUT = """${sh(
returnStdout: true,
script: 'bash jenkins/try_install.sh $VAR_ABC'
)}"""
echo $OUTPUT
}
}
}
}
}
}
Here i am getting syntax error. I want to get the OUTPUT in OUTPUT variable and pass that to next stage. Please help me how to do that in a correct way
When referencing variable outside of a string you should not us a dollar sign ($). The code should be (including changes suggested by Matt):
timestamps
{
node('cf_slave')
{
checkout scm
stage('Download HA image from GSA')
{
withCredentials(usernamePassword(credentialsId: 'ssc4icp_GSA', usernameVariable: 'GSA_USERNAME', passwordVariable: 'GSA_PASSWORD'))
{
environment {
script {
OUTPUT = sh returnStdout: true,
script: "bash jenkins/try_install.sh $VAR_ABC"
echo OUTPUT
}
}
}
}
}
}

How to use Jenkins Pipeline global variable on another stages?

I have defined global variable in Jenkins pipeline
def BUILDNRO = '0'
pipeline { ...
Then i manipulate variable with shell script to enable running builds parallel by using job build number as identifier so we don't mix different docker swarms.
stage('Handle BUILD_NUMBER') {
steps {
script {
BUILDNRO = sh( script: '''#!/bin/bash
Build=`echo ${BUILD_NUMBER} | grep -o '..$'`
# Check if BUILD first character is 0
if [[ $Build:0:1 == "0" ]]; then
# replace BUILD first character from 0 to 5
Build=`echo $Build | sed s/./5/1`
fi
echo $Build
''',returnStdout: true).trim()
}
}
}
i get value out from previos stage and trying to get global variable on next stage
stage('DOCKER: Init docker swarm') {
steps {
echo "BUILDNRO is: ${BUILDNRO}" --> Value is here.
sh '''#!/bin/bash
echo Buildnro is: ${BUILDNRO} --> This is empty.
...
}
}
This will out give global variable empty. why? in previous stage there was value in it.
EDIT 1.
Modified code blocks to reflect current status.
I managed to figure it out. Here is solution how i managed to did it.
BUILDNRO is groovy variable and if wanting to used in bash variable it have to pass using withEnv. BUILD_NUMBER in first stage is bash variable hence it can be used directly script in first stage.
def BUILDNRO = '0'
pipeline {
....
stages {
stage('Handle BUILD_NUMBER') {
steps {
script {
BUILDNRO = sh( script: '''#!/bin/bash
Build=`echo ${BUILD_NUMBER} | grep -o '..$'`
''',returnStdout: true).trim()
}
}
}
stage('DOCKER: Init docker swarm') {
steps {
dir("prose_env/prose_api_dev_env") {
withEnv(["MYNRO=${BUILDNRO}"]) {
sh(returnStdout: false, script: '''#!/bin/bash
echo Buildnro is: ${MYNRO}`
'''.stripIndent())
}
}
}
}
}
}
If you are using single quotes(```) in the shell module, Jenkins treats every variable as a bash variable. The solution is using double quotes(""") but then if you made bash variable you have to escape it. Below an example with working your use case and escaped bash variable
pipeline {
agent any
stages {
stage('Handle BUILD_NUMBER') {
steps {
script {
BUILDNRO = sh(script: 'pwd', returnStdout: true).trim()
echo "BUILDNRO is: ${BUILDNRO}"
}
}
}
stage('DOCKER: Init docker swarm') {
steps {
sh """#!/bin/bash
echo Buildnro is: ${BUILDNRO}
variable=world
echo "hello \${variable}"
sh """
}
}
}
}
output of the second stage:
Buildnro is: /var/lib/jenkins/workspace/stack1
hello world

Store current workspace path in variable for a later stage

I am using the declarative syntax for my pipeline, and would like to store the path to the workspace being used on one of my stages, so that same path can be used in a later stage.
I have seen I can call pwd() to get the current directory, but how do I assign to a variable to be used between stages?
EDIT
I have tried to do this by defining by own custom variable and using like so with the ws directive:
pipeline {
agent { label 'master' }
stages {
stage('Build') {
steps {
script {
def workspace = pwd()
}
sh '''
npm install
bower install
gulp set-staging-node-env
gulp prepare-staging-files
gulp webpack
'''
stash includes: 'dist/**/*', name: 'builtSources'
stash includes: 'config/**/*', name: 'appConfig'
node('Protractor') {
dir('/opt/foo/deploy/') {
unstash 'builtSources'
unstash 'appConfig'
}
}
}
}
stage('Unit Tests') {
steps {
parallel (
"Jasmine": {
node('master') {
ws("${workspace}"){
sh 'gulp karma-tests-ci'
}
}
},
"Mocha": {
node('master') {
ws("${workspace}"){
sh 'gulp mocha-tests'
}
}
}
)
}
post {
success {
sh 'gulp combine-coverage-reports'
sh 'gulp clean-lcov'
publishHTML(target: [
allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: false,
reportDir: 'test/coverage',
reportFiles: 'index.html',
reportName: 'Test Coverage Report'
])
}
}
}
}
}
In the Jenkins build console, I see this happens:
[Jasmine] Running on master in /var/lib/jenkins/workspace/_Pipelines_IACT-Jenkinsfile-UL3RGRZZQD3LOPY2FUEKN5XCY4ZZ6AGJVM24PLTO3OPL54KTJCEQ#2
[Pipeline] [Jasmine] {
[Pipeline] [Jasmine] ws
[Jasmine] Running in /var/lib/jenkins/workspace/_Pipelines_IACT-Jenkinsfile-UL3RGRZZQD3LOPY2FUEKN5XCY4ZZ6AGJVM24PLTO3OPL54KTJCEQ#2#2
The original workspace allocated from the first stage is actually _Pipelines_IACT-Jenkinsfile-UL3RGRZZQD3LOPY2FUEKN5XCY4ZZ6AGJVM24PLTO3OPL54KTJCEQ
So it doesnt look like it working, what am I doing wrong here?
Thanks
pipeline {
agent none
stages {
stage('Stage-One') {
steps {
echo 'StageOne.....'
script{ name = 'StackOverFlow'}
}
}
stage('Stage-Two'){
steps{
echo 'StageTwo.....'
echo "${name}"
}
}
}
}
Above prints StackOverFlow in StageTwo for echo "${name}"
You can also use sh "echo ${env.WORKSPACE}" to get The absolute path of the directory assigned to the build as a workspace.
You could put the value into an environment variable like described in this answer
CURRENT_PATH= sh (
script: 'pwd',
returnStdout: true
).trim()
Which version are you running? Maybe you can just assign the WORKSPACE variable to an environment var?
Or did i totally misunderstand and this is what you are looking for?

Resources