issues with groovy script - jenkins

I have the following groovy script that does the following
- checks all the builds for a specific job to see if it has the same build parameter as the current build
- stops the build with the same parameter as the current build
import hudson.tasks.Ant
def myBuildNumber = build.getEnvVars()['BUILD_NUMBER'].toInteger();
def myFractureNO = build.getEnvVars()['FRACTURE_NO'].toInteger();
def projectXml = new XmlSlurper().parseText("curl http://test.corp.test.com:8080/job/FractureAUT/api/xml".execute().text);
projectXml.build.each {
if(it.number.toInteger() < myBuildNumber)
{
def jobXml = new XmlSlurper().parseText(("curl http://test.corp.test.com:8080/job/FractureAUT/" + it.number + "/api/xml").execute().text);
def myparams = jobXml.getAction(hudson.model.ParametersAction.class);
for( p in myparams ) {
printlin p.name.toString();
if (p.name.toString == "FRACTURE_NO") {
if (p.value.toString() == myFractureNO.toString()) {
"curl http://test.corp.adobe.com:8080/job/FractureAUT/" + it.number + "/stop".execute().waitFor();
break;
}
}
}
}
}
the script outputs a bunch of urls to the screen because of the line:
def projectXml = new XmlSlurper().parseText("curl http://test.corp.test.com:8080/job/FractureAUT/api/xml".execute().text);
and it doesn't do what it suppose to do. How can I make it so that the line
def projectXml = new XmlSlurper().parseText("curl http://test.corp.test.com:8080/job/FractureAUT/api/xml".execute().text);
doesn't output the urls to the screen?
I get the following output
189http://test.corp.test.com:8080/job/FractureAUT/189/188http://test.corp.test.com:8080/job/FractureAUT/188/187http://test.corp.test.com:8080/job/FractureAUT/187/186http://test.corp.test.com:8080/job/FractureAUT/186/185http://test.corp.test.com:8080/job/FractureAUT/185/184http://test.corp.test.com:8080/job/FractureAUT/184/183http://test.corp.test.com:8080/job/FractureAUT/183/182http://test.corp.test.com:8080/job/FractureAUT/182/181http://test.corp.test.com:8080/job/FractureAUT/181/179http://test.corp.test.com:8080/job/FractureAUT/179/178http://test.corp.test.com:8080/job/FractureAUT/178/177http://test.corp.test.com:8080/job/FractureAUT/177/176http://test.corp.test.com:8080/job/FractureAUT/176/174http://test.corp.test.com:8080/job/FractureAUT/174/173http://test.corp.test.com:8080/job/FractureAUT/173/172http://test.corp.test.com:8080/job/FractureAUT/172/171http://test.corp.test.com:8080/job/FractureAUT/171/170http://test.corp.test.com:8080/job/FractureAUT/170/169http://test.corp.test.com:8080/job/FractureAUT/169/168http://test.corp.test.com:8080/job/FractureAUT/168/167http://test.corp.test.com:8080/job/FractureAUT/167/166http://test.corp.test.com:8080/job/FractureAUT/166/165http://test.corp.test.com:8080/job/FractureAUT/165/164http://test.corp.test.com:8080/job/FractureAUT/164/163http://test.corp.test.com:8080/job/FractureAUT/163/162http://test.corp.test.com:8080/job/FractureAUT/162/161http://test.corp.test.com:8080/job/FractureAUT/161/160http://test.corp.test.com:8080/job/FractureAUT/160/159http://test.corp.test.com:8080/job/FractureAUT/159/158http://test.corp.test.com:8080/job/FractureAUT/158/157http://test.corp.test.com:8080/job/FractureAUT/157/156http://test.corp.test.com:8080/job/FractureAUT/156/155http://test.corp.test.com:8080/job/FractureAUT/155/154http://test.corp.test.com:8080/job/FractureAUT/154/153http://test.corp.test.com:8080/job/FractureAUT/153/152http://test.corp.test.com:8080/job/FractureAUT/152/151http://test.corp.test.com:8080/job/FractureAUT/151/150http://test.corp.test.com:8080/job/FractureAUT/150/148http://test.corp.test.com:8080/job/FractureAUT/148/146http://test.corp.test.com:8080/job/FractureAUT/146/144http://test.corp.test.com:8080/job/FractureAUT/144/143http://test.corp.test.com:8080/job/FractureAUT/143/142http://test.corp.test.com:8080/job/FractureAUT/142/141http://test.corp.test.com:8080/job/FractureAUT/141/140http://test.corp.test.com:8080/job/FractureAUT/140/139http://test.corp.test.com:8080/job/FractureAUT/139/138http://test.corp.test.com:8080/job/FractureAUT/138/137http://test.corp.test.com:8080/job/FractureAUT/137/136http://test.corp.test.com:8080/job/FractureAUT/136/135http://test.corp.test.com:8080/job/FractureAUT/135/134http://test.corp.test.com:8080/job/FractureAUT/134/133http://test.corp.test.com:8080/job/FractureAUT/133/132http://test.corp.test.com:8080/job/FractureAUT/132/131http://test.corp.test.com:8080/job/FractureAUT/131/130http://test.corp.test.com:8080/job/FractureAUT/130/129http://test.corp.test.com:8080/job/FractureAUT/129/128http://test.corp.test.com:8080/job/FractureAUT/128/127http://test.corp.test.com:8080/job/FractureAUT/127/126http://test.corp.test.com:8080/job/FractureAUT/126/125http://test.corp.test.com:8080/job/FractureAUT/125/124http://test.corp.test.com:8080/job/FractureAUT/124/123http://test.corp.test.com:8080/job/FractureAUT/123/122http://test.corp.test.com:8080/job/FractureAUT/122/121http://test.corp.test.com:8080/job/FractureAUT/121/120http://test.corp.test.com:8080/job/FractureAUT/120/119http://test.corp.test.com:8080/job/FractureAUT/119/118http://test.corp.test.com:8080/job/FractureAUT/118/117http://test.corp.test.com:8080/job/FractureAUT/117/116http://test.corp.test.com:8080/job/FractureAUT/116/115http://test.corp.test.com:8080/job/FractureAUT/115/114http://test.corp.test.com:8080/job/FractureAUT/114/113http://test.corp.test.com:8080/job/FractureAUT/113/112http://test.corp.test.com:8080/job/FractureAUT/112/111http://test.corp.test.com:8080/job/FractureAUT/111/110http://test.corp.test.com:8080/job/FractureAUT/110/109http://test.corp.test.com:8080/job/FractureAUT/109/108http://test.corp.test.com:8080/job/FractureAUT/108/107http://test.corp.test.com:8080/job/FractureAUT/107/106http://test.corp.test.com:8080/job/FractureAUT/106/105http://test.corp.test.com:8080/job/FractureAUT/105/104http://test.corp.test.com:8080/job/FractureAUT/104/103http://test.corp.test.com:8080/job/FractureAUT/103/102http://test.corp.test.com:8080/job/FractureAUT/102/101http://test.corp.test.com:8080/job/FractureAUT/101/100http://test.corp.test.com:8080/job/FractureAUT/100/99http://test.corp.test.com:8080/job/FractureAUT/99/98http://test.corp.test.com:8080/job/FractureAUT/98/97http://test.corp.test.com:8080/job/FractureAUT/97/96http://test.corp.test.com:8080/job/FractureAUT/96/95http://test.corp.test.com:8080/job/FractureAUT/95/94http://test.corp.test.com:8080/job/FractureAUT/94/93http://test.corp.test.com:8080/job/FractureAUT/93/92http://test.corp.test.com:8080/job/FractureAUT/92/91http://test.corp.test.com:8080/job/FractureAUT/91/90http://test.corp.test.com:8080/job/FractureAUT/90/89http://test.corp.test.com:8080/job/FractureAUT/89/88http://test.corp.test.com:8080/job/FractureAUT/88/87http://test.corp.test.com:8080/job/FractureAUT/87/86http://test.corp.test.com:8080/job/FractureAUT/86/85http://test.corp.test.com:8080/job/FractureAUT/85/
Why do I get the output above?

