Groovy Script failing in Jenkins job but runs fine from command line - jenkins

I have the following Managed Jenkinsfile for Pipeline Job stripped of the Stages for brevity.
#!groovy
import groovy.json.JsonSlurperClassic
def json = new File("TEST_JSON.json").text
def data = new JsonSlurperClassic().parseText(json)
def string_1 = data.test
properties([
parameters([
string(defaultValue: string_1, description: 'STRING 1', name: 'STRING_1', trim: false),
string(defaultValue: string_1, description: 'STRING 2', name: 'STRING_2', trim: false),
[$class: 'ChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'MPSS Flavor',
filterLength: 1, filterable: true,
name: 'MPSS_FLAVOR', randomName: 'choice-parameter-10980926894589',
script: [
$class: 'GroovyScript',
fallbackScript: [classpath: [], sandbox: false, script: ''],
script: [
classpath: [], sandbox: false,
script: '''
import groovy.json.JsonSlurperClassic
def json = new File("TEST_JSON.json").text
def data = new JsonSlurperClassic().parseText(json)
mpss_flavors = []
for (option in data.options) {
println option
mpss_flavors.add(option.mpss_flavor)
}
return mpss_flavors
'''
]
]
],
[$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'TARGET',
filterLength: 1, filterable: true,
name: 'TARGET', randomName: 'choice-parameter-10980967122105',
referencedParameters: 'MPSS_FLAVOR',
script: [
$class: 'GroovyScript',
fallbackScript: [classpath: [], sandbox: false, script: ''],
script: [
classpath: [], sandbox: false,
script: '''
import groovy.json.JsonSlurperClassic
def json = new File("TEST_JSON.json").text
def data = new JsonSlurperClassic().parseText(json)
targets = []
for (option in data.options) {
if (option.mpss_flavor == MPSS_FLAVOR) {
targets.add(option.target);
}
}
return targets;
'''
]
]
],
[$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Build Command',
filterLength: 1, filterable: true,
name: 'BUILD_CMD', randomName: 'choice-parameter-11980967122105',
referencedParameters: 'TARGET,MPSS_FLAVOR',
script: [
$class: 'GroovyScript',
fallbackScript: [classpath: [], sandbox: false, script: 'return ["ERROR"]'],
script: [
classpath: [], sandbox: false,
script: '''
import groovy.json.JsonSlurperClassic;
def json = new File("TEST_JSON.json").text;
def data = new JsonSlurperClassic().parseText(json);
build_cmds = [];
for (option in data.options) {
if ((option.mpss_flavor == MPSS_FLAVOR) && (option.target == TARGET)) {
build_cmds.addAll(option.build_commands);
}
}
return build_cmds;
'''
]
]
]
])
])
And the following JSON File containg the configurations
{
"test": "TEST STRING FROM JSON",
"options": [
{
"mpss_flavor": "MPSS1",
"target": "TARGET1",
"build_commands": [
"BUILD_COMMAND_1"
]
},
{
"mpss_flavor": "MPSS2",
"target": "TARGET2",
"build_commands": [
"BUILD_COMMAND_2",
"BUILD_COMMAND_3"
]
}
]
}
I would like to configure the Parameters for the Job automatically when the JOSN file is updated (I am fully aware that the first Job run after the JSON Update will not contain the intended changes, but that is Ok for us). MPSS_FLAVOR and TARGET are showing the Values as intended. However the BUILD_CMD Choice parameter is returning an error. When I run the groovy script code with Statically defined MPSS_FLAVOR and TARGET in command line the Script works fine and the returned build_cmds are as expected. However Through Jenkins UI It is showing as ERROR (Fallback Script)
I have tried several iterations without any success. I am sure there is a minor mistake and I Could Figure out.
My Question is there any way to see the print Logs of the script that is used for choice parameter to isolate the issue.
Update
Same code works fine for Jenkins file defined within the Job. issue seems to be specific to Managed Jenkins file

just wrap script with try-catch
try{
...your parameter script here
}catch(Throwable t){
return [t.toString()]
}
in this case you'll see error as a parameter value

