Unable to get output of Failing Jenkins jobs to pipeline's console - jenkins

Unable to get output of Failing Jenkins jobs to pipeline's console
I'm calling several jobs from my pipeline. Below is an example job 'printuser' that gets triggered from my pipeline.
I'm able to get the output of the job on my pipeline console which is my requirement.
pipeline {
agent none
stages {
stage ("Check Parameters"){
steps {
echo "In pipeline"
script {
echo "Start condition check"
}
def slaveJob = build job: 'printuser'
println slaveJob.rawBuild.log
}
}
}
}
The issue happens when 'printuser' fails in which case the failing output does not show in the pipeline console page.
I tried adding the println to the post failure block like below:
post {
failure {
script {
println slaveJob.rawBuild.log
}
}
}
But, I get the below error in doing so.
Error when executing failure post condition:
groovy.lang.MissingPropertyException: No such property: slaveJob for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:270)
Can you please suggest how can I get the output of "FAILING" jobs to the pipeline console ?

On your post block you can print the whole job build log.
post {
failure {
echo Jenkins.getInstance().getItemByFullName('printuser').getLastBuild().logFile.text
}
}
Note that you should approve specific signatures to allow pipeline and groovy to access the above functions.
If you haven't done this yet, the above script will fail with
Start condition check Scripts not permitted to use staticMethod
jenkins.model.Jenkins getInstance. Administrators can decide whether
to approve or reject this signature.
You can follow the error message by clicking on the link of the message which will redirect you to the scriptApproval page of Jenkins where you can add the signature that needs approval to the approval list.
You should have the following list of approved signatures for the above to work
method hudson.model.ItemGroup getItem java.lang.String
method hudson.model.Job getLastBuild
method hudson.model.Run getLogFile
method jenkins.model.Jenkins getItemByFullName java.lang.String
staticMethod jenkins.model.Jenkins getInstance
staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getText java.io.File
If you follow this solution, you can change the post's failure action to always so it print the log always (not only on errors) and remove the println slaveJob.rawBuild.log

When using the def keyword a variable has block scope. Try slaveJob = build job: 'printuser' without the def.

Related

jenkinsfile doesn't retrieve downstream build ID on ABORT or FAILURE

I am writing a groovy code in a Jenkinsfile, In a stage, I am building another pipeline this way,
stage("1"){
steps{
script{
def u1Results = build job: 'ChildPipeline1', parameters: [string(name : 'PARAM', value: "1")]
print u1Results.number
}
}
}
u1Results.number works when ChildPipeline1 succeeds, but no clue to get the ChildPipeline1 build ID if it was aborted or failed normally, Even if I added a post-class to the stage
I'd like to know the build-id of ChildPipeline1 anyway.

Looking for a jenkins pipeline build job syntax that really works