Why are you invoking curl at all? Just retrieve the contents of the URL from groovy:
def xmlString = new URL("http://test.corp.test.com:8080/job/FractureAUT/api/xml").getText()
def projectXML = new XMLSlurper().parseText(xmlString)

XmlSlurper can parse the URL directly:
def projectXml = new XmlSlurper().parse('http://test.corp.test.com:8080/job/FractureAUT/api/xml')

I think the output on screen is because of curl. So can try to silence it with -s or --silent option:
def projectXml = new XmlSlurper().parseText("curl -s 'http://test.corp.test.com:8080/job/FractureAUT/api/xml'".execute().text);

Related

Install Snyk in Jenkins "Global Tool Configuration" using groovy

I'm trying to add a Snyk installation to Jenkins using groovy. The plugin is installed and I can see the installation option in Global Tool Configuration:
The problem is the Descriptor is not available until I manually add the installer and click Save. If I don't do this task manually, which I want to prevent, it causes my code to fail with the following error message "Cannot invoke method setInstallations() on null object"
My code:
import hudson.model.*
import jenkins.model.*
import hudson.tools.*
import hudson.tasks.*
import io.snyk.jenkins.tools.SnykInstaller
import io.snyk.jenkins.tools.SnykInstallation
def snyk_name = "Snyk"
def snyk_home = ""
def snyk_installer = new SnykInstaller("", "latest", 24)
def snyk_properties = new InstallSourceProperty([snyk_installer])
def instance = Jenkins.getInstance()
println("[init.groovy.d] START Configuring Snyk Installation...")
// Get the GlobalConfiguration descriptor of Snyk plugin.
def snyk_conf = instance.getDescriptor("io.snyk.jenkins.SnykStepBuilder.SnykStepBuilderDescriptor")
def snyk_inst = new SnykInstallation(
snyk_name,
snyk_home,
[snyk_properties]
)
// Only add the new Snyk setting if it does not exist - do not overwrite existing config
def snyk_installations = snyk_conf.getInstallations()
def snyk_inst_exists = false
snyk_installations.each {
installation = (SnykInstallation) it
if (snyk_inst.getName() == installation.getName()) {
snyk_inst_exists = true
println("Found existing installation: " + installation.getName())
}
}
if (!snyk_inst_exists) {
snyk_installations += snyk_inst
snyk_conf.setInstallations((SnykInstallation[]) snyk_installations)
snyk_conf.save()
}
// Save the state
instance.save()
println("[init.groovy.d] END")
Is there any way to do what I want programmatically?
After testing your groovy on my local Jenkins (v 2.263.1) I came up with the below which then worked for me:
import hudson.model.*
import jenkins.model.*
import hudson.tools.*
import hudson.tasks.*
import io.snyk.jenkins.tools.*
def instance = Jenkins.getInstance()
def snyk_name = "SnykLatest"
def snyk_home = ""
def snyk_installer = new SnykInstaller("", "latest", 24L, null)
def snyk_properties = new InstallSourceProperty([snyk_installer])
println("[init.groovy.d] START Configuring Snyk Installation...")
// Get the GlobalConfiguration descriptor of Snyk plugin.
def snyk_conf = instance.getDescriptor("io.snyk.jenkins.tools.SnykInstallation")
def snyk_inst = new SnykInstallation(
snyk_name,
snyk_home,
[snyk_properties]
)
// Only add the new Snyk setting if it does not exist - do not overwrite existing config
def snyk_installations = snyk_conf.getInstallations()
def snyk_inst_exists = false
snyk_installations.each {
installation = (SnykInstallation) it
if (snyk_inst.getName() == installation.getName()) {
snyk_inst_exists = true
println("Found existing installation: " + installation.getName())
}
}
if (!snyk_inst_exists) {
snyk_installations += snyk_inst
snyk_conf.setInstallations((SnykInstallation[]) snyk_installations)
snyk_conf.save()
}
// Save the state
instance.save()
println("[init.groovy.d] END")
In basic Terms the SnykInstaller was expecting 4 values not 3. Groovy also took the 3rd value as an Integer when it was expecting a Long Value.
References:
https://javadoc.jenkins.io/plugin/snyk-security-scanner/io/snyk/jenkins/tools/SnykInstaller.html
https://github.com/jenkinsci/snyk-security-scanner-plugin/blob/master/src/main/java/io/snyk/jenkins/tools/SnykInstaller.java
https://github.com/jenkinsci/snyk-security-scanner-plugin/blob/master/src/main/java/io/snyk/jenkins/tools/PlatformItem.java