Related

Cannot return the file value as list in jenkins active choice reference parameter script in jenkins

Hello I have the following code as my Jenkinsfile.
pipeline {
agent any
parameters{
string(name: 'IP_ADDRESS', defaultValue: '', description: 'Enter server IP address')
string(name: 'USERNAME', defaultValue: '', description: '')
string(name: 'PASSWORD', defaultValue: '', description: '')
}
environment{
VERSION='1.3.0'
}
stages {
stage('Build') {
steps {
echo 'Built'
sh(script:"python sshMac.py ${IP_ADDRESS} ${USERNAME} ${PASSWORD}", returnStatus: true, returnStdout: true)
}
}
stage('Test') {
steps {
script{
env.FILENAME = readFile 'macAdds.properties'
env.FILEDATA = FILENAME.tokenize( "," )
input message: 'Please choose one',
parameters: [
[$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select the Environemnt from the Dropdown List',
filterLength: 1,
filterable: false,
name: 'ENVIRONMENT',
script: [$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: 'return ["ERROR"]'
],
script: [
classpath: [],
sandbox: true,
script: """
return['1', '2', '3', '4']
""".stripIndent()
]
]
],
[$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select the Environemnt from the Dropdown List',
filterLength: 1,
filterable: false,
name: 'ENVIRONMENT2',
script: [$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: 'return ["ERROR"]'
],
script: [
classpath: [],
sandbox: true,
script: """
return['1', '2', '3', '4', '5']
""".stripIndent()
]
]
],
[$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select a choice',
filterLength: 1,
filterable: false,
name: 'choice1',
referencedParameters: 'ENVIRONMENT',
script: [$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: 'return ["ERROR"]'
],
script: [
classpath: [],
sandbox: true,
script: """
def tokens = ${FILENAME}.tokenize(',')
switch(ENVIRONMENT) {
case "1":
return ${env.FILEDATA}
case "2":
return ${env.FILEDATA}
case "3":
return ${env.FILEDATA}
case "4":
return ${env.FILEDATA}
}
"""
]
]
],
text(name: 'vertical', defaultValue: "${FILENAME}")
]
}
echo 'Testing'
echo "${FILENAME}"
echo "${FILEDATA}"
}
}
stage('Deploy') {
steps {
echo 'Deploying'
}
}
}
}
So Here I have obtained the values from a file (FILENAME) and split them into a list (FILEDATA). It works perfectly and it prints out and echo too. Actually it returns a set of Mac addresses from a macAdds.properties such as [ff:ff:ee:ee:ee:ff, ff:ee:dd:aa:bb:ee, ff:ee:aa:cc:bb:dd].
But in my active choice reference parameter (choice1) when I returns the FILEDATA value in my switch case as single select it does not work out where it will run fall back script and gives me an error. I have tested returning some random values given manually to the switch statements where it works perfectly. I want to know why I can't return the values in my active choice reference parameter (choice1) script. Help me out!! Thank you
Well I have figured out the answer for this solution. When you are using groovy sandbox value as through you can do many thing without limitations. But you have to approve the script manually from Manage Jenkins => Script Approval. Hope this will help out someone. Thanks!

Access global map variable inside active choice reactive reference parameter

