Not able to spawn threads in Jenkins groovy pipeline - multithreading

I want to run multiple threads in my groovy pipeline. Here is my pipeline
node{
List<Thread> cleanupThreads = new ArrayList<>(100);
"""1 2 3 4 5 6""".split().each{
def th = new Thread({
Random rand = new Random()
def wait = (long)(rand.nextDouble() * 1000)
this.sleep wait
println "Running Thread ${this.getName()}"
})
cleanupThreads.add(th)
}
cleanupThreads.each {it.start() }
cleanupThreads.each {it.join() }
}
When i run it, i don't see any "Running Thread ${this.getName()}" output line in console
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/test_jobs/multithreaded_groovy_pipeline
[Pipeline] {
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Any idea what wrong here? Does Jenkins pipeline support multi-threading?

I'm not sure why you want to code groovy multithread functionality into pipeline script which is not advisable. If you want to run different jobs in parallel you can use Parallel stage functionality. Please find below sample
pipeline {
agent any
stages {
stage ("Test Stage"){
steps {
parallel(
job1: {
echo "Inside 1st Job"
},
job2: {
echo "Inside 2nd Job"
},
job3: {
echo "Inside 3rd Job"
}
)
}
}
}
}
Output

Related

How to get session data in jenkins delarative piepline

I dont want to used from CurrentBuild or CurrentUser because this return the user information that who build the job , but i wnat to get the user information that login to jenkins.
for example the job X run by timer and the one user will aborted this , i want to found that which user aborted this job .
you can use the below code. pay attention when you want to execute this code you have to permit to run these methods by go to " manage Jenkins/in process script Approval" and approve them to be executable. by using this code you can get whom aborted Jenkins pipeline not only in manually running job also in running by timer.
pipeline {
agent any
triggers{cron("*/1 * * * *")}
stages {
stage('Hello') {
steps {
sleep(20000)
echo 'Hello World'
}
}
}
post{
aborted{
script{
def causee = ''
def actions = currentBuild.getRawBuild().getActions(jenkins.model.InterruptedBuildAction)
for (action in actions) {
def causes = action.getCauses()
// on cancellation, report who cancelled the build
for (cause in causes) {
causee = cause.getUser().getDisplayName()
cause = null
}
causes = null
action = null
}
actions = null
echo causee
}
}
}
}

How to perform actions for failed builds in Jenkinsfile

Is there a way to perform cleanup (or rollback) if the build in Jenkinsfile failed?
I would like to inform our Atlassian Stash instance that the build failed (by doing a curl at the correct URL).
Basically it would be a post step when build status is set to fail.
Should I use try {} catch ()? If so, what exception type should I catch?
Since 2017-02-03, Declarative Pipeline Syntax 1.0 can be used to achieve this post build step functionality.
It is a new syntax for constructing Pipelines, that extends Pipeline with a pre-defined structure and some new steps that enable users to define agents, post actions, environment settings, credentials and stages.
Here is a sample Jenkinsfile with declarative syntax:
pipeline {
agent label:'has-docker', dockerfile: true
environment {
GIT_COMMITTER_NAME = "jenkins"
GIT_COMMITTER_EMAIL = "jenkins#jenkins.io"
}
stages {
stage("Build") {
steps {
sh 'mvn clean install -Dmaven.test.failure.ignore=true'
}
}
stage("Archive"){
steps {
archive "*/target/**/*"
junit '*/target/surefire-reports/*.xml'
}
}
}
post {
always {
deleteDir()
}
success {
mail to:"me#example.com", subject:"SUCCESS: ${currentBuild.fullDisplayName}", body: "Yay, we passed."
}
failure {
mail to:"me#example.com", subject:"FAILURE: ${currentBuild.fullDisplayName}", body: "Boo, we failed."
}
}
}
The post code block is what handles that post step action
Declarative Pipeline Syntax reference is here
I'm currently also searching for a solution to this problem. So far the best I could come up with is to create a wrapper function that runs the pipeline code in a try catch block. If you also want to notify on success you can store the Exception in a variable and move the notification code to a finally block. Also note that you have to rethrow the exception so Jenkins considers the build as failed. Maybe some reader finds a more elegant approach to this problem.
pipeline('linux') {
stage 'Pull'
stage 'Deploy'
echo "Deploying"
throw new FileNotFoundException("Nothing to pull")
// ...
}
def pipeline(String label, Closure body) {
node(label) {
wrap([$class: 'TimestamperBuildWrapper']) {
try {
body.call()
} catch (Exception e) {
emailext subject: "${env.JOB_NAME} - Build # ${env.BUILD_NUMBER} - FAILURE (${e.message})!", to: "me#me.com",body: "..."
throw e; // rethrow so the build is considered failed
}
}
}
}
I manage to solve it by using try:finally. In case of this stage raises an error the stage will be red and finally run the code but if the stage is okay, the stage will be green and finally will run too.
stage('Tests'){
script{
try{
sh """#!/bin/bash -ex
docker stop \$(docker ps -a -q)
docker rm \$(docker ps -a -q)
export DOCKER_TAG=${DOCKER_TAG}
docker-compose -p ${VISUAL_TESTING_PROJECT_TAG} build test
docker-compose -p ${VISUAL_TESTING_PROJECT_TAG} up --abort-on-container-exit --exit-code-from test
"""
}
finally{
sh """#!/bin/bash -ex
export DOCKER_TAG=${DOCKER_TAG}
docker-compose -p ${VISUAL_TESTING_PROJECT_TAG} down
"""
}
}
}

How can we run different task in different thread in gradle

I was trying to find a solution to run different task in different threads (depends/independents)
I have scenario where I need to run one task (which internally runs a server) in different thread before running another task (test, depends on above server) in gradle, after 2nd task completed I need to kill first task.
Again, same as above scenario, run another set of server/test/kill tasks.
task exp{
doFirst{
run1stServerTask.execute()
}
def pool = Executors.newFixedThreadPool(5)
try {
def defer = { closure -> pool.submit(closure as Callable) }
defer {
run1stTest.execute()
// After tests are finished, kill 1st server tasks
}
defer {
run2ndServerTask.execute()
}
defer {
run2ndTest.execute()
// After tests are finished, kill 2nd server tasks
}
}
finally {
pool.shutdown()
}
}
Hope, All above make sense... I am open for another approach if its possible in build.gradle.

Gradle: Why Exec-derived tasks does not see custom project properties?

Say, we have following property set in build.gradle:
ext.PING = "PONG"
Now we create to tasks:
task ping(type: Exec) {
commandLine 'echo', project.hasProperty('PING')
}
task pong() {
doLast {
println project.hasProperty('PING')
}
}
If will run gradle pong we'll see true printed, if we'll run gradle ping we won't.
The question is: How can we resolve such propeties at the moment we are forming commandLine command? The thing is that in doLast or doFirst we'll see evaluated properties but this does not help - commandLine should be formed earlier.
Since the forming of command line arguments happens during the configuration phase, you have to check, whether your ext.PING = "PONG" goes before the ping task. For example, I've tested it with simple build script like:
ext.PING = "PONG"
task ping(type: Exec) {
commandLine 'echo', project.hasProperty('PING')
}
The result of echo is true, but for:
task ping(type: Exec) {
commandLine 'echo', project.hasProperty('PING')
}
ext.PING = "PONG"
Result is false.
You have to check, have you set this property before the ping task configuration. As for doFirst and doLast, they are executed during execution phase, that means, that all configurations are done and property exists.

Jenkins Groovy Remote Control Plugin - example

I can't connect to Jenkins and execute script via Groovy Remote Plugin.
I found only this documentation: https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Remote+Control+Plugin
My example:
class GroovyDemo {
static void main(def args) {
def transport = new HttpTransport("http://my-jenkins/plugin/groovy-remote/")
def remote = new RemoteControl(transport)
//1
def result1 = remote {
return jenkins.version.value
}
println "Jenkins version was ${result1}."
//2
def result2 = remote {
return Jenkins.getInstance().getItems().size()
}
println "Jobs count: ${result2}."
}
}
I get the result:
Jenkins version was 1.580.3.
0
Why I get zero as number of jobs despite I have many jobs on my Jenkins?
Thanks
You used different variable names for the Jenkins instance - lower case "jenkins" for the successful call and upper case "Jenkins" for the unsuccessful one.

Resources