How to check if a variable is defined in a Jenkins folder? - jenkins

I created a Jenkins folder which has multiple jobs in it. I've also defined some variables in the folder itself. How can I check if the folder has a variable defined? I tied
import jenkins.model.*
private def getBuildJob(final String folder) {
def jobFolder = null
for (f in Jenkins.instance.getAllItems(AbstractItem.class)) {
if (f.fullName == folder) {
jobFolder = f
break
}
}
return jobFolder
}
node("linux-ubuntu") {
stage("test") {
def folder = getBuildJob("MyFolderName")
println folder.hasVariable("MY_VARIABLE")
}
}
But I get
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: com.cloudbees.hudson.plugins.folder.Folder.hasVariable() is applicable for argument types: (java.lang.String) values: [MY_VARIABLE]
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:153)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:161)

If you are using the folder-properties plugin you can use the following script.
#NonCPS
def checkVar() {
def folderName = "Folderycr"
def propToCheck = "YCRPROP"
def folderItem = Jenkins.instance.getAllItems(com.cloudbees.hudson.plugins.folder.AbstractFolder.class).find{ (it.name == folderName) }
println folderItem.getProperties().each { prop ->
if(prop instanceof com.mig82.folders.properties.FolderProperties){
prop.getProperties().each{
if(it.key == propToCheck) {
println "Prop is available. Vale is : " + it.value
}
}
}
}
}
node("linux-node") {
stage("Run test") {
checkVar()
}
}

Related

How to change the Git URL in all Jenkins jobs

Does anyone have an updated version of ceilfors answer that works for both AbstractProject and WorkflowJob?
This is the solution I came up with. It was tested on Jenkins 2.355
The test was run from the script console.
For testing purposes, I limited the test to one Freestyle (AbstractProject) and one Pipeline (WorkflowJob) job each. You would need to modify the code below.
I hope others find this useful
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import hudson.plugins.git.*
import jenkins.*
import jenkins.model.*
def modifyGitUrl(url) {
def updatedUrl = url.toString().replace("git#gitlab", "git#github")
// println "updatedUrl = ${updatedUrl}"
return updatedUrl
}
Jenkins.instance.getAllItems(Job.class).each {
project = it.getFullName()
if(project.toString().equals("PL_Quick_Testing") || project.toString().equals("A_Freestyle_Job")) {
try {
if (it instanceof AbstractProject){
def oldScm = it.scm
def newUserRemoteConfigs = oldScm.userRemoteConfigs.collect {
new UserRemoteConfig(modifyGitUrl(it.url), it.name, it.refspec, it.credentialsId)
}
def newScm = new GitSCM(newUserRemoteConfigs, oldScm.branches, oldScm.doGenerateSubmoduleConfigurations,
oldScm.submoduleCfg, oldScm.browser, oldScm.gitTool, oldScm.extensions)
it.scm = newScm
it.save()
println "Done"
} else if (it instanceof WorkflowJob) {
def oldScm = it.getTypicalSCM()
def definition = it.getDefinition()
String scriptPath = it.getDefinition().getScriptPath()
def newUserRemoteConfigs = oldScm.userRemoteConfigs.collect {
new UserRemoteConfig(modifyGitUrl(oldScm.userRemoteConfigs.url[0]), it.name, it.refspec, it.credentialsId)
}
def newScm = new GitSCM(newUserRemoteConfigs, oldScm.branches, oldScm.doGenerateSubmoduleConfigurations,
oldScm.submoduleCfg, oldScm.browser, oldScm.gitTool, oldScm.extensions)
def newDefinition = new org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition(newScm, scriptPath)
it.definition = newDefinition
it.save()
println "Done"
} else {
println("${project} has no SCM")
}
} catch (Exception e) {
// e.printStackTrace()
}
}
}

List of filenames Sorting in Jenkins piepline based on file extension

I have a list which contains file names(change log) in Jenkins pipeline. I am looking to sort that list based on file extension.
example - lines = [a.yaml, b.sql, c.json, d.py, e.txt]
I would like to sort this list as below-
lines = [c.json, d.py, b.sql, e.txt, a.yaml]
Thanks in advance.
You can use Groovy Sort with a custom comparator. Please refer to the following sample.
pipeline {
agent any
stages {
stage('Test') {
steps {
script {
def lines = ["a.yaml", "b.sql", "c.json", "d.py", "e.txt"]
echo "Not sorted: $lines"
sortFiles(lines)
echo "Sorted: $lines"
}
}
}
}
}
#NonCPS
def sortFiles(def files) {
return files.sort { s1, s2 -> s1.substring(s1.lastIndexOf('.') + 1) <=> s2.substring(s2.lastIndexOf('.') + 1) }
}
Update
Bringing files without a extension to the top
#NonCPS
def sortFiles(def files) {
return files.sort { s1, s2 ->
def s1Index = s1.lastIndexOf('.')
def s2Index = s2.lastIndexOf('.')
if((s1Index == -1)) { // S1 doesn't have an extension, S1 comes first
return -1
} else if (s2Index == -1) { // S1 have an extension but S2 doesn't so s2 comes first
return 1
} else {
return s1.substring(s1Index + 1) <=> s2.substring(s2Index + 1)
}
}
}

