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).
Related
I'm newbie to Jenkins pipeline and writing a groovy script to parse a json file. However I'm facing an error which many have faced but none of the solutions worked for me. Below is my Jenkinsfile and error msg.
def envname = readJSON file: '${env.WORKSPACE}/manifest.json'
pipeline {
agent any
stages {
stage('Build') {
steps {
echo WORKSPACE
sh "ls -a ${WORKSPACE}"
}
}
}
}
[Pipeline] Start of Pipeline
[Pipeline] readJSON
[Pipeline] End of Pipeline
org.jenkinsci.plugins.workflow.steps.MissingContextVariableException:
Required context class hudson.FilePath is missing Perhaps you forgot
to surround the code with a step that provides this, such as: node at
org.jenkinsci.plugins.pipeline.utility.steps.AbstractFileOrTextStepExecution.run(AbstractFileOrTextStepExecution.java:30)
I even tried readJSON file: '${WORKSPACE}/manifest.json but that didn't work too. I'm sure the mistake is with the first line since when removing that line, there execution is successful. The docs are pretty helpful but I'm not able to track down where exactly I'm going wrong that is why posted here.
UPDATE:
I tried the following methods def envname = readJSON file: "./manifest.json" and def envname = readJSON file: "${env.WORKSPACE}/manifest.json" and even tried them defining under the steps block. Nothing worked. Below is the error msg I recieved when I defined them under step block
WorkflowScript: 5: Expected a step # line 7, column 13
def envname =
^
Below is the official syntax doc of readJson and I can see that I'm using the correct syntax only. but still doesn't work as expected.
https://www.jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#readjson-read-json-from-files-in-the-workspace
'${env.WORKSPACE}/manifest.json' is interpolating the Groovy env map as a shell variable. You need to interpolate it as a Groovy variable like "${env.WORKSPACE}/manifest.json".
sh "ls -a ${WORKSPACE}" is interpolating the shell environment variable WORKSPACE as a Groovy variable. You need to interpolate it as a shell variable like sh 'ls -a ${WORKSPACE}'.
echo WORKSPACE is attempting to resolve the shell variable WORKSPACE as a first class Groovy variable expression. You need to use the Groovy env map instead like echo env.WORKSPACE.
As for the global variable indefinite type assignment on the first line: if it still throws the error above after making those fixes, then it may be due to invalid use of scripted syntax in a declarative syntax pipeline. You likely need to place it inside a step block within your pipeline in that case.
I've solved this myself with the help of "Matt Schuchard"'s below answer. I'm not sure whether this is the only way to solve but this worked for me.
pipeline {
agent any
stages {
stage('Json-Build') {
steps {
script {
def envname = readJSON file: "${env.WORKSPACE}/manifest.json"
element1 = "${envname.dev}"
echo element1
}
}
}
}
}
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.
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)
I am trying to read the server name from the xml file in a pipeline script.
My Code:
node {
def str = "<root><HTTPTargetConnection><Loadbalancer><server name=\"myserver\" /> </Loadbalancer></HTTPTargetConnection></root>";
def rootNode = new XmlParser().parseText(str);
echo rootNode.HTTPTargetConnection.Loadbalancer.server.#name.value[0];
}
Exception:
[Pipeline] End of Pipeline
*
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:
unclassified field groovy.util.Node HTTPTargetConnection at
org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:367)
at
org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:363)
at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
Please help me in resolving this issue.
You're running into sandbox issues. The field in question is not authorized for use and therefore must be approved (in the script approval page).
Good Day,
I have a groovy script running on a jenkins job like so.
//checkoutObjects
def command =""
for (i = 0; i <numOfObj; i++) {
command = "svn export -r "+DeploySetArray[i][1]+" "+DeploySetArray[i][0]+" D:/Jenkins/workspace/mmb.database.deploy"
//println command.execute().text
def proc = command.execute()
proc.waitFor()
println "Process exit code: ${proc.exitValue()}"
println "Std Err: ${proc.err.text}"
println "Std Out: ${proc.in.text}"
}
The above snippet works great, checks out all my SVN objects. Now the below part is where I have the issue.
command = "sqlplus mastermind/***#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=***)(PORT=1521))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=***))) #D:/BuildScripts/MMB/gather_invalids.sql"
def proc = command.execute()
println "This line is printed"
proc.waitFor()
println "This line is not printed"
println "Process exit code: ${proc.exitValue()}"
println "Std Err: ${proc.err.text}"
println "Std Out: ${proc.in.text}"
For some reason when trying to run this groovy script through Jenkins, or running directly from groovy console It waits on this line. However if i extract the sqlplus command exactly and run that by itself on CL it returns within a few seconds. I've looked up a few answers that I thought were close, but it seems weird that it works fine on command line but not through groovy. Any advice or pointers would be appreciated.
Thank you!
EDIT: I've tried using another command line tool "sql" instead of "sqlplus". Script is still hanging in the same spot, making me think its something to do with groovy
Found a solution, my issue wasn't groovy related though. The problem was with the commandline tools 'sql', and 'sqlplus'. When these programs are called with a script to execute, they will run the script and then without exiting prompt for more interaction. This caused the script to hang while it was waiting for more input. I got around this by preceeding my command with "exit | sqlplus..."
This link is what helped me.
https://serverfault.com/questions/87035/run-oracle-sql-script-and-exit-from-sqlplus-exe-via-command-prompt