In my declarative pipeline, i need to select a node matching 2 labels.
I tried something like this
agent { label 'label1 && label2'}
But i get an error that there are no nodes. I have a node with 2 labels label1 and label2 associated.
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Still waiting to schedule task
There are no nodes with the label ‘label1&&label2’
I know that i could temportailiy fix this by creating a 3rd label label1-2 and associate it with agent in the pipeline.
Is there any proper way to fix this?
Ok..figured it out.
agent {label "label1" && "label2"}
Related
I have a question about jenkins multijob possibilities:
current state:
I have 8 Jenkins nodes for job execution, 2 Linux and 6 Windows.
I have Multijob set up, consisting of 3 subJobs.
MultiJob setting: it has restriction to run only on Linux nodes
SubJob settings: n1 can run only on Win node1, n2 only on Win node2, n3 only on Win node3
Desired state:
When I build the multiJob, I need it to check and wait till Win nodes 1,2,3 are free
I need to execute subJobs 1,2,3 in the same time
this wouldn’t be problem, if all nodes were free...but if at least one of those three node is running some other job, it’s a problem already, because one subJob will be late compared to the other two
Is there any way to set up some pre-build script/another way to run subJobs only if all three chosen nodes are free/to wait for them to be free?
Thanks a lot for all ideas :)
You can check the status of the build executor on particular node as a pre-build action.
If the build executor is idle, that means no job is running but if it's busy, something is running into it.
Simple groovy script can be used for this purpose.
import hudson.model.Node
import hudson.model.Slave
import jenkins.model.Jenkins
Jenkins jenkins = Jenkins.instance
def jenkinsNodes =jenkins.nodes
for (Node node in jenkinsNodes)
{
// Make sure slave is online
if (!node.getComputer().isOffline())
{
//Make sure that the slave busy executor number is 0.
if(node.getComputer().countBusy()==0)
{
...put your logic...
}
}
}
Thanks,
Subhadeep
I have made (localhost:8080)
scheduler: true
in one node to make it scheduler master.
Other node have schedule turned off (localhost:8000)
scheduler: false
How will "scheduler master" assign task to other node..??
I work this out. It was simple but simple is tough.
We just have to follow AH architecture.
First of all make sure AH is not using fakeredis.
Than server should not have nay taskprocessor
And all other worker should have one or more taskprocessors. You can find that in /config/tasks.js. Thn in /config/tasks.js name the queue in queue array on which worker should work.
Once they are sharing redis they will share tasks and start working on tasks in queue.
I want to add the job status in the subject line of the email notification of Octopus Deploy. Can you please tell me the system variable to use or another way to add the status?
As a work-around you could use two steps for sending the 'status-email':
One step sending 'success'-email. This step should have its 'Run condition' set to 'Success: only run when previous steps are successfull'.
Another step sending 'failure'-email. This step should have 'Run condition' set to 'Failure: only run when a previous step failed'.
Perhaps the system-variables Octopus.Deployment.Error
Octopus.Deployment.ErrorDetail could also be helpfull.
Tracking deployment status
During deployment, Octopus provides variables describing the status of each step.
Where S is the step name, Octopus will set:
Octopus.Step[S].Status.Code
Octopus.Step[S].Status.Error
Octopus.Step[S].Status.ErrorDetail
Status codes include Pending, Skipped, Abandoned, Cancelled, Running, Succeeded and Failed.
Source: http://docs.octopusdeploy.com/display/OD/System+variables#Systemvariables-DeploymentStatusTrackingdeploymentstatus
So to apply this to your email subject (assuming you're using the inbuilt Send Email step:
FYI: the box circled allows you quick access to the variables list.
You probably want to tweak the value to be closer to this, though
Deployment Status = #{Octopus.Step[Other Step Name].Status.Code}
As an extension to this answer; you can iterate over all steps and output their status, I guess.
Syntax here: http://docs.octopusdeploy.com/display/OD/Variable+Substitution+Syntax#VariableSubstitutionSyntax-Repetition (look for the Repetition heading)
Write-Host "Deployment Steps:"
#{each step in Octopus.Step}
Write-Host "- StepName=#{step}; Status=#{step.Status.Code};"
#{/each}
Example output
Deployment Steps:
StepName=FirstStep; Status=Succeeded;
StepName=ThisStep; Status=Running;
StepName=YetToBeRun; Status=Pending;
You could use variable expressions and deployment error variable to achieve this in email subject field. For example:
State of deployment: #{unless Octopus.Deployment.Error}Success#{/unless} #{if Octopus.Deployment.Error}Failure#{/if}
I have a hadoop cluster with 7 nodes, 1 master and 6 core nodes. Ganglia is setup on each machine, and the web front end correctly shows 7 hosts.
But it only shows metrics from the master node (with both gmetad and gmond). The other nodes have the same gmond.conf file as the master node, and the web front end clearly sees the nodes. I don't understand how ganglia can recognize 7 hosts but only show metrics from the box with gmetad.
Any help would be appreciated. Is there a quick way to see if those nodes are even sending data? Or is this a networking issue?
update#1: when I telnet into a gmond host machine that is not the master node, and look at port 8649, I see the XML but no data. When I telnet to 8649 on the master machine, I see XML and data. Any suggestions of where to go from here?
Set this to all gmond.conf files of every node you want to monitor:
send_metadata_interval = 15 // or something.
Now all the nodes and their metrics are showed in master (gmetad).
This extra configuration is necessary if you are running in a unicast mode, i.e., if you are specifying a host in udp_send_channel rather than mcast_join. In the multi-cast mode, the gmond deamons can query each other any time and proactive sending of monitoring data is not required.
In gmond configuration, ensure the following is all provided:-
cluster {
name = "my cluster" #is this the same name as given in gmetad conf?
## Cluster name
owner = "unspecified"
latlong = "unspecified"
url = "unspecified"
}
udp_send_channel {
#mcast_join = 239.2.11.71 ## Comment this
host = 192.168.1.10 ## IP address/hostname of gmetad node
port = 8649
ttl = 1
}
/* comment out this block itself
udp_recv_channel {
...
}
*/
tcp_accept_channel {
port = 8649
}
save and quit. Restart your gmond daemon. Then execute "netcat 8649". Are you able to see XML with metrics now?
I need to have a Job with multiple tasks, being run on different machines, one after another (not simultaneously), and while the current job is running, another same job can arrive to the queue, but should not be started until the previous one has finished. So I came up with this 'solution' which might not be the best but it gets the job done :). I just have one problem.
I figured out I would need a JobQueue (either MongoDb or Redis) with the following structure:
{
hostname: 'host where to execute the task',
running:FALSE,
task: 'current task number',
tasks:{
[task_id:1, commands:'run these ecommands', hostname:'aaa'],
[task_id:2,commands:'another command', hostname:'bbb']
}
}
Hosts:
search for the jobs with same hostname, and running==FALSE
execute the task that is set in that job
upon finish, host sets running=FALSE, checks if there are any other tasks to perform and increases task number + sets the hostname to the next machine from the next task
Because jobs can accumulate, imagine situation when jobs are queued for one host like this: A,B,A
Since I have to run all the jobs for the specified machine how do I not start the 3rd A (first A is still running)?
{
_id : ObjectId("xxxx"), // unique, generated by MongoDB, indexed, sortable
hostname: 'host where to execute the task',
running:FALSE,
task: 'current task number',
tasks:{
[task_id:1, commands:'run these ecommands', hostname:'aaa'],
[task_id:2,commands:'another command', hostname:'bbb']
}
}
The question is how would the next available "worker" know whether it's safe for it to start the next job on a particular host.
You probably need to have some sort of a sortable (indexed) field to indicate the arrival order of the jobs. If you are using MongoDB, then you can let it generate _id which will already be unique, indexed and in time-order since its first four bytes are timestamp.
You can now query to see if there is a job to run for a particular host like so:
// pseudo code - shell syntax, not actual code
var jobToRun = db.queue.findOne({hostname:<myHostName>},{},{sort:{_id:1}});
if (jobToRun.running == FALSE) {
myJob = db.queue.findAndModify({query:{_id:jobToRun._id, running:FALSE},update:{$set:{running:TRUE}}});
if (myJob == null) print("Someone else already grabbed it");
else {
/* now we know that we updated this and we can run it */
}
} else { /* sleep and try again */ }
What this does is checks for the oldest/earliest job for specific host. It then looks to see if that job is running. If yes then do nothing (sleep and try again?) otherwise try to "lock" it up by doing findAndModify on _id and running FALSE and setting running to TRUE. If that document is returned, it means this process succeeded with the update and can now start the work. Since two threads can be both trying to do this at the same time, if you get back null it means that this document already was changed to be running by another thread and we wait and start again.
I would advise using a timestamp somewhere to indicate when a job started "running" so that if a worker dies without completing a task it can be "found" - otherwise it will be "blocking" all the jobs behind it for the same host.
What I described works for a queue where you would remove the job when it was finished rather than setting running back to FALSE - if you set running to FALSE so that other "tasks" can be done, then you will probably also be updating the tasks array to indicate what's been done.