Is there a way, in a list of jobs, to change a job's parameter to required?

I am using the script console of hudson and jenkins.
And I need make a parameter called "NAME" become required at the jobs where that parameter already exists. But I do not know any method that can help me.
def instance = hudson.model.Hudson.instance;
def allJobs = instance.getView("All");
allJobs.items.each {
if (it.containsParameter('NAME')){ /// this exists?
println(it.getName());
it.set??? /// what can I do?
}
}
I need that way for when someone excute the job the parameter "NAME" do not be empty or null.
you can get the desired result with below code:
def instance = hudson.model.Hudson.instance;
def allJobs = instance.getView("All");
allJobs.items.each {
prop = it.getProperty(ParametersDefinitionProperty.class)
if(prop != null) {
for(param in prop.getParameterDefinitions()) {
try {
if(param.name.equals('NAME')){
println(it.name + ":" + param.name + " " + param.defaultValue)
if(!param.defaultValue.trim()){
println("default value is blank")
}
}
}
catch(Exception e) {
println e
}
}
}
}

jenkins pipeline : How to execute a function on a list of agents in parallel?

I have a bunch of nodes serving labels rhel6, rhel7.
How do I execute myFunc() on any 2 nodes of rhel6 and any 3 nodes rhel7 - in parallel?
def slaveList = ['rhel6', 'rhel6', 'rhel7', 'rhel7', 'rhel7']
def stageFunc (String slaveLabel) {
return {
// Run this stage on any available node serving slaveLabel
agent { label "${slaveLabel}" } // Error shown here.
stage {
myFunc()
}
}
}
pipeline {
agent any
stages {
stage('Start') {
steps {
script {
def stageMap = [:]
def i = 0
slaveList.each { s ->
stageMap[i] = stageFunc(s)
i++
}
parallel stageMap
}
}
}
}
}
Error shown:
java.lang.NoSuchMethodError: No such DSL method 'agent' found among steps [archive, ...
I haven't tested this yet, but it should work.
def slaveList = ['rhel6', 'rhel6', 'rhel7', 'rhel7', 'rhel7']
def stageFunc (stage_name, slaveLabel) {
return {
// Run this stage on any available node serving slaveLabel
stage(stage_name){
node(slaveLabel) {
myFunc()
}
}
}
}
pipeline {
agent any
stages {
stage('Start') {
steps {
script {
def stageMap = [:]
def i = 0
slaveList.each { s ->
stageMap[i] = stageFunc("Stage-${i}", s)
i++
}
parallel stageMap
}
}
}
}
}

Criteria building in GORM

if (params.filters) {
def o = JSON.parse(params.filters);
def groupOp = o.groupOp
def fields = o.rules.field
def values = o.rules.data
def op = o.rules.op
println fields
println values
if(groupOp == "AND") {
fields.eachWithIndex {a, i ->
println op[i]
if(op[i].equals( "eq")) {
and{ eq(fields[i], values[i])}
}
if(op[i].equals("ne")) {
and{ ne(fields[i], values[i])}
}
if(op[i].equals("ge")) {
def valu = Double.valueOf( values[i]);
and{ ge(fields[i], valu)}
}
}
}
if(groupOp == "OR") {
fields.eachWithIndex {a, i ->
println op[i]
if(op[i].equals( "eq")) {
println 'eq';
or{ eq(fields[i], values[i])}
}
if(op[i].equals("ne")) {
println 'ne';
or{ ne(fields[i], values[i])}
}
if(op[i].equals("ge")) {
def valu = Double.valueOf( values[i]);
or{ ge(fields[i], valu)}
}
}
}
}
where params.filters is following JSON text.
{
"groupOp":"OR",
"rules":[
{
"field":"foo1",
"op":"le",
"data":"9.5"
},
{
"field":"foo2",
"op":"eq",
"data":"12345-123"
},
{
"field":"foo3",
"op":"cn",
"data":"IDM"
}
]
}
This data is coming from JQuery data grid.
Is there a better way of doing this?
In the code I have just listed only 3 operators, but in real I have 14 operations.
You can use String as Criteria operation, like:
A.withCriteria {
'eq' (id, 1)
}
so you might come to something like
A.withCriteria {
(groupOp) {
for (???) {
(op[i]) (fields[i], parsedVals[i])
}
}
}
Anyway you'll need to sanitize the web-submitted query for only allowed subset of operations. You don't want to receive end execute arbitrary sqlRestriction, right? :D So the code is going to be more complex then this anyway.
Note: wrapping and{} or or {} around single statement has no point, you need to put it around whole block of if-s.
I suggest that you have a look at the source code of the FilterPane plugin. Its service does essentially what you are doing and may give you some ideas for enhancements.

Resources