How to pass variable between jenkins pipeline from shell script conditional result - jenkins

in the first stage, i've shell script to check directory in the remote server and the results will be sent to the next stage. I have tried the following way but it seems the variable is not read in the execute stage, is there another proper way?
pipeline {
agent any
stages
{
stage("validate")
{
steps
{
sh '''
dir_path="/home/servicenamedir"
ssh username#host bash -c "'
if [ -d "$dir" ]
then
checkdir="true"
else
checkdir="false"
fi
'"
'''
}
}
stage("execute")
{
steps
{
sh '''
if [ "$checkdir" == "true" ]
then
echo "directory already exist, please double check";
exit;
elif [ "$checkdir" == "false" ]
then
echo "execute ./install-service.sh"
fi
'''
}
}
}

create variable
def var
use options returnStdout: true. And parse output
Def var = sh ( script " ls -la", returnStdout: true).split("\n")
use var in stage 'execute'
If (var[0] =="true"){...} else {...}
https://www.jenkins.io/doc/pipeline/steps/workflow-durable-task-step/

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
"""
}
}
}
}

How to change global variable in Jenkins mix pipeline?

I have a script like this [ code below ]
At the end of the stage block under node I get the desired result, but inside pipeline block I am not getting the changed value, instead it is giving me null. I tried all possible ways. Please let me know is there a way to get the changed value inside pipeline block.
def AGENT_LABEL
node('k8s-agent-large-mem-oci') {
stage('Checkout and set agent'){
sh '''
if [ ! -z "`echo ${ADE_LABEL} | grep "BRONZE"`" ]
then
AGENT_LABEL="DB_OCI"
fi
if [ ! -z "`echo ${ADE_LABEL} | grep "SILVER"`" ]
then
AGENT_LABEL="DB_OCI"
fi
if [ ! -z "`echo ${ADE_LABEL} | grep "FUSIONAPPS_11.13"`" ]
then
AGENT_LABEL="DB_ARU"
fi
echo "Final Agent Label is $AGENT_LABEL"
'''
}
}
pipeline {
agent {
label "${AGENT_LABEL}"
}
stages {
stage ('Git Copy to DB VM') {
steps {
echo "Running in ${AGENT_LABEL}"
build job: 'Git_Scripts_DB'
}
}
}
}
Before giving you a pipeline example, where do you set ${ADE_LABEL}?
Try this one:
pipeline {
agent none
environment {
AGENT_LABEL = """${sh(
returnStdout: true,
script: 'if [[ ! -z $(grep -E "BRONZE|SILVER" <<< "${ADE_LABEL}") ]]
then
AGENT_LABEL="DB_OCI"
fi
if [[ ! -z $(grep -E "FUSIONAPPS_11.13" <<< "${ADE_LABEL}") ]]
then
AGENT_LABEL="DB_ARU"
fi
echo "Final Agent Label is ${AGENT_LABEL}"'
).trim()}"""
}
stages {
stage ('Git Copy to DB VM') {
agent {
label "${AGENT_LABEL}"
}
steps {
echo "Running in ${AGENT_LABEL}"
build job: 'Git_Scripts_DB'
}
}
}
}

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

when use jenkins pipeline shared library ,the function parameters in sh ''' ''' will be null

/var/coverityCompile.groovy
#!groovy
def java(String DIR) {
compile_dir="${WORKSPACE}/${DIR}"
echo "complie_dir:${compile_dir}"
sh "echo complie_dir:${compile_dir}"
sh '''
echo complie_dir:${compile_dir}
'''
}
/src/org/coverity/JenkinsFile
#!groovy
#Library('shared-library') _
pipeline {
agent { label 'dev_ci_env_dm' }
stages {
stage('coverity'){
steps{
script{
coverityCompile.java("DM")
}
}
}
}
}
The Jenkins log will be:
complie_dir:/home/ci/workspace/test_coverity/DM
[Pipeline] sh
[test_coverity] Running shell script
+ echo complie_dir:/home/ci/workspace/test_coverity/DM
complie_dir:/home/ci/workspace/test_coverity/DM
complie_dir:
when I use echo "complie_dir:${compile_dir}"
and sh "echo complie_dir:${compile_dir}"
the result will be printed as expected. But, when I use
sh '''
echo complie_dir:${compile_dir}
'''
The result of ${compile_dir} will be null.
Now, I want to execute multiline of shell,so is there any other way to replace sh ''' '''?

Resources