Groovy DSL for Extended choice parameter plugin - jenkins

I'm converting my Jenkins job configurations into code using groovy DSL. Am able to convert all the code except extended choice parameter plugin configuration.
I've a groovy script which does some API calls and get the values and return as choice to the defied parameter in the job. I've tested it and working fine. But, when I tried to automate/convert the same into Groovy DSL am not getting enough support from the plugin rather I haven't find any document which helps me with this situation.
kindly help.

I went through the same process a couple of months ago. I found this article tremendously useful - http://www.devexp.eu/2014/10/26/use-unsupported-jenkins-plugins-with-jenkins-dsl.
Here's a sample code snippet:
configure {
project->
project / 'properties' << 'hudson.model.ParametersDefinitionProperty' {
parameterDefinitions {
'com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition' {
name 'TARGET_ENVS'
quoteValue 'false'
saveJSONParameterToFile 'false'
visibleItemCount '15'
type 'PT_CHECKBOX'
value "${deployTargets}"
multiSelectDelimiter ','
projectName "${jobName}"
}
}
}
}
The article suggests appending the 'configure' code block at the end of your DSL job definition, however that didn't work for me. I ended up putting the code block at the start of the definition.
Good luck

Job DSL plugins allows you to add XML configuration to jobs config.xml files. You have to use configure closure and next specify whatever you want. For example I have such configuration:
<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions>
<com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition plugin="extended-choice-parameter#0.76">
<name>PRODUCT_REPO_URL</name>
<description>ssh URL of the product repository</description>
<quoteValue>false</quoteValue>
<saveJSONParameterToFile>false</saveJSONParameterToFile>
<visibleItemCount>10</visibleItemCount>
<type>PT_SINGLE_SELECT</type>
<groovyScript>import hudson.slaves.EnvironmentVariablesNodeProperty
import jenkins.model.Jenkins
Jenkins.get().globalNodeProperties.get(EnvironmentVariablesNodeProperty.class).envVars.get(&apos;PRODUCT_REPOSITORIES&apos;)</groovyScript>
<bindings></bindings>
<groovyClasspath></groovyClasspath>
<defaultGroovyScript>import hudson.slaves.EnvironmentVariablesNodeProperty
import jenkins.model.Jenkins
Jenkins.get().globalNodeProperties.get(EnvironmentVariablesNodeProperty.class).envVars.get(&apos;PRODUCT_REPOSITORY_DEFAULT&apos;)</defaultGroovyScript>
<defaultBindings></defaultBindings>
<defaultGroovyClasspath></defaultGroovyClasspath>
<multiSelectDelimiter>,</multiSelectDelimiter>
<projectName>try-to-upgrade-dependencies</projectName>
</com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
Now I can generate it by adding the following code:
configure {
project -> project / 'properties' << 'hudson.model.ParametersDefinitionProperty' {
parameterDefinitions {
'com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition'(plugin: 'extended-choice-parameter#0.76') {
delegate.name('PRODUCT_REPO_URL')
delegate.description('ssh URL of the product repository')
delegate.quoteValue(false)
delegate.saveJSONParameterToFile(false)
delegate.visibleItemCount(10)
delegate.type('PT_SINGLE_SELECT')
delegate.groovyScript("""import hudson.slaves.EnvironmentVariablesNodeProperty
import jenkins.model.Jenkins
Jenkins.get().globalNodeProperties.get(EnvironmentVariablesNodeProperty.class).envVars.get('PRODUCT_REPOSITORIES')""")
delegate.defaultGroovyScript("""import hudson.slaves.EnvironmentVariablesNodeProperty
import jenkins.model.Jenkins
Jenkins.get().globalNodeProperties.get(EnvironmentVariablesNodeProperty.class).envVars.get('PRODUCT_REPOSITORY_DEFAULT')""")
delegate.multiSelectDelimiter(',')
delegate.projectName('try-to-upgrade-dependencies')
}
}
}
}
The final result:
<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions>
<com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition plugin="extended-choice-parameter#0.76">
<name>PRODUCT_REPO_URL</name>
<description>ssh URL of the product repository</description>
<quoteValue>false</quoteValue>
<saveJSONParameterToFile>false</saveJSONParameterToFile>
<visibleItemCount>10</visibleItemCount>
<type>PT_SINGLE_SELECT</type>
<groovyScript>import hudson.slaves.EnvironmentVariablesNodeProperty
import jenkins.model.Jenkins
Jenkins.get().globalNodeProperties.get(EnvironmentVariablesNodeProperty.class).envVars.get('PRODUCT_REPOSITORIES')</groovyScript>
<defaultGroovyScript>import hudson.slaves.EnvironmentVariablesNodeProperty
import jenkins.model.Jenkins
Jenkins.get().globalNodeProperties.get(EnvironmentVariablesNodeProperty.class).envVars.get('PRODUCT_REPOSITORY_DEFAULT')</defaultGroovyScript>
<multiSelectDelimiter>,</multiSelectDelimiter>
<projectName>try-to-upgrade-dependencies</projectName>
</com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>

