Jenkins: How to get node name from label to use as a parameter - maven

I need to give a server name to a maven build. During the maven build this server name will be used to make a call that server do some tests on that server.
Our servers have jenkins slaves on them and is grouped using labels
Example
Slaves/Node | Label
Server1 | BackEndServers
Server2 | BackEndServers
Server3 | FrontEndServers
Server4 | FrontEndServers
With Elastic Axis plugin i can say run my Jenkins job on this Node Label (for example on BackEndServers) and the same project will be executed on both of the servers (Server1 & Server2).
In my case I cannot do this as maven is not installed on the BackEndServers where my code is running. But the maven build needs to know about the server names though.
So is there a way how I can get the server names from a label and then run the same job multiple times passsing each servername to the maven build?
Example
Giving that I have the label 'BackEndServers'
obtain a list of node names 'Server1,Server2'
and run my job for each node name and pass a parameter to it
aka
Having Job (with parameter Server1)
Having Job (with parameter Server2)

Use Jenkins environment variables like NODE_NAME in the Maven command of the build job as value for a system property. For example:
mvn clean install -Djenkins.node.name=${NODE_NAME}
In your Maven project (pom.xml) configure the plugin, which requires the node name, with the help of following property: ${jenkins.node.name}
Here are some links - how to trigger Jenkins builds remotely:
How to trigger Jenkins builds remotely and to pass paramter
Triggering builds remotely in Jenkins
Launching a build with parameters
I don't, if it is possible in the way you want it. But the provided information should help you to find a solution.

Try Jenkins.getInstance().getComputer(env.NODE_NAME).getNode() See more on official Doc

In the end I created a 2 jobs.
To interogate the Jenkens nodes for me and build up a string of servers to use
Then use Dynamic Axis lable with the list I have in Job 1 to execute my maven build
In Job 1 - I used The EnjEnv plugin and it has a 'Evaludated Groovy Script' section that basically you can do anything... but it should return a property map. I don't know how to return a value from a Groovy script so this worked kewl for me as I can reference property (or Environment variables) from almost anyware
import hudson.model.*
String labelIWantServersOf = TheLabelUsedOnTheElasticAxisPlugin; // This is the label assosiated with nodes for which i want the server names of
String serverList = '';
for (aSlave in hudson.model.Hudson.instance.slaves) {
out.println('Evaluating Server(' + aSlave.name + ') with label = ' + aSlave.getLabelString());
if (aSlave.getLabelString().indexOf(labelIWantServersOf ) > -1) {
serverList += aSlave.name + ' ';
out.println('Valid server found: ' + aSlave.name);
}
}
out.println('Final server list where SOAP projects will run on = ' + serverList + ' which will be used in the environment envInject map');
Map<String, String> myMap = new HashMap<>(2);
myMap.put("serverNamesToExecuteSoapProjectOn", serverList );
return myMap;
Then I had some issue to pass the Environment var onto my next job. So I simply wrote the values that I wanted to a property file using a windows batc script in the Build process
echo serverNamesToExecuteSoapProjectOn=%serverNamesToExecuteSoapProjectOn%> baseEnvMap.properties
Then as a post build action I had a "Trigger parameterized build on other projects' calling my 2nd job and I passed the baseEnvMap.properties to it.
Then on my Job 2 which is a Multiconfig job I added a Dynamic Axis using the environment var that was passed via the property file to job 2.
This will duplicate Job 2 and execute it each time with the value that the groovy script build up which I can reference in my mvn arguments.

To list out all nodes of label name LABELNAME:
http://ServerIP:8080/label/LABELNAME/api/json?pretty=true

Related

I can't export a custom report name from html-reporter-extra

This really should be straightforward but I can't get it to work.
It's a simple setup: I have a locally run Jenkins, exported Postman collections that I'm running using newman. I got html-report-extra installed and it's generating a report but I can't get it to export the html file under a different name!
I have a locally installed Jenkins, I'm using a freestyle project and under Build - Execute Windows batch command I have this:
newman run IDMS4.postman_collection.json -e IDMS4.postman_environment.json --reporters cli,htmlextra --reporter-html-export newman/index.html --disable-unicode
This is how my Jenkins job is setup:
Jenkins job setup
Build completes but there is no index.html anywhere. This is the the part that's puzzling me.
In
.jenkins\jobs\Newman runner\htmlreports\HTMLReport
i get the default file format name (project name + timestamp).
In
.jenkins\workspace\Newman runner\newman
I also get project name + timestamp html files.
Why is this outputed to both folders and how can I get this to export just one index.html?
Please try with dot slash. eg: ./newman/index.html.
and also
if you need collection name to be in the report, please use following node module
https://www.npmjs.com/package/jaiman