I am trying to set a global map variable in a jenkins declarative pipeline. I am trying to access it inside an Active Choice Reactive Reference parameter. I tried many ways to achieve this but nothing worked.
Below is my sample Pipeline.
def sampleMap= [
'students' : ['12312312'],
'teachers' : ['145436436']
]
pipeline {
agent any
stages {
stage('set params') {
steps{
script {
properties([
parameters([
[
$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: '',
filterLength: 1,
filterable: false,
name: 'Type',
randomName: 'choice-parameter-1325654724334254',
referencedParameters: '',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: ''
], script: [
classpath: [],
sandbox: true,
script: '''
def choices = []
choices.add('students')
choices.add('teachers')
return choices'''
]
]
],
[
$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
description: '',
name: 'value',
randomName: 'choice-parameter-14347325234254',
referencedParameters: 'Type',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: ""
],
script: [
classpath: [],
sandbox: true,
script: '''
def result= ${sampleMap.get(Type)}
return """<input name=\"value\" value=\"${result}\" class=\"setting-input\" type=\"text\">"""
'''
]
],
omitValueField: true
]
])
])
}
}
}
}
As per above script, I have a global Map variable with list of students and list of teachers. I have two build parameters named as Type and value. Type is a dropdown with values 'students' and 'teachers' . Based on the dropdown selection, I want to refer to the global map variable and access it's respective value in another build parameter.
It seems like the active choice parameter is unable to access global variables. Or is that a syntax issue?
Can anyone help?
Thanks!
You should pass whole map into script and call it:
[$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
filterLength: 1,
filterable: false,
name: 'value',
referencedParameters: 'Type',
script: [$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: 'return ["ERROR"]'
],
script: [
classpath: [],
sandbox: true,
script: """
def sampleMap = ${sampleMap.inspect()}
return sampleMap.get(Type)
""".stripIndent()
]
]
]

Jenkins generate new parameters based on another parameter value

I have a choice parameter called 'Data Center' which has two values DC01 and DC02. If user chooses DC01 I want few other build parameters to show up, if he chooses DC02 I want other parameters to show up. Is there any way to do it?
If user chooses DC01, I want two more fields such as 'hostname' and 'IP address' which are just text fields.
I have tried using Active Choice Plugin, but I don't think we can generate text field parameters using that.
Can anyone help?
We can generate text field parameters using Active Choices Plugin.
We will use two types of parameters here: Active Choices Parameter and Active Choices Reactive Reference Parameter
Active Choices Reactive Reference Parameter
In Active Choices Reactive Reference Parameter, there are wide variety of rendering options available, of which one is Formatted HTML i.e. in the return string you can pass the html tags.
So, making use of the above two parameters, here is the pipeline code that will help in your case:
Note: After saving the below pipeline code, first Click on Build Now. After the build got success, then refresh the page. You will be able to see the option Build with Parameters. You can also see in the Job Configuration page, all the fields of This build is parameterized gets populated automatically once you build the job after saving the pipeline.
properties([
parameters([
[$class: 'ChoiceParameter',
choiceType: 'PT_CHECKBOX',
description: 'Select the Application Service from the Dropdown List',
filterLength: 1,
filterable: false,
name: 'data_center',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script:
"return['Could not get the services list']"
],
script: [
classpath: [],
sandbox: false,
script:
"return['DC01', 'DC02', 'DC03']"
]
]
],
[$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
description: 'enter job params',
name: 'hostname',
referencedParameters: 'data_center',
script:
[$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: "return['']"
],
script: [
classpath: [],
sandbox: false,
script: '''
if (data_center.contains('DC01')){
return """<textarea name=\"value\" rows=\"5\" class=\"setting-input \"></textarea>"""
} else
if (data_center.contains('DC02')){
return """<textarea name=\"value\" rows=\"5\" class=\"setting-input \"></textarea>"""
}
'''
]
],
omitValueField: true
],
[$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
description: 'enter job params',
name: 'ipaddress',
referencedParameters: 'data_center',
script:
[$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: "return['']"
],
script: [
classpath: [],
sandbox: false,
script: '''
if (data_center.contains('DC01')){
return """<textarea name=\"value\" rows=\"5\" class=\"setting-input \"></textarea>"""
} else
if (data_center.contains('DC02')){
return """<textarea name=\"value\" rows=\"5\" class=\"setting-input \"></textarea>"""
}
'''
]
],
omitValueField: true
],
[$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
description: 'enter job params',
name: 'port_number',
referencedParameters: 'data_center',
script:
[$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: "return['']"
],
script: [
classpath: [],
sandbox: false,
script: '''
if (data_center.contains('DC02')){
return """<textarea name=\"value\" rows=\"5\" class=\"setting-input \"></textarea>"""
}
'''
]
],
omitValueField: true
]
])
])
pipeline {
environment {
vari = ""
}
agent any
stages {
stage ("Example") {
steps {
script{
echo "${params.data_center}"
echo '\n'
echo "${params.hostname}"
echo "${params.ipaddress}"
echo "${params.port_number}"
}
}
}
}
}
Screenshots:
Output when data center DC01 is selected,
Output when data center DC02 is selected,

