Getting a second parameter based on the first parameter in Jenkins - jenkins

I have a task where my Jenkins job needs two parameters for build. The first specifies the application name and can be either QA, Dev, Prod etc and the second is a server which is dependent on the first one.
Example: If I chose the app name as QA, the second parameter should display values like QAServer1, QAServer2, QAServer3.
I'm using Active Choices Plugin (https://wiki.jenkins.io/display/JENKINS/Active+Choices+Plugin) to get this done but facing an problem in fetching the second parameter contents.
Snapshots:
For obtaining the second parameter, I've written a Groovy code which reads the respective files of the selected first parameter and gets the details.
code:
#!/usr/bin/env groovy
import hudson.model.*
def Appliname = System.getenv("APPNAME")
//println Appliname
def list1 = []
def directoryName = "C:/Users/Dev/Desktop/JSONSTest"
def fileSubStr = Appliname
def filePattern = ~/${fileSubStr}/
def directory = new File(directoryName)
def findFilenameClosure =
{
if (filePattern.matcher(it.name).find())
{
def jsoname = it.name
def jsoname1 = jsoname.reverse().take(9).reverse()
list1.add(jsoname1.substring(1,4))
String listAsString = "[\'${list1.join("', '")}\']"
println "return"+listAsString
}
}
directory.eachFileRecurse(findFilenameClosure)
The above code will print the output as return['QAServer1', 'QAServer2'] which i want to use it as input for the second parameter.
Snapshot of Second parameter:
Somehow the Groovy script is not being executed and second parameter value remains empty. How can i get this done dynamically. Am i following the right away to it. Kindly help me figure out. TIA

Would you like to try below change
From:
def findFilenameClosure =
{
if (filePattern.matcher(it.name).find())
{
def jsoname = it.name
def jsoname1 = jsoname.reverse().take(9).reverse()
list1.add(jsoname1.substring(1,4))
String listAsString = "[\'${list1.join("', '")}\']"
println "return"+listAsString
}
}
directory.eachFileRecurse(findFilenameClosure)
To:
directory.eachFileRecurse {
if (filePattern.matcher(it.name).find()) {
def jsoname = it.name
def jsoname1 = jsoname.reverse().take(9).reverse()
list1.add(jsoname1.substring(1,4))
}
}
return list1

Related

Jenkins: Set job timeout from a variable in scripted pipeline

I premise that I am not very familiar with Jenkins and Groovy.
I am trying to set a timeout with a time value that can change based on a specific condition. I was wondering if it is possible to do this and how.
This is a shortened example for simplicity, of the pipeline I'm dealing with:
/**
* prepare tests for parallel
* #param filename Name of the file that contains the testsuites list
*/
def doDynamicParallelSteps(filename){
tests = [:]
echo "doDynamicParallelSteps"
def w = pwd()
def path = "$w/$filename"
// read all the lines into a list, each line is an element in the list
def fh = new File(path)
def lines = fh.readLines()
for (line in lines) {
def values = line.split(":")
def testsuite_name = values[0].trim()
def test_path = values[1].trim()
def test_filename_or_directory = test_path.split("/").getAt(-1);
def is_file = test_filename_or_directory.matches("(.*).php")
def is_custom_mycondition = test_filename_or_directory.matches("MyMatchCondition")
if (is_custom_mycondition){ // large timeout
def time_val = 10
} else { // default timeout
def time_val = 5
}
tests["${test_filename_or_directory}"] = {
stage("UnitTest ${test_filename_or_directory}") {
timeout(time: time_val, unit: 'MINUTES') { // scripted syntax
// other stuff here
} // end timeout
} // end stage
} // end MAP
}
parallel tests
}
If I run this pipeline I got the following output:
hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: time_val for class: mycustomJob
Then I've tried to set it as global value and it worked but not as expected, because its value doesn't seems to changed, it outputs "5" ignoring my condition.
What am I doing wrong? Can anyone show me the right way or a better approach?
What you are doing looks more pythonic than groovy. You must define the variable 'time_val' on a higher level to make it visible in your scope, like:
def time_val = 5
if (is_custom_mycondition){ // large timeout
time_val = 10
}
Instead of your else part.
You can also define it in a single line, like:
def time_val = is_custom_mycondition ? 10 : 5
Your 'timeout' usage looks correct to me. Just define the variable properly.

