将 Jenkins 作业专用于特殊节点,如果该作业因节点离线而无法运行,我希望收到通知。可以设置这个功能吗?
换句话说,如果作业在节点离线(“待处理”作业状态)时已启动,则 Jenkins 的默认行为是等待节点。在这种情况下,我想让作业失败(或根本不启动)并发送“节点离线”邮件。
这个节点检查内容应该在作业内部,因为作业很少执行,而且我不关心作业不需要时节点是否离线。我已经尝试过外部节点监视插件,但它并不能完全满足我的要求 - 每次节点离线时它都会触发电子邮件,这在我的情况下是多余的。
我在这里找到了答案。 您可以添加命令行或 PowerShell 块来调用 curl 命令并处理结果
curl --silent $JENKINS_URL/computer/$JENKINS_NODENAME/api/json
结果 json 包含具有 true/false 值的 offline 属性
我认为检查节点是否可用可以在您想要运行的作业(例如
JobX
)内完成。检查行为,特别是在执行时检查您的JobX
,本身需要一个作业来运行 - 我不知道有一个插件/配置选项可以做到这一点。 JobX
无法检查节点是否空闲JobX
。
我使用了很多流程作业(正在转换为管道逻辑的过程中),其中
JobA
将触发JobB
,因此JobA
可以在主节点上运行,检查节点是否有JobB
,在您的情况下JobX
,如果启动则触发它。
JobA
需要是一个自由式作业并运行“执行系统 Groovy 脚本 > Groovy 命令”构建步骤。下面的常规代码是从许多工作示例中提取出来的,因此未经测试:
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()
}
要获取节点离线电子邮件,您只需触发构建后操作以在失败时发送电子邮件。
尝试使用插件的工具
nodesByLabel
Pipeline Utility 步骤:
online_nodes = nodesByLabel label: "jenkins-slave-3", offline: false
if (online_nodes) {
echo "online"
} else {
echo "offline"
}
结果(在线):
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
结果(离线):
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
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 + ')'
)
}