Related

How to disable or remove multibranch pipeline trigger on existing jobs

I have hundreds of jenkins jobs(multibranch pipeline) with trigger enabled to periodically scan respective repositories every 5 mins. I'm trying to disable "scan multibranch pipeline triggers" on all the existing jobs in a particular folder(development/microservice). I'm running below script from Jenkins script console and getting exception at removeTrigger
import hudson.model.*
import hudson.triggers.*
import jenkins.model.*
import com.cloudbees.hudson.plugins.folder.Folder
for (it in Jenkins.instance.getAllItems(jenkins.branch.MultiBranchProject.class)) {
if(it.fullName.length() > 25 && it.fullName.substring(0,25) ==
'development/microservice/' && it.fullName.split("/").length == 3) {
println it.fullName
it.triggers.each { descriptor, trigger ->
it.removeTrigger(descriptor)
it.save()
}
}
}
Can someone please help me how to disable triggers on multibranch pipeline jobs programmatically.
It seems one just needs to iterate over the triggers, and pass the right part to removeTrigger(); that means passing the trigger rather than the descriptor:
for (p in Jenkins.instance.getAllItems(jenkins.branch.MultiBranchProject.class)) {
p.triggers.each { descriptor, trigger ->
//println descriptor
//println trigger
p.removeTrigger(trigger)
}
}
Output sample for a single trigger, when println statements are not commented out:
com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger$DescriptorImpl#30f35b28
com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger#3745f994
Many thanks for your question, your almost working code helped me a lot. ;)

Jenkins - Groovy pipeline - Using FilePath gives Could not find matching constructor

Building on this suggestion:
Using FilePath to access workspace on slave in Jenkins pipeline I am trying to get the files that are dropped into the workspace by git, and iterate through those files using eachFileRecurse, by passing in the adjusted folder. However, when calling into FilePath, I get errors.
import groovy.io.FileType
import java.io.File
import java.lang.Object
import hudson.FilePath
import jenkins.model.Jenkins
def createFilePath(path) {
return new FilePath(Jenkins.getInstance().getComputer(env['NODE_NAME']).getChannel(), path);
}
#NonCPS // has to be NonCPS or the build breaks on the call to .each
def getFiles(dirLoc) {
def dir = new File (dirLoc)
def list = []
dir.eachFileRecurse (FileType.FILES)
{file -> if (file.name.endsWith('.txt')) {list << file}}
return list
}
I get this error
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.io.File(hudson.FilePath)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1737)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1537)
I cannot figure out what I am missing here to make this work. Thanks in advance!
There is no Constructor for java.io.file with hudson.FilePath as a parameter.
Refer to java doc at following link: https://docs.oracle.com/javase/7/docs/api/java/io/File.html

Groovy Script to add new phase job to multi-job in Jenkins

For the already available multi-job in jenkins, need to add new phase jobs using Groovy Scripting. I have written the following groovy code which adds up an already existing job p25_deploy-1.
This code is working to create the multi-job but the phase job is not showing as mapped in the Jenkins UI. Where as if I see it config.xml, its created properly as expected except a tag <killPhaseOnJobResultCondition>. Not sure why the phase job is not mapped properly?
import jenkins.model.*
import hudson.model.*
import com.tikal.jenkins.plugins.multijob.*
import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig.*
import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig.KillPhaseOnJobResultCondition.*
import java.lang.String.*
import hudson.model.Descriptor;
import hudson.tasks.Builder;
def jenkinsInstance = jenkins.model.Jenkins.instance
def templateJobName = 'profile_p25'
def templateJob = jenkinsInstance.getJob(templateJobName)
// get MultiJob BuildPhases and clone each PhaseJob
builders = templateJob.getBuilders();
builders.each { b ->
if (b instanceof MultiJobBuilder){
def pj = b.getPhaseJobs()
hudson.model.Describable p1 = new PhaseJobsConfig("p25_deploy-1",null,
true,PhaseJobsConfig.KillPhaseOnJobResultCondition NEVER,null,false,false,null,0,false,true,null,false,false)
pj.add(p1)
}
}
templateJob.save()
// update dependencies
jenkinsInstance.rebuildDependencyGraph()
Any help will be really appreciated. Have tried many ways but was not able to figure out the problem with the script.
We can use DSL to create but I wanted it to be done in Groovy Scripting and moreover modify the existing job.
Blockquote
Yay! I am back with the answer for my question. Have tried this since very long time. Finally am able to make it though. I was aware that solution would be really simple but not able to figure out the hack of it.
import jenkins.model.*
import hudson.model.*
import com.tikal.jenkins.plugins.multijob.*
import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig.*
import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig.KillPhaseOnJobResultCondition.*
import java.lang.String.*
import hudson.model.Descriptor
import hudson.tasks.Builder
def jenkinsInstance = jenkins.model.Jenkins.instance
def templateJobName = 'profile_p25'
def templateJob = jenkinsInstance.getJob(templateJobName)
// get MultiJob BuildPhases and clone each PhaseJob
builders = templateJob.getBuilders();
builders.each { b -> if (b instanceof MultiJobBuilder)
{ def pj =
b.getPhaseJobs()
hudson.model.Describable newphase = new
PhaseJobsConfig(deploys[i],null,
true,null,null,false,false,null,0,false,false,"",false,false)
newphase.killPhaseOnJobResultCondition = 'NEVER'
pj.add(newphase)
}
}
templateJob.save()

