How can I define multiple agents in declarative jenkinsfile? - jenkins-pipeline

In my Jenkinsfile I want a particular stage to run on both the agents in parallel.for example:
stage('abc'){
agent {
label "dev6" && "dev7"
}
steps {
xyz()
}
}
I have two slaves with label dev6 and dev7. I want xyz() to start on both the agents dev6 and dev7 at same time parallely. What is the correct way to do it? Do i need parallel block ? from the above code it just starts the functions on one of dev6 or dev7. I tried with
label "dev6 || dev7"
label "dev6 && dev7"
but it doenst work. Can someone help??
Thanks

You need parallel on level of stages, the reason for that is actually you want this to run twice on separate agents. Unless I misunderstood you.
pipeline {
agent none
stages {
stage('Test') {
parallel {
stage('Test On dev6') {
agent {
label "dev6"
}
steps {
xyz()
}
}
stage('Test On dev7') {
agent {
label "dev7"
}
steps {
xyz()
}
}
}
}
}

Related

Jenkins function of shared library executed on wrong node

I have a simple shared library and want to call a function which creates a file.
My pipeline script looks like this:
#Library('jenkins-shared-library')_
pipeline {
agent {
node {
label 'node1'
}
}
stages {
stage('test') {
steps {
script {
def host = sh(script: 'hostname', returnStdout: true).trim()
echo "Hostname is: ${host}"
def testlib = new TestLibrary(script:this)
testlib.createFile("/tmp/file1")
}
}
}
}
}
This pipeline job is triggered by another job which runs on the built-in master node.
The stage 'test' is correctly executed on the 'node1'.
Problem: The created file "/tmp/file1" is created on the jenkins master, instead of "node1"
I also tried it without the shared library and load a groovy script
directly in a step:
pipeline {
agent {
node {
label 'node1'
}
}
stages {
stage('test') {
steps {
script {
def script = load "/path/to/script.groovy"
script.createFile("/tmp/file1")
}
}
}
}
}
This also creates the file on the master node, instead on "node1".
Is there no way of loading external libs or classes and execute them on the node where the stage is running on ? I dont want to place all the code directly into the step.
Ok I found it myself, groovy scripts run by definition always on the master node. No way to run scripts or shared-library code on a node other than master.

Parallel Stages with parallel input message in Jenkins pipe line

I have the following pipeline:
pipeline {
agent any
stages {
stage('CI') {
parallel {
stage('גמלאות') {
steps {
input message: "Pass Sanity?"
}
}
stage('וועדות') {
steps {
input message: "Pass Sanity?"
}
}
stage('מבוטח') {
steps {
input message: "Pass Sanity?"
}
}
}
}
}
}
I'm expecting to see in the UI 3 option to select in each stage. but getting only one instead.
If I will look at tradinall console then I will be able to select if to proceed or to abort.
Is there a way to get this function thru the UI?
Here is an example of the UI:
It seems that the code is correct. The problem is with the Jenkins plugin.
I mooved to work with Blueocean plugin, and now it seems to work fine:

Jenkins parallel dynamic stage does not work

I am using below code snippet for deploying code to multiple environments parallelly . For example I have two environments acpt, acpt2. The function
Deploy executes from shared library which loaded at first to below script . The problem is when it tries to deploy first environment “acpt” as its parallel stage it moves to “acpt2” environment and it never deploys to acpt environment. How to get around this issue ? Any thoughts?
stage('Deployment Distribution') {
steps {
script {
for (int i = 0; i < environments.size(); i++) {
env.environ = environments[i]
jobs["${env.environ}"] = {
node("XXXXX") {
stage("Deploy ${env.environ}") {
Deploy("${env.environ}") /// This function is written in shared library
sleep 10
}
}
}
}
parallel jobs
}
}
}
as we discuss in the comment, your expectation can be achieved like this :
In my below example with an If condition I have added sleep for the acpt2 parallel job.
node {
jobs=[:]
['acpt','acpt2'].each {
jobs["${it}"] = {
stage("deploy") {
// sleep 10 will add only in acpt2 deployment running parallel
if("${it}" == "acpt2") {
sleep 10
}
echo "deployment"
}
}
parallel jobs
}
}
I finally went with sequential deployment which is time consuming but no other option

Is there a way to move the entire post {} build section in Jenkinsfile to the global pipeline library?

I'm relatively new to Jenkins pipelines, but having implemented already a few, I've realised I need to start using jenkins shared library before I go mad.
Have already figured out how to define some repetitive steps in the library and call them with less clutter from Jenkinsfile, but not sure if the same thing can be done for the entire post build section (thought I've read about to how to define the entire pipeline in the lib and similar), as this is pretty much static end of every single pipeline code:
#Library('jenkins-shared-library')_
pipeline {
agent none
stages {
stage ('System Info') { agent any
steps { printSysInfo() }
}
stage ('Init'){ agent {label 'WinZipSE'}
steps { init('SCMroot') }
}
stage('Build') { agent any
steps { doMagic() }
}
}
// This entire 'post {}' section needs to go to a shared lib
// and be called just with a simple methed call, e.g.
// doPostBuild()
post {
always {
node ('master') {
googlechatnotification (
message: '[$BUILD_STATUS] Build $JOB_NAME $BUILD_NUMBER has finished',
url: 'id:credential_id_for_Ubuntu')
step (
[$class: 'Mailer',
recipients: 'sysadmins#example.com me#example.com',
notifyEveryUnstableBuild: true,
sendToIndividuals: true]
)
}
}
success {
node ('master') {
echo 'This will run only if successful'
}
}
failure {
node ('master') {
echo 'This will run only if failed'
}
}
// and so on
}
}
I just dunno how to syntactically achieve that. For sure, I can define the entire post build section an a lib/var like: doPotBuild.groovy
def call () {
post {...}
}
but how I will eventually call it from within my Jenkinsfile outside of that defined post {} build block section (AKA stages).
I can call it within some stage('post build){doPostBuild()}, but it won't serve the way how the true post {} section is supposed to work, e.g. it won't get executed it there was failure in one of the previous stages.
Any thoughts on that and mainly working examples?
I am not entirely if this will work as I don't use declarative pipelines, so am unsure how rigid the top level structure is. But I would revert to a script block.
#Library('jenkins-shared-library')_
pipeline {
agent none
stages {
stage ('System Info') { agent any
steps { printSysInfo() }
}
stage ('Init'){ agent {label 'WinZipSE'}
steps { init('SCMroot') }
}
stage('Build') { agent any
steps { doMagic() }
}
}
// This entire 'post {}' section needs to go to a shared lib
// and be called just with a simple methed call, e.g.
// doPostBuild()
script {
doPostBuild()
}
}

exit declarative pipeline prematurely based on script output

While I am aware of this question clean way to exit declarative Jenkins pipeline as success I am to green to understand how to put it to use (from where does the skipBuild variable come?).
I have a script that determines whether the pipeline should continue or not but I am unsure how to piece it together (I am free to construct the script as needed).
pipeline {
agent {
docker { image 'python:3-alpine' }
}
stage('Should I continue') {
steps {
python should_i_continue.py
}
when { ? == true }
stages {
...
}
}
}
I am aware that the capabilities increase tenfold if I use a scripted pipeline but I wonder if it is possible to do what I want with a declarative one?
You can use any custom variable, which you will set as true|false based on some condition in the steps of your pipeline and all stages that need to be executed based on that condition have to have following format:
stage('Should Continue?') {
setBuildStatus("Build complete", "SUCCESS");
when {
expression {skipBuild == true }
}
}
In other words to provide you a bit clean picture, check this abstract example:
node {
skipBuild = false
stage('Checkout') {
...
your checkout code here
...
}
stage('Build something') {
...
some code goes here
skipBuild = true
...
}
stage('Should Continue?') {
setBuildStatus("Build complete", "SUCCESS");
when {
expression {skipBuild == true }
}
}
}

Resources