Reputation: 6942
Having the Jenkins job dedicated to special node I'd like to have a notification if the job can't be run because the node is offline. Is it possible to set up this functionality?
In other words, the default Jenkins behavior is waiting for the node if the job has been started when the node is offline ('pending' job status). I want to fail (or don't start at all) the job in this case and send 'node offline' mail.
This node checking stuff should be inside the job because the job is executed rarely and I don't care if the node is offline when it's not needed for the job. I've tried external node watching plugin, but it doesn't do exactly what I want - it triggers emails every time the node goes offline and it's redundant in my case.
Upvotes: 2
Views: 14109
Reputation: 2548
offlineNodes = 0
def isNodeOnline(nodeName) {
def node = jenkins.model.Jenkins.instance.getNode(nodeName)
return ((node != null) && node.getComputer().isOnline())
}
def runOnNode(nodeName) {
stage(nodeName) {
if (isNodeOnline(nodeName)) {
node(nodeName) {
echo("Do the stuff..")
}
} else {
unstable ('Node ' + nodeName + ' is offline.');
offlineNodes = 1
}
}
}
// main
try {
runOnNode('yournode')
} catch (e) {
print('Got exception: ' + e)
currentBuild.result = 'FAILURE'
} finally {
if (offlineNodes > 0) {
currentBuild.result = 'ABORTED' // or UNSTABLE or whatever you like
emailext(
to: '[email protected]', replyTo: '$DEFAULT_REPLYTO', body: '''$DEFAULT_CONTENT''',
subject: '${PROJECT_NAME} - Build ${BUILD_NUMBER} (' + currentBuild.currentResult + ')'
)
}
}
Upvotes: 0
Reputation: 11
Try to use the tool nodesByLabel
of plugin Pipeline Utility Steps:
online_nodes = nodesByLabel label: "jenkins-slave-3", offline: false
if (online_nodes) {
echo "online"
} else {
echo "offline"
}
result (online):
Started by user testteam
Replayed #9
[Pipeline] Start of Pipeline
[Pipeline] nodesByLabel (hide)
Found a total of 1 nodes with the 'jenkins-slave-3' label
[Pipeline] echo
online
[Pipeline] End of Pipeline
Finished: SUCCESS
result (offline):
Started by user testteam
Replayed #8
[Pipeline] Start of Pipeline
[Pipeline] nodesByLabel
Could not find any nodes with 'jenkins-slave-1' label
[Pipeline] echo
offline
[Pipeline] End of Pipeline
Finished: SUCCESS
Upvotes: 0
Reputation: 869
I found an answer here. You can add a command-line or PowerShell block which invokes the curl command and processes a result
curl --silent $JENKINS_URL/computer/$JENKINS_NODENAME/api/json
The result json contains offline property with true/false value
Upvotes: 3
Reputation: 464
I don't think checking if the node is available can be done inside the job (e.g JobX
) you want to run. The act of checking, specifically for your JobX
at time of execution, will itself need a job to run - I don't know of a plugin/configuration option that'll do this. JobX
can't check if the node is free for JobX
.
I use a lot of flow jobs (in process of converting to pipeline logic) where JobA
will trigger the JobB
, thus JobA
could run on master check the node for JobB
, JobX
in your case, triggering it if up.
JobA
would need to be a freestyle job and run a 'execute system groovy script > Groovy command' build step. The groovy code below is pulled together from a number of working examples, so untested:
import hudson.model.*;
import hudson.AbortException;
import java.util.concurrent.CancellationException;
def allNodes = jenkins.model.Jenkins.instance.nodes
def triggerJob = false
for (node in allNodes) {
if ( node.getComputer().isOnline() && node.nodeName == "special_node" ) {
println node.nodeName + " " + node.getComputer().countBusy() + " " + node.getComputer().getOneOffExecutors().size
triggerJob = true
break
}
}
if (triggerJob) {
println("triggering child build as node available")
def job = Hudson.instance.getJob('JobB')
def anotherBuild
try {
def params = [
new StringParameterValue('ParamOne', '123'),
]
def future = job.scheduleBuild2(0, new Cause.UpstreamCause(build), new ParametersAction(params))
anotherBuild = future.get()
} catch (CancellationException x) {
throw new AbortException("${job.fullDisplayName} aborted.")
}
} else {
println("failing parent build as node not available")
build.getExecutor().interrupt(hudson.model.Result.FAILURE)
throw new InterruptedException()
}
To get the node offline email, you could just trigger a post build action to send emails on failure.
Upvotes: 1