Executing groovy scripts on Jenkins' slaves - jenkins

I'm trying to execute a simple groovy script on Jenkins' slaves using the Groovy plugin.
I'm using the execute groovy script option and not the execute system groovy script option. I'm also using the "install automatically" (install from groovy website) option of the plugin of the latest version(2.4.6) . However, the job fails and I'm getting this:
Building remotely on .... (...) in workspace C:\Jenkins_Slave\workspace\...
Unpacking https://dl.bintray.com/groovy/maven/apache-groovy-binary-2.4.6.zip to C:\Jenkins_Slave\tools\hudson.plugins.groovy.GroovyInstallation\groovy_2_4_6 on ...
[groovy_reset_dead_slave] $ C:\Jenkins_Slave\tools\hudson.plugins.groovy.GroovyInstallation\groovy_2_4_6\bin\groovy.bat C:\Jenkins_Slave\workspace\...\hudson5850644430171226650.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
C:\Jenkins_Slave\workspace\...\hudson5850644430171226650.groovy: 5: unable to resolve class jenkins.model.Jenkins
# line 5, column 1.
import jenkins.model.Jenkins
^
1 error
Build step 'Execute Groovy script' marked build as failure
Finished: FAILURE
How can I overcome this issue and make it work properly?

From the Groovy plugin page:
Groovy Script vs System Groovy Script
The plain "Groovy Script" is run in a forked JVM, on the slave where the build is run. It's the basically the same as running the "groovy" command and pass in the script.
The system groovy script, OTOH, runs inside the Jenkins master's JVM. Thus it will have access to all the internal objects of Jenkins, so you can use this to alter the state of Jenkins. It is similar to the Jenkins Script Console functionality.
When not using the system Groovy, you do not have Jenkins object in your classpath. You need to make sure the required classes are accessible from the job you are running, and pass them in the "Class path" field of the "execute groovy script" step.

We can use RemoteDignostics class
The following Script runs on master but uses RemoteDignostics to run groovy on Worker Nodes/slave.
import hudson.util.RemotingDiagnostics
import jenkins.model.Jenkins
String agent_name = 'your agent name'
groovy_script = '''
println System.getenv("PATH")
println "uname -a".execute().text
'''.trim()
String result
Jenkins.instance.slaves.find { agent ->
agent.name == agent_name
}.with { agent ->
result = RemotingDiagnostics.executeGroovy(groovy_script, agent.channel)
}
println result

Related

Groovy script works in console but not in job

So I've created a Groovy script, and it works in the console. I then implemented it into my job in the field Execute Groovy Script but then it failed.
Here I have the console, and I do know the imports aren't needed, but I had to try.
But When I run my job with this code, I get this error:
Running as SYSTEM
[EnvInject] - Loading node environment variables.
Building remotely on Buildsl (hant) in workspace C:\JS\workspace\node_checker
[Vetus_node_checker] $ groovy C:\JS\workspace\node_checker\hudson633049885410603886.groovy
Caught: groovy.lang.MissingPropertyException: No such property: Jenkins for class: hudson633049885410603886
groovy.lang.MissingPropertyException: No such property: Jenkins for class: hudson633049885410603886
at hudson633049885410603886.run(hudson633049885410603886.groovy:6)
Build step 'Execute Groovy script' marked build as failure
Started calculate disk usage of build
Finished Calculation of disk usage of build in 0 seconds
Started calculate disk usage of workspace
Finished Calculation of disk usage of workspace in 0 seconds
Finished: FAILURE
It look like you are using the "Execute Groovy script", but to execute scripts like in Script Console you must use the "Execute system Groovy script" step.
The normal execute will start a new Java/JVM with Groovy which is not "connected" to your Jenkins.
Only the system step will execute the script within the existing Java/JVM that is running Jenkins.
So yes I had to run it as a Execute system Groovy script, but I also had to give the full path to the lib I'm using, before it worked. the Script Console didn't need the jenkins.model... part, but the job does.