Jenkins Pipeline emailext: How to access build object in pre-send script

I'm using Jenkins ver. 2.150.1 and have some freestyle jobs and some pipeline jobs.
In both job types I am using the emailext plugin, with template and pre-send scripts.
It seems that the build variable, which is available in the freestyle projects, is null in the pipeline projects.
The pre-send script is the following (just an example, my script is more complex):
msg.setSubject(msg.getSubject() + " [" + build.getUrl() + "]")
There is no problem with the msg variable.
In the freestyle job, this script adds the build url to the mail subject.
In the pipeline job, the following is given in the job console:
java.lang.NullPointerException: Cannot invoke method getUrl() on null object
The invocation of emailext in the pipeline job is:
emailext body: '${SCRIPT, template="groovy-html.custom.pipeline.sandbox.template"}',
presendScript: '${SCRIPT, template="presend.sandbox.groovy"}',
subject: '$DEFAULT_SUBJECT',
to: 'user#domain.com'
I would rather find a general solution to this problem (i.e. Access the build variable in a pipeline pre-send script), but would also appreciate any workarounds to my current needs:
Access job name, job number, and workspace folder in a pipeline pre-send script.
I have finally found the answer -
Apparently for presend script in pipeline jobs, the build object does not exist, and instead the run object does. At the time I posted this question this was still undocumented!
Found the answer in this thread
Which got the author to update the description in the wiki:
run - the build this message belongs to (may be used with FreeStyle or Pipeline jobs)
build - the build this message belongs to (only use with FreeStyle jobs)
You can access the build in a script like this:
// findUrl.groovy
def call(script) {
println script.currentBuild.rawBuild.url
// or if you just need the build url
println script.env.BUILD_URL
}
and would call the script like this from the pipeline:
stage('Get build URL') {
steps {
findUrl this
}
}
The currentBuild gives you a RunWrapper object and the rawBuild a Run. Hope this helps.

TeamCity - how to access environment variable in gradle