Dynamically add path in Groovy

I'm trying to add new functionality, without refactoring the entire code. Actually the code calls msg.typeOfMsg('msg'), but I want to add validation when it comes true change all the typeOfMsg to a specific type:
def specialRule = true
def message = changeMessageType()
def changeMessageType() {
def toInform = { def message -> thePath.toChange.inform(message) }
return specialRule ? [reprove : toInform, approve : toInform] : thePath.toChange
}
println(message.reprove('Standart reprove message')
This is the solution I found, it works, but I have a lot of message types and custom message types, there's some way to dynamically change all calls to inform, without refactoring all the code to calls something like message(typeOfMessage, message)?
-----Edit-----
Here's a runnable version
def message = changeMessageType()
def changeMessageType() {
def originalPath = new OriginalPath()
def specialRule = true
def toInform = { def message -> originalPath.inform(message) }
return specialRule ? [reprove : toInform, approve : toInform] : originalPath
}
message.approve('Standart reprove message')
class OriginalPath {
def reprove(message) {
println "Reprove: ${message}"
}
def approve(message) {
println "Approve: ${message}"
}
def inform(message) {
println "Inform: ${message}"
}
}

How to minimize the complexity of this code ,by avoiding it to traverse all the jenkins job(lets say 5000 jobs?)

I'm changing my jenkins job's SCM url from, lets say gitlab to github by using Groovy script. Is there any way to minimize the complexity of this code ?
I have used Jenkins.instance.items.each {} which traverses through all the jobs in my jenkins
import hudson.plugins.git.*
import jenkins.*
import jenkins.model.*
def modifyGitUrl(url) {
def newurl = url.replace("source", "destination")
return newurl
}
def modifyGitID(credentialsId) {
def newID = ("Jenkins User ID")
return newID
}
Jenkins.instance.items.each {
if(it.name == "expected name"){
if (it.scm instanceof GitSCM) {
def oldScm = it.scm
def newUserRemoteConfigs = oldScm.userRemoteConfigs.collect {
new UserRemoteConfig(modifyGitUrl(it.url), it.name, it.refspec, modifyGitID(it.credentialsId))
}
def newScm = new GitSCM(newUserRemoteConfigs, oldScm.branches, oldScm.doGenerateSubmoduleConfigurations,
oldScm.submoduleCfg, oldScm.browser, oldScm.gitTool, oldScm.extensions)
it.scm = newScm
it.save()
}
}
}

extract parameters from a jenkins previous build

I am working on Jenkins version 2.32.1 pipeline. I want to extract the parameters that were chosen in the previous build of my job.
In our previous Jenkins instance ( 1.627 ) we were using jenkins.model.Jenkins.instance.getItem(job).lastBuild.getBuildVariables().get(param);
For some reason this is not working in this version (I also tried disabling the sandbox).
Any pointers on how to accomplish it?
Simplified version of the previous script:
def build = Jenkins.get().getItems(org.jenkinsci.plugins.workflow.job.WorkflowJob).find {it.displayName == 'YOUR_JOB_NAME_HERE'}?.getLastBuild()
build.actions.find{ it instanceof ParametersAction }?.parameters.each {echo "${it.name}=${it.value}"}
Actually a little bit shorter version for those who want to get the params for the current build from the previous run and is working on new 2+ Jenkins versions.
To get 1 particular parameter:
def cls = currentBuild.getPreviousBuild().getRawBuild().actions.find{ it instanceof ParametersAction }?.parameters.find{it.name == 'cls'}?.value
Get all params respectfully:
def cls = currentBuild.getPreviousBuild().getRawBuild().actions.find{ it instanceof ParametersAction }?.parameters
Something like this might work, based on https://stackoverflow.com/a/19564602/3920342:
def h = hudson.model.Hudson.instance
def r = null
h.getItems(org.jenkinsci.plugins.workflow.job.WorkflowJob).each {project ->
if (project.displayName.equals('YOUR_JOB_NAME')) {
r = project
}
}
r.getBuilds().findAll { b -> // here we loop over all past builds, apply some filter if necessary
def p = b?.actions.find{ it instanceof ParametersAction }?.parameters
p.each {
echo "parameter ${it.name}: ${it.value}"
}
}
For those who are not able to access getActions() due to admin permissions i.e. facing the following error:
Scripts not permitted to use method hudson.model.Actionable getActions
They can copy the parameter variables to the env and get them using build.previousBuild.buildVariables
stage('Prepare environment') {
steps {
script {
env.MY_PARAM_COPY = "${MY_PARAM}"
}
}
}
println("MY_PARAM in previous build: ${currentBuild.previousBuild.buildVariables["MY_PARAM_COPY"]}")
That's how I made it works, answer from #dan.goriaynov and #jherb caused some CPS closure issues for me.
(the gist of the code is to allow only greater TAG number than the previous one to be deployed)
stage('Validate build number') {
def previous_build = currentBuild.getPreviousBuild().getRawBuild();
def PREVIOUS_TAG = '';
for (int i = 0; i < previous_build.allActions.size(); i++) {
if (previous_build.allActions[i] in hudson.model.ParametersAction) {
PREVIOUS_TAG = previous_build.allActions[i].getParameter("TAG").value
}
}
if (PREVIOUS_TAG.toInteger() > TAG.toInteger()) {
echo PREVIOUS_TAG
error('TAG number needs to be greater than the previous one')
}
}

commonsMultipartFile trouble

Hi I have am trying to implement a file upload in my application where the file uploaded is parsed and an entry is created in the database using that information.
def save = {
def file = request.getFile("file");
def filename = file.getOriginalFilename();
def type = filename.split('\\.');
if(!file.isEmpty()){
if(type[1] == "properties"){
redirect(action:"parsePropertyFile", params:params);
}
}
}
def parsePropertyFile = {
println "\n"
println params.file;
println "\n";
def f = params.file;
println f;
def filename = f.getOriginalFilename();
println filename;
}
when I print out f this is output:
org.springframework.web.multipart.commons.CommonsMultipartFile#29d32df9
but when I try to call getOriginalFilename() on f I get the following error:
groovy.lang.MissingMethodException: No signature of method:
java.lang.String.getOriginalFilename() is applicable for argument types: () values: []
I also printed out file from the save function and the output of that is also:
org.springframework.web.multipart.commons.CommonsMultipartFile#29d32df9
so why am I getting the error?
Instead of redirecting, can you just call your another function? Redirect will issue an http redirect with the file as param with no need.
if(type[1] == "properties") {
parsePropertyFile(file)
}
And then:
private def parsePropertyFile(def file) {
String filename = file.getOriginalFilename();
...
}
In your parsePropertyFile action you aren't getting a File object, you're getting the String from params. Just like in your save action, you need to do
def f = request.getFile('file')
println f.getOriginalFilename()

Resources