Delete view programmatically in Jenkins

I'm trying to delete a Jenkins view programmatically but my Jenkins job:
import jenkins.model.*;
import jenkins.util.*;
jenkins = Jenkins.instance
def view = jenkins.getView("my-view")
jenkins.deleteView( view )
fails giving:
[workspace] $ groovy /var/lib/jenkins/jobs/DeleteViews/workspace/hudson8664703220024294601.groovy
Caught: groovy.lang.MissingPropertyException: No such property: Jenkins for class: hudson8664703220024294601
groovy.lang.MissingPropertyException: No such property: Jenkins for class: hudson8664703220024294601
at hudson8664703220024294601.run(hudson8664703220024294601.groovy:4)
Build step 'Execute Groovy script' marked build as failure
I've seen solutions like this:
https://stackoverflow.com/a/42020732/343204
and suggestions on how to import like this:
Running Groovy command from Jenkins using Groovy script plugin
but not sure how to proceed.
Any suggestions?
As I understand, you use freestyle job with step "Execute Groovy script".
So, you need to change this step to "Execute system Groovy script" and your code will work.

Jenkins: Running groovy script with ant commands

I have a groovy script with ant commands on it. The script is successfully run in my local machine but when I tried it with Jenkins the groovy script always fail. Jenkins always return error that "ant can't create task or type p4Change". I already added Apache ant support in the global configuration. How do I configure ant to successfully run the groovy script I have. Any idea. Thanks.
Sample code snippets:
I have execute.groovy file with ant commands
ant=new AntBuilder()
def checkChanges {
ant.p4change(description:"Checking",port:'perforce:1666',user:optional,view:"'${workspace}'...")}
And I created a batch file that will run the execute.groovy file
call groovy execute.groovy project bopolz18 -c bopolz18.Workspace 150718
In my machine this works well but in Jenkins when I execute the batch command it fails giving the error mention above.

Passing Jenkins classpath via gradle plugin

I have a groovy script with objects which runs in my Jenkins script window. This script references my Jenkins instance and creates new Jenkins branch jobs.
The script runs in the the Jenkins script window. Now I have a requirement to use Jenkins Gradle plugin to execute the script. The groovy plugin works, but as I said the requirement is to accomplish this via the gradle plugin.
I've tried Gradle task type JavaExec, which forks a new JVM and I lose access to my Jenkins instance. I also tried Groovy evaluate(File file) method but classpath reference to Jenkins classes are lost.
// FAILS: forks a new JVM that does not have access to Jenkins object graph
task runCreateBranchJobs(type: JavaExec) {
description 'Create Branch Jobs in Jenkins'
main = 'createBranchJobs'
classpath = sourceSets.main.runtimeClasspath
}
// FAILS: has no knowledge of Jenkins classes, even when evaluated in Jenkins job
task runCreateBranchJobsInSameProcess {
doLast {
evaluate(new File("${projectDir}/src/main/groovy/createBranchJobs.groovy"))
}
}
Any suggestions on how to run the groovy script within the context of the Jenkins Job while successfully passing the classpath using the gradle plugin?

Running groovy script on slave nodes

How do we configure running groovy scripts on slave nodes? am able to get groovy installation from manage jenkins section, but the scripts fail to run.
I am having a job with execute groovy steps and this job is supposed to run on "slave" nodes.
The System groovy option wont fit since it runs on master and the execute groovy on job configured to run on slave fails with error
/workspace/hudson5188055044238549912.groovy: 2: unable to resolve class jenkins.model.Jenkins
# line 2, column 1.
import jenkins.model.Jenkins
Seems the jars are not picked during run. Is there easy way to setup or which jenkins and groovy jars are required??
On the job configuration page there should be a drop down beside "Groovy Version" under the "Execute Groovy Script" block. You need to select the name of the groovy install that is on master. Jenkins will grab the necessary files from master.

Resources