I have specified environment variable named DIR in my build agent. It is visible in my parameters/environment variables section of my Build Agent properties. I want to access this variable from gradle. I don't know how. I tried many things like:
if (project.hasProperty("teamcity")) {
println teamcity
println teamcity["teamcity.build.properties.file"]
def properties = file(teamcity["teamcity.build.properties.file"])
println properties.DIR
println DIR
println env.DIR
}
My teamcity file looks like:
{teamcity.buildType.id=Taxi5Mobile_BuildDev, build.vcs.number.Taxi5Mobile_Taxi5devVCS=a23e58c8ff92, teamcity.version=8.1.1 (build 29939), teamcity.buildConfName=Build-dev, teamcity.agent.dotnet.agent_url=http://localhost:9090/RPC2, teamcity.build.id=111, agent.ownPort=9090, agent.name=MacAgent, build.number=82, teamcity.runner.properties.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/teamcity.runner3909938768619827374.properties, teamcity.build.changedFiles.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/changedFiles8064633368222257261.txt, teamcity.agent.cpuBenchmark=552, teamcity.build.workingDir=/Users/surecase/Desktop/buildAgent/work/88410410f80bbc04/Mobile/Android, agent.home.dir=/Users/surecase/Desktop/buildAgent, teamcity.auth.userId=TeamCityBuildId=111, teamcity.build.checkoutDir=/Users/surecase/Desktop/buildAgent/work/88410410f80bbc04, teamcity.configuration.properties.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/teamcity.config8874044708331653991.properties, build.vcs.number=a23e58c8ff92, teamcity.tests.recentlyFailedTests.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/testsToRunFirst6286498944890258669.txt, teamcity.projectName=Taxi5Mobile, agent.work.dir=/Users/surecase/Desktop/buildAgent/work, teamcity.build.tempDir=/Users/surecase/Desktop/buildAgent/temp/buildTmp, build.vcs.number.1=a23e58c8ff92, teamcity.auth.password=8dYVHDftOmXenz9cJjnCyctBrF5NKq7G, java.io.tmpdir=/Users/surecase/Desktop/buildAgent/temp/buildTmp, teamcity.build.properties.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/teamcity.build174113942945941853.properties, teamcity.agent.dotnet.build_id=111}
There are some files which contains properties but I don't know how to access them.
Any ideas?
Environment variables can be read using the standard Java API:
def dir = System.getenv("DIR")
It might make sense to use a name that's a little less ambiguous than DIR.

Access to build environment variables from a groovy script in a Jenkins build step (Windows)

I'm using Scriptler plugin, so I can run a groovy script as a build step. My Jenkins slaves are running on windows in service mode. With scriptler, I don't need to use windows batch scripts.
But I have trouble to get the environment variables in a build step... This is working:
System.getenv("BASE")
Where BASE is part of the env-vars on jenkins startup. However, I would like to get
%JOB_NAME%
If I'm adding an "Execute Windows batch command" build step:
echo %JOB_NAME%
It works.
If I'm adding a scriptler script as a build step with the same settings:
println "JOB_NAME: " + System.getenv("JOB_NAME")
I'm getting:
JOB_NAME: null
So how can I reach the injected environment variables from a groovy script as a build step?
build and listener objects are presenting during system groovy execution. You can do this:
def myVar = build.getEnvironment(listener).get('myVar')
You might be able to get them like this:
def thr = Thread.currentThread()
def build = thr?.executable
def envVarsMap = build.parent.builds[0].properties.get("envVars")
On jenkins 2.x, with groovy plugin 2.0, running SystemGroovyScript I managed to get to build variables, as below:
def build = this.getProperty('binding').getVariable('build')
def listener = this.getProperty('binding').getVariable('listener')
def env = build.getEnvironment(listener)
println env.MY_VARIABLE
If you are using goovy from file, simple System.getenv('MY_VARIABLE') is sufficient
The Scriptler Groovy script doesn't seem to get all the environment variables of the build. But what you can do is force them in as parameters to the script:
When you add the Scriptler build step into your job, select the option "Define script parameters"
Add a parameter for each environment variable you want to pass in. For example "Name: JOB_NAME", "Value: $JOB_NAME". The value will get expanded from the Jenkins build environment using '$envName' type variables, most fields in the job configuration settings support this sort of expansion from my experience.
In your script, you should have a variable with the same name as the parameter, so you can access the parameters with something like:
println "JOB_NAME = $JOB_NAME"
I haven't used Sciptler myself apart from some experimentation, but your question posed an interesting problem. I hope this helps!
The only way I could get this to work (on Linux) was to follow this advice:
https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+System+Groovy+script
import hudson.model.*
// get current thread / Executor and current build
def thr = Thread.currentThread()
def build = thr?.executable
// if you want the parameter by name ...
def hardcoded_param = "FOOBAR"
def resolver = build.buildVariableResolver
def hardcoded_param_value = resolver.resolve(hardcoded_param)
println "param ${hardcoded_param} value : ${hardcoded_param_value}"
This is on Jenkins 1.624 running on CentOS 6.7
Jenkins 2.x has the global variables. env is one of them from any script...
println env.JOB_NAME
More at https://build.intuit.com/services-config/pipeline-syntax/globals#env
One thing to note, if you are using a freestyle job, you won't be able to access build parameters or the Jenkins JVM's environment UNLESS you are using System Groovy Script build steps. I spent hours googling and researching before gathering enough clues to figure that out.
In System Groovy Script (Jenkins 2.89), I was able to use the environmental variable to disable another Jenkins job
import jenkins.*
import jenkins.model.*
def env = binding.build.environment
Jenkins.instance.getItemByFullName(env.job_name).setDisabled(false)
I also added a conditional step so as to either enable or disable another Jenkins job.
Thanks #Allan Lewis, your comment was helpful.

Unable to locate file 'C:\BuildAgent\temp\buildTmp\SYSTEM_[AGENT NAME] 2013-02-06 16_25_11\

I have an MSTest build step in my TeamCity build. Some of the tests are looking for a file in a relative path which they cannot find and the tests are throwing the error...
Cannot find path...
'C:\BuildAgent\temp\buildTmp\SYSTEM_[AGENT NAME] 2013-02-06 16_25_11\Documents\json.value.list.txt'
I have a PowerShell script that I want to use to create and copy the file out to the above path. However, I cant seem to figure out the appropriate TeamCity parameters to use to construct the path...
I have...
%system.teamcity.build.tempDir%\%teamcity.agent.name%\documents
However, that gives me...
'C:\BuildAgent\temp\buildTmp[AGENT NAME]\Documents\'
What can parameters or TeamCity variables can I use to construct...
C:\BuildAgent\temp\buildTmp\SYSTEM_[AGENT NAME] 2013-02-06 16_25_11\Documents
Thanks!
If your test is reading the contents of a file, this will ensure that relative paths are resolved correctly so tests can be run on TeamCity as well as locally:
string currentDir = new System.Diagnostics.StackFrame(true).GetFileName();
var workingFile = new FileInfo(currentDir);
string fileContents = File.ReadAllText(workingFile.Directory + relativeFilePath);
relativeFilePath is the variable containing the file. fileContents will contain the contents of this file when run from TeamCity or locally.

Resources