How to use "Scoring Load Balancer" plugin in Jenkins - jenkins

I want to run a job on different slaves, but in a predefined order.
i.e. I would like the job to run on the second machine only when all the executors of the first slave are busy.
I am trying to use "Scoring Load Balancer" plugin to allocate scores to different slaves,i.e. if I have 3 nodes, NodeA,NodeB and NodeC, having preferences of 9,5 and 1 respectively and no. of executors 10 on each node.
The nodes have a common label "WindowSlave".
Also, I have defined a job,"ProjectX", with project preference score of 10 and the label "WindowSlave" as the preferred label.
I had expected that if I run 100 concurrent builds for the "ProjectX" then the execution would happen in the order :
NodeA(10 builds) -> NodeB(10 builds) -> NodeC(10 builds) -> NodeA(10 builds) -> NodeB(10 builds)->... and so on.
From my observations it is still not clear if above scenario would always be achieved.
Also it happens that any random slave starts behaving as the main slave and co-ordinates with the other slave,such that all the build workspace are created on that particular slave.
What am i missing here??

Related

Jenkins workspace variable is swapping during parallel builds stages

I got a WS variable which is saving the Jenkins WORKSPACE variable.
During stages I always check if the WS == WORKSPACE Jenkins generic variable.
What I saw that during parallel runs ( when 2 different workspaces are created inside C:/jenkins/workspace#1 and C:/jenkins/workspace#2 the $WORKSPACE is swapping between those 2 parallels builds.
The problem is reproduced rarely , less than 10 percent of cases but I find it quite strange , for the picture above -> The first workspace its AVB_Aplicattions_BOSCH-3 its going trough 3 stages and in the 4th stages the $WORKSPACE variable its swapping with AVB_APLICATTIONS_BOSCH-4( the other parallel build).If I will look on the other build (AVB_APLICATTIONS_BOSCH-4 I will see the same problem-> the workspace is becoming AVB_APLICATTIONS_BOSCH-3).
During this builds I compile using cmake files, I'm afraid that the results will be not correct.
I was thinking to use the in build dir() function during each stage to be sure im on the same workspace .
Some one know a good approach for this case and also why its happening?
I don't want to deactivate parallel's builds.
The problem is that Jenkins variable scopes aren't really safe with parallel stages (see further sources / link). There are actually several questions and answers (and workaround) how to work with variables when using parallel stages. Long story short: don't use global variables but pay extra attention to define local variables with def to limit their scope:
Jenkins - matrix jobs - variables on different slaves overwrite each other?
Variables get overwritten in parallel stages
Parallel matrix and global variables without race condition?
Jenkins community links:
https://issues.jenkins.io/browse/JENKINS-55040
https://issues.jenkins.io/browse/JENKINS-54732

Are labels of Jenkins build slaves checked in a case sensitive manner for job scripts?

When i have two build clients, where one has a label of "Windows" (1st char is capitalized) and the other has a label of "windows" (all lower case), will i either need to write a job label formula of "(Windows || windows)" (assumed the case of the label is respected) or is either "Windows" or "windows" (assumed the comparison is case-insensitive) sufficient to freely run the job on any of both machines, whichever is first or free?
I have to ask, because i felt like i was unable to determine from docs in what fashion this is set up. (Some docs even indicate that some other check-operations are configurable in respect to case'ness.)
The Node labels are case sensitive in jenkins. So, When you write (Windows || windows) as a target node, jenkins will first try to run the job on the agent with label "Windows" in case if that agent doesn't respond then it will try to run the same job on the second agent with label "windows". If you want to run a job freely on any of the available agents then there are two way to accomplish that
Define the RegEx for those agents with OR (||) symbol (for example "Windows || windows"), which you already have.
Have the same label name on both agents (for example "windows") and have your job run with label "windows". It will run in a little different manner. In this case when you run that job with target label "windows", jenkins will send the request to both nodes but jenkins will run the job on the agent which will respond first.

jenkins from master running multiple downstream jobs

use case: I want to run the regression suite on multiple images(image selection is variable it can be 4 or 5).
I want to create 1 master job who will take the images name as an input, and This master job passes the image name one by one to downstream regression job. The number of images can be variable.
Master job
INPUT image: a,b,c .....
|
|
-------------------------------------------------
| | |
Regression job Regression REgression
Input image: a Image b Image c
Can anyone just tell me how can I perform this task in Jenkins?
To Solve this, I have used the pipeline and Active choice parameter plugins.
Here is the configuration:
Here is the problem, I am getting ThunderImage list as [p,1,p,2,p,3] instead of ['p1','p2','p3'] .
So,you want to select which regression Job starts depending on the selected input from your Master Job? For this you could use the Post build task and use it's regex functionality to check for the input Paramter inside the Build Log.
If you are using a Pipeline job you can use the solution of Christopher Orr from: Jenkins trigger build dependent on build parameters

Jenkins - only run a job on a node with 2+ executors free

We have a number of multi-jobs that run a parent job and multiple sub-jobs. The parent does some preprocessing, then kicks off the first sub-job.
Example:
Parent - checks out git repos and preps the code
Build the code
Unit Tests
Upload to HockeyApp
Since the parent is running the entire time the sub-jobs are running, the process starts out with one executor, then picks up a second whenever a sub-job starts. drops it and then picks it back up when the next starts.
We have 4 nodes with 3 - 4 executors on each of them. We also don't have a networked drive so the sub job has to stay on the same executor as the parent to avoid having to pass the entire workspace between jobs.
The problem is that if one job is running and has two executors, then another gets kicked off and then another right after that, there's a chance they'll all end up on the same node and something like below happens:
Node 1
Executor 1 - Parent1
Executor 2 - Child1
Executor 3 - Parent2
Executor 4 - Parent3
Now Parent2 and Parent3 just sit around waiting for a free executor. Eventually the Child job on Parent1 ends, then 2 r 3 grabs the executor and all of them are fighting for it.
Is there a way to tell Jenkins only kick off that parent on a node with at least 2 executors free? I know if someone started enough jobs quickly enough we could still end up with man issue, but it would significantly reduce the chance of it.
I think you can use - https://wiki.jenkins.io/display/JENKINS/Heavy+Job+Plugin , and define for each step the amount of free executers you need.

Jenkins - Running a single job addressing two nodes simultaneous - or intercommunicate between two jobs

Jenkins newbie, but have other build-server experience.
I'm in progress of setting up a test job, where software on two nodes need to ping-pong with each other.
I have a pool of labeled nodes (lets call them A, running windows 7) to run the testing software and another pool of labeled nodes (lets call these B, running lubuntu 14.10).
The testing is performed through TCP/IP and needs various command line stimuli on both A and B nodes throughout the test. In the end I need to gather artifacts from both the A and B nodes.
I imagine the requirement and need to control multiple nodes simultaneous isn't so rare, but I'm really having a hard time locating info on this on the web.
Might there be a plugin for this that I've missed?
Below are my thoughts of what needs to be performer, should a single plugin not exist to help me out.
My preferred solution would be a single job, but then I need to find out how to perform following:
Check out from SVN to Node A.
Check out from SVN to Node B.
Execute Windows script on Node A.
Execute Linux script on Node B.
Collect artifact from Node A.
Collect artifact from Node B.
Alternative to all the even bullets above, might be to perform those actions using SSH from either the master or the A node to control the B Node, but that leaves the following questions:
How to select one B node out of the B node pool - and mark it in use?
How to use the Jenkins SSH/slave credentials?
A totally different alternative could be to set up two jobs, one for Node A's and one for Node B's. But then I need to find out how to perform the following:
Associate one Node A job with a Node B job, so they are both aware of the association.
Perform two-ways inter-communication, allowing the Node A job to wait for a signal from a Node B job and visa verse.
Eagerly looking forward to your answers!
In a similar scenario we use, we have two jobs (I'm not aware of a way to run a single job on two nodes).
Job A runs on node A and sets up a server and then triggers job B, which is set to run on node B (as a build step).
Job B will start its client app, which is configured to work with the server installed by A (an IP configuration in my case).
The job A (server) goes into a wait loop (using bash while) that checks if client running on B has connected (I use a flag file in a shared location).
Once connected, both jobs do a few more steps and complete. Each job will end with its own reporting.
I hope this helps.
In my case I've used Multi-configuration project with Slave axis. Then you can synchronize execution between nodes using your own code, or mix it with (system) Groovy script to communicate between different configurations.
ie.
def siblings = []
build.getParentBuild().getExactRuns().each { run ->
if (!build.is(run)) {
if (run.hasntStartedYet()) {
println "Build " + name + " hasn't started yet!"
} else {
if (!run.isBuilding()) {
println "Build " + name + " has already completed!"
break
}
executor = run.getExecutor()
if (executor) {
hostname = executor.getOwner().getHostName()
// In case hostname could not be found explicitly,
// then set it based on node's name.
if (!hostname) hostname = executor.getOwner().getName()
if (hostname) {
siblings.add(hostname)
}
}
}
}
}

Resources