Groovy Variable $ Dollar Sign in JSON

I've got a JSON file that I am slurping with groovy.
{
"team": "${GLOBAL_TEAM_NAME}",
"jobs": [
{
In the JSON above is a property 'team' that contains a groovy-like variable I want to be resolved at runtime.
teamList.each { tl ->
try
{
def teamSlurper = new JsonSlurperClassic()
def t = teamSlurper.parseText(tl.text)
println "*********************"
println "PROVISIONING JOB FOR: " + t.team
Output:
PROVISIONING JOB FOR: ${GLOBAL_TEAM_NAME}
The above outputs the raw value, but I would like it to resolve the global variable that has been defined for the system.
How can I resolve ${GLOBAL_TEAM_NAME} to its actual system value?
You can do this with Groovy Templates.
def slurper = new groovy.json.JsonSlurperClassic()
def engine = new groovy.text.SimpleTemplateEngine()
def binding = ["GLOBAL_TEAM_NAME": "Avengers"]
def json = '{"team":"${GLOBAL_TEAM_NAME}"}'
def t = slurper.parseText(engine.createTemplate(json).make(binding).toString())
t.team // "Avengers"

Jenkins Groovy with XMLSlurper Error "failed to serialize"

I am on Jenksin 2.46.2 and have a job that uses Active Choices Reactive Parameter. I select my servers in my first selection from a XML file using XMLSlurper and reference that for my second selection. When I hardcode the server name the code works fine. When I use the variable in my code I get an error.
This code works:
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
def SERVER = 'testserver1'
def output = []
serverList.Server.find { it.#name == SERVER}.CleanUp.GZIP.File.each{
it.output.add(p)
}
return output
When I reference the variable selection from my previous selection I get the error:
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
def SERVER = SERVER
def output = []
serverList.Server.find { it.#name == SERVER}.CleanUp.GZIP.File.each{
it.output.add(p)
}
return output
The error that I am getting is below. Any idea why I get an error?
WARNING: failed to serialize [[/app/test2/log], [/app/test2/log]] for ...*other text*... net.sf.json.JSONException: There is a cycle in the hierarchy!
Here is my XML file:
<ServerList>
<Server name="testserver1">
<CleanUP>
<GZIP>
<File KeepDays="30">/app/test1/log</File>
</GZIP>
</CleanUP>
</Server>
<Server name="testserver2">
<CleanUP>
<GZIP>
<File KeepDays="30">/app/test2/log</File>
</GZIP>
</CleanUP>
</Server>
</ServerList>
NE.jpg
Here is the script that you need, which reads the value of File element and returns a list:
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
return serverList.'**'.findAll{ it.name() == 'File'}*.text()
Output:
[/app/test1/log, /app/test2/log]
EDIT: based on OP comments
def server = 'testserver1'
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
def result = serverList.'**'.find{ it.#name == server}.CleanUP.GZIP.File
println result
return result
EDIT2:
If you want list or array, try below:
def server = 'testserver1'
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
def result = serverList.'**'.findAll{ it.#name == server}*.CleanUP.GZIP.File.text()
println result
return result

Grails 3 Cookie Plugin - return Null

i am trying to use cookie in grails 3.
i tried this plugin but i don't know why its not work at all..
cookieService.setCookie('username', customer?.email)
and i use this code for call it from gsp
<g:cookie name="username"/>
i also tried this way..
def cokusername = cookieService.setCookie('username', customer?.email)
println "cookieService.getCookie('username') = "+cookieService.getCookie('username')
redirect(controller: "toko",cokusername: cokusername)
and this is in my tokoController.groovy index :
def index={
def toko = CifLogo.executeQuery("from CifLogo order by rand()",[max: 10])
// def itemRandom = Item.executeQuery("from Item where cif = :cif order by rand()",[max:12,cif:cif])
def awdf = cookieService.getCookie('username')
println "awdf = "+awdf
println "cokusername = "+params.cokusername
[tokoList:toko,cokusername:awdf]
}
i have no idea to retrieve my cookie. :(
update
def index(){
def toko = CifLogo.executeQuery("from CifLogo order by rand()",[max: 10])
// def itemRandom = Item.executeQuery("from Item where cif = :cif order by rand()",[max:12,cif:cif])
def awdf = cookieService.getCookie('username')
println "awdf = "+awdf
println "cokusername = "+params.cokusername
[tokoList:toko,cokusername:awdf]
}
i tried to print cookie like this..
def awdf = request.getCookie('username')
println "awdf = "+awdf
println "cokusername = "+params.cokusername
request.cookies.each { println "${it.name} == ${it.value}" }
and this is what the result
From what I can see this line:
redirect(controller: "toko",cokusername: cokusername)
Should be:
redirect(controller: "toko",params:[cokusername: cokusername])
Also actions using closures in grails 3 will have undesired results. You should change to methods. Hence this line:
def index={
SHould be:
def index(){
Apart from this it seems the cookieService code should work fine, so I can only assume its being caused my the closure index that should be a method.
Another thing could be the fact that you are doing a redirect, which will clear the request and not persist any cookies that were set before the redirect
I don't know why, but maybe it's a bug.
i use this code to setCookie
cookieService.setCookie(name:"username", value: customer?.email, maxAge: 24*60*60, path: "/")
after read this code.
and i cannot deleteCookie with this code.
cookieService.deleteCookie(cookieService.findCookie("username"))
because when i print cookieService.findCookie("username") it returns javax.servlet.http.Cookie#78cbf320
and method deleteCookie(Cookie cookie) from this link
so i think it mustbe deleted.
but still availlable.
so i can answer this question about setCookie not deleteCookie
i also tried this way to delete cookie..but still failed.
CookieService.setCookie(name:"username", value: "", maxAge: 0, path: "/")

why is groovy skipping the each statement

I have the following controller action in grails to determine if an item is in my shopping cart
def itemInCart(){
def cartHasItem = false
def product = Product.findOrCreateByPartNumberAndColor(params.partNumber, params.color)
def cart = shoppingCartItems()
cart.each() { item ->
if (item['partInfo']['partNumber'] == params.partNumber && item['partInfo']['color']==params.color){
cartHasItem = true
}
}
render(cartHasItem)
}
I added an item to the cart
cart at the time of cart.each() is
[{partInfo={partNumber=69874, color=BLACK}, qty=1, price=16.99}]
params.partNumber = 69874
params.color = BLACK
The issue is that my code is completely skipping over the each() block. debug hits cart.each() { item -> and then goes streight to render
Looks like you want to use any instead of each here:
def cartHasItem = cart.any{ item ->
item['partInfo']['partNumber'] == params.partNumber && item['partInfo']['color']==params.color
}
I wanted to expand on #Dónal's comment on the question, to find out why each() vs each is different.
I've never used object.each() {}, instead I always use this form:
cart.each { item ->
// do work
}
However, I couldn't actually get each() to fail in this simple test:
def myfn() {
def items = [1,2,3]
def ret = false
items.each() {item -> if (item == 2) { ret = true }}
return ret
}
myfn()
==> true
I tried a more complicated version using a map to represent the data you are using, and a simple version just using
[[a:1, b:2, c:3]].each() { println it }
which always renders the item.
What version of groovy are you using?
I'm assuming your data is actually a list of maps here, your syntax for the item was more clojure, than groovy.

Resources