Set Gatling report name in Jenkins pipeline througt taurus

I'm writing a declarative jenkins pipeline and I'm facing problems with gatling reports:
Mean response time trend is not correct, Is there a way to replace following cloud of dots by a curve ?
Extracts from my Jenkinsfile:
stage('perf') {
steps {
bzt params: './taurus/scenario.yml', generatePerformanceTrend: false, printDebugOutput: true
perfReport configType: 'PRT', graphType: 'PRT', ignoreFailedBuilds: true, modePerformancePerTestCase: true, modeThroughput: true, sourceDataFiles: 'results.xml'
dir ("taurus/results") {
gatlingArchive()
}
}
}
Extract from my scenario.yml:
modules:
gatling:
path: ./bin/gatling.sh
java-opts: -Dgatling.core.directory.data=./data
In scenario.yml, I tried to set gatling.core.outputDirectoryBaseName :
java-opts: -Dgatling.core.directory.data=./data -Dgatling.core.outputDirectoryBaseName=./my_scenario
In this case it replace only gatling by my_scenario, but huge number is already present.
I finally found a solution to solve this problem, but it's not simple since it involves an extension of the taurus code.
The problem is here, at line 309 of the file gatling.py in taurus repo. It explicitly add a prefix 'gatling-' to find a gatling report.
However, parameter -Dgatling.core.outputDirectoryBaseName=./my_scenario in file scenario.yml change this prefix by my_scenario. What I will describe below is a way to extend taurus in order to quickly extends.
Create a file ./extensions/gatling.py with this code to extend class GatlingExecutor:
from bzt.modules.gatling import GatlingExecutor, DataLogReader
class GatlingExecutorExtension(GatlingExecutor):
def __init__(self):
GatlingExecutor.__init__(self)
def prepare(self):
# From method bzt.modules.gatling.GatlingExecutor:prepare, copy code before famous line 309
# Replace line 309 by
self.dir_prefix = self.settings.get('dir_prefix', 'gatling-%s' % id(self))
# From method bzt.modules.gatling.GatlingExecutor:prepare, copy code after famous line 309
Create a file ./bztx.py to wrap command bzt:
import signal
import logging
from bzt.cli import main, signal_handler
if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
main()
Update file scenario.yml by using new setting property dir_prefix and define new executor class:
modules:
gatling:
path: ./bin/gatling.sh
class: extensions.GatlingExecutorExtension
dir_prefix: my_scenario
java-opts: -Dgatling.core.directory.data=./data -Dgatling.core.outputDirectoryBaseName=./my_scenario
Finaly, update your Jenkinsfile by replacing bzt call with a call to your new file bztx.py:
stage('perf') {
steps {
sh 'python bztx.py ./taurus/scenario.yml'
perfReport configType: 'PRT', graphType: 'PRT', ignoreFailedBuilds: true, modePerformancePerTestCase: true, modeThroughput: true, sourceDataFiles: 'results.xml'
dir ("taurus/results") {
gatlingArchive()
}
}
}
That's all and it works for me. Bonus: this solution gives a way to easily extends taurus with your owns plugins ;-)

Accessing config.groovy variables from Quartz Job

This is grails-app/conf/Config.groovy from which i am trying to access
variables in Quartz Job. This is the variable i am trying to access in the quartz job below:
ais.mediquery.TrialVariable="My Variable";
Quartz Job :
import com.projectname.*;
import org.codehaus.groovy.grails.commons.GrailsApplication;
import grails.util.Holders
class TrialJob {
GrailsApplication grailsApplication;
static triggers = {
simple repeatInterval: 10000l // execute job once in 5 seconds
}
def execute() {
//log.info(grailsApplication.ais.mediquery.TrialVariable)
println (Holders.config.ais.mediquery.TrialVariable)
}
}
I have tried using both GrailsApplication and ais.mediquery.TrialVariable
but none of them seem to access variables and print them
The config is definitely available from GrailsApplication and that's the best option:
println grailsApplication.config.ais.mediquery.TrialVariable
If that doesn't seem to work, try printing the whole config and see if you have a typo:
println grailsApplication.config
or
println grailsApplication.config.flatten()
As with any behavior that seems strange, run grails clean and grails compile to force a clean compile.

Resources