I'm trying to trigger a jenkins pipeline job from inside another jenkins pipeline job, with parameters.
I'm relatively newbie in java/groovy so I search the web for functional samples but all that I found are unusable for syntax or scripting reasons.
Some of my tests below:
How to trigger another Jenkins pipeline that needs a $BRANCH variable?
node() {
build job: 'INVENTORIES', propagate: true, wait: true
}
Failed: java.lang.NoSuchMethodError: No such DSL method 'build' found among steps [ansiblePlaybook
Jenkins pipeline for building other jobs
node() {
stage('Desc1') {
steps {
dir('/var/lib/jenkins/workspace') {
build job: 'INVENTORIES', propagate: true, wait: true
}
}
}
}
Failed: java.lang.NoSuchMethodError: No such DSL method 'steps' found among steps [ansiblePlaybook,
node() {
stages {
stage ("build") { //an arbitrary stage name
steps {
build 'INVENTORIES' //this is where we specify which job to invoke.
}
}
}
}
Failed: java.lang.NoSuchMethodError: No such DSL method 'stages' found among steps [ansiblePlaybook,
I've tried plenty of samples (script block, step block, stage block...) but it never works, always throwing java exception like:
java.lang.ClassCastException: org.jenkinsci.plugins.workflow.steps.CoreStep.delegate expects interface jenkins.tasks.SimpleBuildStep but received class ...
Before I jump from a bridge, could anyone here helps me?
Thanks in advance, I know swimming but it's a little cold
[SOLVED]
It were missing a Pipeline Plugin but the error messages wasn't clear enought and log content too poor to guess.
Thanks to #zett42 to have pointed me on the good search way.
Have a nice day.

Jenkins Pipeline throws a java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowJob within a NonCPS method

I'm trying to get the data of another job within a #NonCPS method. It fails with a NotSerializableException even though the failing method is declared as #NonCPS.
The script is as follows - it only tries to get another job's data using its name and build number:
#!groovy
import jenkins.model.Jenkins
node('build_agent') {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
stage('Get job details') {
name = "another_jenkins_job"
job = Hudson.instance.getJob(name)
job_data = Jenkins.instance.getItemByFullName(job.fullName)
jobNumber = "1234"
println 'Job: ' + job.fullName
getUpstreamJobData(job.fullName.trim(), buildNumber.trim())
}
}
#NonCPS
def getUpstreamJobData(jobName, jobNumber) {
println "Getting build #${jobNumber} from job ${jobName}"
Jenkins.getInstance().getItemByFullName(jobName).getBuildByNumber(jobNumber)
}
The script fails, however, within the #NonCPS method getUpstreamJobData:
[Pipeline] echo
Job: another_jenkins_job
[Pipeline] echo
Getting build #1234 from job another_jenkins_job
[Pipeline] echo
Getting build #1234 from job another_jenkins_job
[Pipeline] echo
Getting build #1234 from job another_jenkins_job
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // wrap
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
an exception which occurred:
in field delegate
in field closures
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup#1f5bb62e
Caused: java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowJob
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
...
My understanding is that this failure usually happens when we return a non-serializable object outside of a Non-CPS method. However, the method here doesn't return anything yet, and it declared as NonCPS. Additionally the print statements seem to indicate that the method is executed 3 times while it is only called once.
I had the very same issue because of missing def in front of one assignment inside a #NonCPS method.
It seems, every assignment must be prefixed with def, otherwise job works as expected, but fails at the end when trying to save the finished build state.
So which part of your code is not serializable?
Why do you think the exception is thrown from you #NonSCP method?
I think that those two look very suspicious
job = Hudson.instance.getJob(name)
job_data = Jenkins.instance.getItemByFullName(job.fullName)

Jenkins pipelines Jenkins.instance.getItemByFullName

I'm having problems with my Jenkinsfile.
I want to list all running workers in current job, but jenkins just fails without printing any error. Code snippet:
#NonCPS
def check_running_process() {
// Check if PR build already in progress to kill old one
def pull_id = env.ghprbPullId.toInteger()
println pull_id
def current_build_id = env.BUILD_ID.toInteger()
println current_build_id
def currentJob = Jenkins.instance.getItemByFullName('jobname')
println currentJob
}
Output:
[Pipeline] echo
2
[Pipeline] echo
47
So Jenkins stops at def currentJob = Jenkins.instance.getItemByFullName('jobname')
There is no error produced, just a build fail.
There are no errors in jenkins.log file.
This works in scripting console.
Did anyone had the same problem?
Thank you
Okay, this was my problem.
I was calling check_running_process() inside try handler.
This produced no error, but failed because
method jenkins.model.Jenkins getItemByFullName java.lang.String
signature was not approved
(nor it produced script approval request).

Load env variables successfully in Jenkins pipeline but not while the pipeline was used as shared library

In one stage of my declarative jenkins pipeline codes, it executes a bash script(sh '''./a.sh''', script "a.sh" is maintained outsides) - in that script, the value of "jarVersion" is injected in ${WORKSPACE}/.jarVersion (echo "jarVersion=${jarVersion}" > ${WORKSPACE}/.jarVersion). At later stage, we need get the value of jarVersion. We use load "${WORKSPACE}/.jarVersion" and ${jarVersion} to get the value. It works when we do so in pipeline script.
However, when we set this pipeline as a shared library (put it in /vars/testSuite.groovy) and call it in another pipeline script. It can not recognize var ${jarVersion}.
Please advise how to solve the issue. A common question is: how to transfer a value in a script from stage A to stage B?
stage('getJarVersion'){
steps{
script{
load "${WORKSPACE}/.jarVersion"
currentBuild.description = "jarVersion:${jarVersion}"
}
}
}
I expected it could work as it is in pipeline scripts.
But it shows:
groovy.lang.MissingPropertyException: No such property: jarVersion for class: testSuite
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:53)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:458)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.getProperty(DefaultInvoker.java:34)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
at testSuite.call(/jenkins/jobs/TestSuite1/builds/11/libs/pipelineUtilities/vars/testSuite.groovy:84)
With the stages under the same groovy file, you have to declare the object out of the stage blocks and before the node block. So for each stage, you can define the value inside the variable:
Pipeline {
def my_var
stage('stage1'){
---------
}
stage('stage2'){
---------
}
}
If you are defining a stage per file, you have to create the closures with the input object and to pass it in the call from the parent groovy file:
test.groovy:
def call(def my_obj, String my_string) {
stage('my_stage') {
println(my_obj)
}
}
parent_test.groovy
test(obj_value,string_value)

Resources