Dynamic or Conditional display of Jenkins job's parameters

I am trying to use following jenkins job to generate Active Choices user selectable params for a job.
my ask is to show/hide textbox when heartbeat_consumer checkbox is selected/unselected. I would also like to store the value of user input in heartbeat_consumer_parms, which can be accessed thru env.heartbeat_consumer_parms. I plan to use this value in downstream jobs.
pipeline {
agent any
stages {
stage('Parameters'){
steps {
script {
properties([
parameters([
text(
defaultValue: '''''',
name: 'application_servers',
description: 'Please provide semicolon delimited (;) application server list ',
),
[$class: 'CascadeChoiceParameter',
choiceType: 'PT_CHECKBOX',
description: 'Select Services',
name: 'application_services_list',
referencedParameters: 'application_servers',
script:
[$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: "return['']"
],
script: [
classpath: [],
sandbox: false,
script: '''
if (application_servers.length() > 0){
return["heartbeat_consumer", "surgeon_cloud_login", "system_configuration"]
}
'''
]
]
]
])
])
if (application_services_list.contains('heartbeat_consumer')){
text(
defaultValue: '''''',
name: 'heartbeat_consumer_parms',
description: 'Please provide heartbeatconsumer job parms ',
)
}
}
}
}
}
}
with current implmentation I am not seeing that textbox heartbeat_consumer_parms is being displayed at all.
Pipeline script for your scenario:
properties([
parameters([
[$class: 'ChoiceParameter',
choiceType: 'PT_CHECKBOX',
description: 'Select the Application Service from the Dropdown List',
filterLength: 1,
filterable: false,
name: 'application_services_list',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script:
"return['Could not get the services list']"
],
script: [
classpath: [],
sandbox: false,
script:
"return['heartbeat_consumer', 'surgeon_cloud_login', 'system_configuration']"
]
]
],
[$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
description: 'SAdd params',
name: 'heartbeat_consumer_parms',
omitValueField: 'true',
referencedParameters: 'application_services_list',
script:
[$class: 'GroovyScript',
script: 'return["Could not get Information"]',
script: [
script: '''
if (application_services_list.equals("heartbeat_consumer")){
inputBox="<input type ='text' id = 'myText' name='value' >"
return inputBox
}
'''
]
]
]
])
])
pipeline {
environment {
vari = ""
}
agent any
stages {
stage ("Example") {
steps {
script{
echo "${params.application_services_list}"
echo '\n'
echo "${params.heartbeat_consumer_parms}"
}
}
}
}
}
Please find the screenshot of the output:
Output of pipeline after build:
this worked for me,
pipeline {
agent any
stages {
stage('Parameters'){
steps {
script {
properties([
parameters([
text(
defaultValue: '''''',
name: 'application_servers',
description: 'Please provide semicolon delimited (;) application server list ',
),
[$class: 'CascadeChoiceParameter',
choiceType: 'PT_CHECKBOX',
description: 'Select Services',
name: 'application_services_list',
referencedParameters: 'application_servers',
script:
[$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: "return['']"
],
script: [
classpath: [],
sandbox: false,
script: '''
if (application_servers.length() > 0){
return["heartbeat_consumer", "surgeon_cloud_login", "system_configuration"]
}
'''
]
]
],
[$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
description: 'enter job params',
name: 'hb_job_params',
referencedParameters: 'application_services_list',
script:
[$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: "return['']"
],
script: [
classpath: [],
sandbox: false,
script: '''
if (application_services_list.contains('heartbeat_consumer')){
return """<textarea name=\"value\" rows=\"5\" class=\"setting-input \"></textarea>"""
}
'''
]
],
omitValueField: true
],
])
])
}
}
}
}
}
I used, DynamicReferenceParameter for using HTML generated textarea however accessing entered textarea values was tricky. after a bit of researching I found that,
The trick for formatting a text input box is to format the HTML in a way that reflects the HTML Jenkins uses to display parameters in a job submission form. The easiest way to do this is to review the HTML Jenkins uses to display an existing String parameter.
src: https://github.com/biouno/uno-choice-plugin/wiki/Using-Uno-Choice-for-Dynamic-Input-Text-Box-Defaults

