I'm using Extended Choice Parameter plugin to ask user for some parameters.
It has inputs:
Countries
Environments
So, I defined first parameter countries and selected multiple choice and Groovy Script for value.
I posted some script, which gets json, parses it, and it has this in the end:
json.objectEntries.attributes.each { j->
j.objectAttributeValues[4].displayValue.each{ host ->
hosts.add(host+","+j.objectAttributeValues[6].displayValue.join("")+","+j.objectAttributeValues[14].displayValue.join(";") )
}
j.objectAttributeValues[14].displayValue.each{ country -> countries.add(country) }
j.objectAttributeValues[6].displayValue.each{ environment -> environments.add(environment) }
}
Environments = environments.unique(true).join(",")
Hosts = hosts.join(";")
countries.unique(true).each {c -> println c}
Then I added second parameter - Environments.
Almost same as first one, but script now look like that:
Environments.each{ e -> println e}
and from that point everything is fine and I can freely use variables Environments and Countries in later steps.
But I can't pass variable Hosts.
And question is - How to to define variable on first script, so it will pass variable across whole job?
Related
I'm trying to write a Jenkins plugin that provides Step myStep which expects a block with a single parameter per below
myStep { someParameter -> <user code> }
I've found that BodyInvoker ( retrieved from StepContext.newBodyInvoker() ) provides no facilities to invoke the user provided block with parameters.
Expanding the environment would not be ideal, even though the type of the parameter is serializable ( to/from String ), i'd have to provide additional helpers to carry out this serialization, e.g
myStep { deserialize "${env.value}" <user code> }
do i have any other option to pass a non-string type in to the provided block? would type information of the parameter survive even if i did?
nb: i understand you can return a value from your Execution.run() which will be the return value of the step in the pipeline. It's just that in a related shared pipeline library i'm already heavily leaning in to this pattern of:
withFoo { computedFoo ->
# something with computedFoo
withBar computedFoo { computedBar ->
}
}
i prefer this over
computedFoo = withFoo
# something with computedFoo
withBar(computedFoo)
..then again, i couldn't find any plugins pulling this off.
no matter how close i look at workflow-step-api-plugin this doesn't seem possible today. The options are:
expand the environment context with a string value
add a custom object to the context ( requires access to step context in pipeline )
use a return value
My requirement is that I have written a bash script which monitors telnet on several ip(s) and ports. I have used the CSV which contains the input data and the script will read each row in the CSV and checks if the ip(s) can be telnet.
However I have requirement to jenkinize it, and I am wondering if there a way I can define my parameter in the Jenkins Job with different combination or values
say for example:
PARAM_KEY : VAL_1
PARAM_KEY : VAL_2
PARAM_KEY : VAL_3
and so on thus I can use the PARAM_KEY in the script and the Jenkins job gets executed for all the parameters defined i.e. based on the number of PARAMETERS defined i.e. 3 in above case.
Can any one guide me on this requirement.
If you mean to run 1 job and iterate over the ips inside, you can parse the CSV file inside a pipeline or pass it as a parameter ( and then split it )
// example of pipeline code
node ('slave80') {
csvString = "1.1.1.1,2.2.2.2,3.3.3.3" // can be sent as parameter
def ips = csvString.split(',')
ips.each { ip ->
sh """
./bash_script ${ip}
"""
}
}
I am new to Jenkins pipeline scripting. I am developing a Jenkins pipeline in which the Jenkins code is as follows. The logic looks like this:
node{
a=xyz
b=abc
//defined some global variables
stage('verify'){
verify("${a}","${b}")
abc("${a}","${b}")
echo "changed values of a and b are ${a} ${b}"
}}
def verify(String a, String b)
{ //SOme logic where the initial value of a and b gets changed at the end of this function}
def verify(String a, String b){
//I need to get the changed value from verify function and manipulate that value in this function}
I need to pass the initial a and b(multiple) values to the verify function and pass the changed value on to the other function. I then need to manipulate the changed value, and pass it to the stage in the pipeline where echo will display the changed values. How can I accomplish all this?
Ok, here's what I meant:
def String verify_a(String a) { /* stuff */ }
def String verify_b(String b) { /* stuff */ }
node {
String a = 'xyz'
String b = 'abc'
stage('verify') {
a = verify_a(a)
b = verify_b(b)
echo "changed values of a and b are $a $b"
}
stage('next stage') {
echo "a and b retain their changed values: $a $b"
}
}
The easiest way I have found to pass variables between stages is to just use Environment Variables. The one - admittedly major - restriction is that they can only be Strings. But I haven't found that to be a huge issue, especially with liberal use of the toBoolean() and toInteger() functions. If you need to be passing maps or more complex objects between stages, you might need to build something with external scripts or writing things to temporary files (make sure to stash what you need if there's a chance you'll switch agents). But env vars have served me well for almost all cases.
This article is, as its title implies, the definitive guide on environment variables in Jenkins. You'll see a comment there from me that it's really helped me grok the intricacies of Jenkins env vars.
I have a pipeline job running in Jenkins and I want to know the name of the node it's running on. Is there a way to get the node name from within the job's Groovy script?
I have tried the below code:
print currentBuild.getBuiltOn().getNodeName()
the error is:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method org.jenkinsci.plugins.workflow.job.WorkflowRun getBuiltOn
I also tried this:
def build = currentBuild.build()
print build.getExecutor().getOwner().getNode().getNodeName()
but the result is ''.
There is an environment variable 'NODE_NAME' which has this.
You can access it like this:
echo "NODE_NAME = ${env.NODE_NAME}"
When you are editing a pipeline job, you can find all the available environment variables by going to the "pipeline syntax" help link (left of page) then look for the "Global Variables" section and click through to the "Global Variables Reference". There is a section "env" that lists the environment variables available.
It is not documented, but indeed Node and Executor objects can be obtained from CpsThread class of the pipeline. Of course, they are defined only inside node { } block:
import org.jenkinsci.plugins.workflow.cps.CpsThread;
#NonCPS
obtainContextVariables() {
return CpsThread.current().getContextVariables().values;
}
node('myNode') {
print('Node: ' + obtainContextVariables().findAll(){ x -> x instanceof Computer }[0].getNode())
print('Executor: ' + obtainContextVariables().findAll(){ x -> x instanceof Executor }[0])
}
This is my requirement to have parameters in Jenkins:
1. User selects 3 Values from Dropdown: DEV, QA, PROD
2. Upon selection I need to return single value as parameter as like this:
If DEV selected, return "Development http://dev.com 1"
If QA selected, return "QA http://qa.com 2"
If PROD selected, return "Production http://prod.com 3"
3. Once the value is returned in a variable, I will use that variable value in next step of 'Windows batch command'.
Where and How can define Key/Values. I tried to use Extended Choice Parameter plugin, but not sure how to do this.
I have managed to get the keys/values with a dropdown select parameter working with the Active Choices Plugin, it's not as complicated as the other answer here, and it actually buried in the comments on the plugin page itself.
To get a key/value pair select dropdown list parameter in Jenkins (i.e. show a human readable value, but pass a different key to the build. You simply need to use a map rather than a list when writing your groovy script. The map key is what the parameter will be set to if the user selects this option. The map value is what will be actually displayed to the user in the dropdown list.
For example the script: return ['Key1':'Display 1', 'Key2':'Display 2', 'Key3':'Display 3'] will display a dropdown containing: Display1, Display2 and Display3 to the user. However the build parameter will actually be set to Key1, Key2 or Key3 depending on what is selected.
For this specific question, here are the steps.
Ensure you have the Active Choices Plugin installed.
Open the configuration of your Jenkins job, select This project is parameterised.
Click Add Parameter and select Active Choices Parameter.
Name your parameter and click the Groovy Script check box.
In Groovy Script enter content: return ['Development http://dev.com 1':'DEV', 'QA http://qa.com 2':'QA', 'Production http://prod.com 3':'PROD'] For this example the user will see a dropdown with 3 options: DEV, QA, and PROD. The value passed for this parameter will be Development http://dev.com 1 etc. Now having a parameter with space and URLs may cause issue depending on how you use it later on in the build, but the concept is really what I'm trying to illustrate.
This can be achieved using the Active choice plugin, Find below the link and the image for your reference
Plugin reference: https://wiki.jenkins-ci.org/display/JENKINS/Active+Choices+Plugin
Another method without any plugins
Using shell script this can be achieved
Add a build step as shell script and add the below script that will return your values. Lets say the dropdown paramater name is "env"
if [ $env == "DEV" ]
then
url = "Development http://dev.com 1"
elif [ $env == "QA" ]
then
url = "QA http://qa.com 2"
elif [ $env == "PROD" ]
then
url = "Production http://prod.com 3"
fi
The $url variable will be having the expected value that can be used in your next build steps
Shell Script Reference: http://www.tutorialspoint.com/unix/if-elif-statement.htm
You can do the mapping in a groovy script. If you have a parameter named InputParam, you can map it to a new parameter called OutParam in a System Groovy Script like so:
import hudson.model.*
def parameterMap=[:]
parameterMap.put('DEV','Development http://dev.com 1')
parameterMap.put('QA','QA http://qa.com 2')
parameterMap.put('PROD','Production http://prod.com 3')
def buildMap = build.getBuildVariables()
def inputValue=buildMap['InputParam']
buildMap['OutParam']=parameterMap[inputValue]
setBuildParameters(buildMap)
def setBuildParameters(map) {
def npl = new ArrayList<StringParameterValue>()
for (e in map) {
npl.add(new StringParameterValue(e.key.toString(), e.value.toString()))
}
def newPa = null
def oldPa = build.getAction(ParametersAction.class)
if (oldPa != null) {
build.actions.remove(oldPa)
newPa = oldPa.createUpdated(npl)
} else {
newPa = new ParametersAction(npl)
}
build.actions.add(newPa)
}
Choose Execute system Groovy script as the first build action. You can then access the output param as an environmental variable in the windows shell, eg.
ECHO %OUTPARAM%