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?
Related
I'm fairly new to Jenkins and a total newbie to Bamboo. I have a Jenkins Pipeline and I'm trying to create an equivalent in Bamboo (I believe it's called a Plan).
I've got some groovy code that I want to run in my Bamboo plan.
I'll simplify the code below for brevity and clarity.
Assume this file is called me_myEvent.groovy and is stored at https://github.com/myuser/repo1
def processEvent( Map args ) {
String strArg1 = args.myArg1;
String strArg2 = args.myArg2;
// etc...
}
My Jenkins pipeline has a global pipeline library (myGitLibraryFromGlobal) linking to https://github.com/myuser/repo1 and my pipeline is:
#Library('myGitLibraryFromGlobal#master') abc
pipeline {
agent any
stages {
stage('First Stage') {
steps {
script {
def myObj = new com.mysite.me_myEvent();
def returnVal = myObj.processEvent(arg1: 'foo', arg2: 'bar');
}
}
})
}
}
I've got the GitHub repo saved in Bamboo as a global linked repository called abc123.
Can I achieve the same thing in Bamboo using the script task? What would this look like in Bamboo?
The short answer is NO, as Atlassian Bamboo doesn't support the DSL Groovy or Scripted Groovy pipeline. Also, please keep in mind that when you run the Jenkins Groovy pipeline, then Jenkins adds its own environment to the script execution, it is not just running "bare" groove script (i.e. without exposed Jenkins commands and variables).
If you need to run a "bare" groovy script supporting the idea of Configuration as Code, one solution is to create a Bamboo Java/YAML spec. Then you need to create ScriptTask.
// this is called when the plan and stages are created
new Job("JobName","JobKey").tasks(new VcsCheckoutTask(), // to download the groovy script
new ScriptTask().inlineBody("groovy me_myEvent.groovy").interpreterBinSh())
Note: your Bamboo build agent should have a pre-installed groovy.
Another solution is to use the Bamboo plugin Groovy Tasks for Bamboo.
I have a Jenkins Ivy job that uses the Inject environment variables to the build process step. I am writing a DSL script so that I can dynamically create this job with the job-dsl-plugin plug-in.
I set up the following lines for this:
steps {
envInjectBuilder {
propertiesFilePath('/tmp/file')
}
}
but the steps method can only be applied to a free-style job and not to an Ivy job. I get this in the console output:
Processing DSL script ivyJob.groovy
java.lang.IllegalStateException: steps cannot be applied for Ivy jobs
Doesn't the DSL plug-in support EnvInject for an Ivy job? If it doesn't, is there a way I can do this programmatically? I know EnvInject is compatible with Ivy jobs since I can manually create the very job.
Thanks.
The EnvInject plugin allows to inject variables at several points in a build's lifecycle. A build step is only one possibility. For a Ivy project type the job property and wrapper options will work.
ivyJob('example') {
environmentVariables {
env('ONE', '1')
propertiesFile('env.properties')
keepBuildVariables(true)
}
wrappers {
environmentVariables {
env('ONE', '1')
envs(FOO: 'bar', TEST: '123')
propertiesFile('env.properties')
}
}
}
See the Job DSL API Viewer for details:
https://jenkinsci.github.io/job-dsl-plugin/#path/ivyJob-environmentVariables
https://jenkinsci.github.io/job-dsl-plugin/#path/ivyJob-wrappers-environmentVariables
What are seed jobs in Jenkins and how does it work ?
Can we create a new job from seed job without using github ?
That depends on context. Jenkins itself does not provide "seed jobs".
There's plugins that allow creating jobs from other jobs, like the excellent Job-DSL plugin. With that, you can create jobs where a groovy script creates a larger number of jobs for you.
The Job-DSL plugin refers to those jobs as "seed jobs" (but they're regular freestyle or pipeline jobs). The Job-DSL plugin does not require a github connection.
The seed job is a normal Jenkins job that runs the Job DSL script; in turn, the script contains instructions that create additional jobs. In short, the seed job is a job that creates more jobs. In this step, you will construct a Job DSL script and incorporate it into a seed job. The Job DSL script that you’ll define will create a single freestyle job that prints a 'Hello World!' message in the job’s console output.
A Job DSL script consists of API methods provided by the Job DSL plugin; you can use these API methods to configure different aspects of a job, such as its type (freestyle versus pipeline jobs), build triggers, build parameters, post-build actions, and so on. You can find all supported methods on the API reference site.
The jobs we used for creating new jobs are called Seed Jobs and this seed job generates new jobs using Jenkins files (using JobDSL plugin).
Here, we disabling this feature (Enable script security for Job DSL scripts)
Jenkins Dashboard→ Manage Jenkins → Configure Global Security
Way to create seed job :
JobDSL scripts for generating new jobs.
Job1.groovy
job("Job1"){
description("First job")
authenticationToken('secret')
label('dynamic')
scm {
github('Asad/jenkins_jobDSL1', 'master')
}
triggers {
gitHubPushTrigger()
}
steps {
shell ('''
echo "test"
''')
}
}
buildPipelineView('project-A') {
title('Project A CI Pipeline')
displayedBuilds(5)
selectedJob('Job1')
showPipelineParameters()
refreshFrequency(60)
}
and create same way others Job2.groovy and so on.
For Jenkins Job DSL documentation:-
Follow https://jenkinsci.github.io/job-dsl-plugin/
Think about a job - what is it actually ?
It is actually just a java/jre object that represents like this
How you generates such job/build ?
Configure Jenkins UI -> rest api to Jenkins url -> Jenkins service receive your call on the relevant endpoint -> calling to the relevant code/method and generate this new job
How Seed job will make it ?
Configure seed job on Jenkins UI only once -> run this seed job - > this code run against the internal Jenkins methods and skip all the manual process describes above
Now, when your code can talk directly to Jenkins code , things are much easier.just update your code on the relevant repo - and you are done
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
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.