How to pass variables into Groovy script executed in Jenkins pipeline parameter?

I have a consul keys AAA/BBB/test-key like '1,2,3', AAA/CCC/test-key like '4,5,6' and others.
I have a shared Jenkinsfile between several jobs.
I do not want to make Jenkinfile per each job. I want to access keys by job name but I can't make it working.
It works if I hardcode key in the URL, e.g.
node('master') {
properties([parameters([
[ $class: 'ChoiceParameter',
name: 'GROUPS',
description: 't2',
randomName: 't3',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [], sandbox: false, script: ''
],
script: [
classpath: [], sandbox: false, script:
'''
def text = new URL('http://consul.local:8500/v1/kv/AAA/BBB/test-key?raw').getText()
return text.split(",").collect{ (it=~/\\d+|\\D+/).findAll() }.sort().collect{ it.join() } as List
'''
]
],
choiceType: "PT_RADIO", //PT_SINGLE_SELECT,PT_MULTI_SELECT,PT_RADIO,PT_CHECKBOX
filterable: true,
filterLength: 1
]
])])
}
However, when I try to use env.JOB_NAME inside the URL, it does not work:
node('master') {
properties([parameters([
[ $class: 'ChoiceParameter',
name: 'GROUPS',
description: 't2',
randomName: 't3',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [], sandbox: false, script: ''
],
script: [
classpath: [], sandbox: false, script:
'''
def text = new URL('http://consul.local:8500/v1/kv/AAA/'+ env.JOB_NAME + '/test-key?raw').getText()
return text.split(",").collect{ (it=~/\\d+|\\D+/).findAll() }.sort().collect{ it.join() } as List
'''
]
],
choiceType: "PT_RADIO", //PT_SINGLE_SELECT,PT_MULTI_SELECT,PT_RADIO,PT_CHECKBOX
filterable: true,
filterLength: 1
]
])])
}
How can I access env variables inside the choice parameter defined with the Groovy script?
If you want to pass env.JOB_NAME to the script content you have to replace ''' with """ and refer to the variable with ${env.JOB_NAME}. Something like this:
script: [
classpath: [], sandbox: false, script:
"""
def text = new URL('http://consul.local:8500/v1/kv/AAA/${env.JOB_NAME}/test-key?raw').getText()
return text.split(",").collect{ (it=~/\\d+|\\D+/).findAll() }.sort().collect{ it.join() } as List
"""
]
Yes after changing ''' to """,my issue got resolved.
And also by using ${abc}
Thanks #szymon-stepniak but ${env.JOB_NAME} does not work in ChoiceParameter
Next code works well
node('master') {
properties([parameters([
[ $class: 'ChoiceParameter',
name: 'GROUPS',
description: 't2',
randomName: 't3',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [], sandbox: false, script: ''
],
script: [
classpath: [], sandbox: false, script:
"""
def build = Thread.currentThread().toString()
def regexp= ".+?/job/(.*?)/build "
def match = build =~ regexp
def jobName = match[0][1].replaceAll("/job/", "/") as String
def text = new URL('http://consul.local:8500/v1/kv/${jobName}/test-key?raw').getText()
return text.split(",").sort() as List
"""
]
],
choiceType: "PT_RADIO", //PT_SINGLE_SELECT,PT_MULTI_SELECT,PT_RADIO,PT_CHECKBOX
filterable: true,
filterLength: 1
]
])])
}

Resources