How to change global variable in Jenkins mix pipeline? - jenkins

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

Related

Jenkins escaped the string variables I defined

#!groovy
def call(Map map) {
pipeline {
//agent{
// node{
// label 'jenkins-slave'
// }
//}
agent any
environment {
APP_NAME = "${map.app}"
K8S_NS = "${map.namespace}"
DEFAULT = "Running"
}
stages {
stage('Output Pod Log') {
steps {
sh '''for (( i=1;i<=5;i=i+1 ))
do
POD_STATUS=$(kubectl get pods -n ${K8S_NS} | grep "${APP_NAME}" | awk '{print $3}')
POD=$(kubectl get pod -o wide -n ${K8S_NS} |grep "${APP_NAME}" |grep "0/1" |awk '{print $1}'|head -n 1)
if [[ "$POD" == "" ]]; then
break
elif [[ "$POD_STATUS" != "$DEFAULT" ]]; then
kubectl get pod -o wide -n ${K8S_NS} |grep "${APP_NAME}"
sleep 5
continue
elif [[ "$POD" != "" ]] && [[ "$POD_STATUS" == "$DEFAULT" ]]; then
timeout 70 kubectl logs -f $POD -n ${K8S_NS}
timeout 10 kubectl rollout status deployment ${APP_NAME} -n ${K8S_NS}
break
else
break
fi
done'''
}
}
}
}
This is one of my jenkinsfile sections, which is trying to filter out the newly created pod containers by the script content. And output the corresponding logs to the Jenkins console, but currently Jenkins seems to have added escaped characters to the Default variable string I defined. Log content output:
enter image description here
I hope that you can help me.

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

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

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/

Not able to read the item from list using for loop in the jenkins pipeline stage

Running one linux command and saving the ouput of the command as list and then reding the list item one by one.
stage('NAMESPACE Availability') {
node ('master'){
withEnv(["KUBECONFIG=${JENKINS_HOME}/.kube/config"]){
NS_list = sh (
script: '''kubectl get ns | awk '{print \$1}' | awk '{\$1=\$1; print "[\\x27" $0 "\\x27]"}' FS='\n' OFS="','" RS='' ''',
returnStdout: true
).trim()
echo "${NS_list}"
NS(NS_list)
}
}
}
def NS(list) {
for (i in list) {
echo "${i}"
if ( i == "${NAME_SPACE}" ) {
sh "kubectl delete all --all -n '${NAME_SPACE}' && kubectl delete '${NAME_SPACE}' "
break;
}
}
}
Rather then reading as Item its reading as character , Lets say if command output is ['NAME','b2','b6','b7','cert-manager','default'] its reading as below output.
[Pipeline] echo
[
[Pipeline] echo
'
[Pipeline] echo
N
[Pipeline] echo
A
[Pipeline] echo
M
[Pipeline] echo
E
[Pipeline] echo
[Pipeline] echo
'
[Pipeline] echo
,
[Pipeline] echo
'
I solved my problem as per below changes. Rather then using for(loop).. i used ".contains"
stage('NAMESPACE Availability') {
node ('master'){
withEnv(["KUBECONFIG=${JENKINS_HOME}/.kube/config"]){
NS_list = sh (
script: '''kubectl get ns | awk '{print \$1}' ''',
returnStdout: true
).trim()
def lst = "${NS_list}";
NS = (lst.contains( "${NAME_SPACE}" ));
echo "${NS}"
if ( NS == true ) {
sh "kubectl delete all --all -n ${NAME_SPACE} "
}
else {
sh "kubectl create ns ${NAME_SPACE}"
}
}
You haven't declared NS_list, that will store everything as a string. Add def NS_list = [] at the beginning of your pipeline

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

Resources