主机重启后如何继续jenkins管道。

时间:2018-05-08 12:54:21

标签: jenkins

我有一个Jenkins作业,目前用于重新启动主机,这是管道的一部分,有几个下游作业。目前,在开始下游构建之前,作业正在重新启动和休眠。在继续而不是使用睡眠之前,是否有更好的方法来检查主机是否备份?

Reboot_host作业当前正在执行:

ssh <hostname> "sudo reboot"
sleep 90

主机是VM,这就是睡眠持续时间如此之短的原因。

2 个答案:

答案 0 :(得分:0)

我假设你在这里使用Jenkinsfile因为你说过“管道”;如果没有,请提供更多关于你工作的信息(带有执行shell的自由式等)。

您可能需要sleep,但您可以将其与retry结合使用,以便更快地获得成功(以及更快的失败)。假设您只需要启动VM,您可以使用以下内容:

retry(20){
    sleep time: 5 unit: 'SECONDS'
    sh 'ssh -o ConnectTimeout=1 <hostname> exit'
}

这将尝试每隔5秒ssh到主机。添加ConnectTimeout意味着ssh只需等待1秒即可完成连接。 exit只是确保断开连接成功。 retry将评估命令最多20次,直到sh命令具有0(成功)退出值。如果它运行20次而没有成功,则构建将失败(这可能是好的,因为这意味着您的VM不可用于下游作业)。

如果您正在等待特定服务,则可以curl或以其他方式尝试联系该服务,而不是使用ssh

答案 1 :(得分:0)

假设您正在使用管道,我可以告诉我们我们在Windows机器上所做的工作,我们使用作业来安装Windows更新并触发重新启动。

整个过程涉及几个步骤和许多错误检查。由于代码需要访问Jenkins API,我们将其放入一个全局共享库中,其中所有对Jenkins API的调用都封装在@NonCPS方法中。以下只是所需要做的工作的粗略概图-将完整的代码放在这里可能太多了。

我们重启Windows计算机的过程

要在Linux机器上触发重启,您可能不需要所有步骤。但是,使用它们并不应该有害。当然,您还必须实施适当的错误检查。 我将代码放在了一些可以进行单元测试的库中。

    从节点块内的某个循环中轮询
  1. Computer.countBusy()(对于重量级执行程序)和Computer.getOneOffExecutors()(对于flyweight执行程序),在轮询之前,将节点置于离线状态(Computer.setTemporarilyOffline()) 。您可以使用getContext(hudson.FilePath).toComputer()获得的计算机。一旦有一个正在使用的重量级执行器(就是我们),而没有一个重量级执行器,节点就可以重新启动了。使节点保持脱机状态,并留在节点块中进行第二步。
  2. node仍然离线的情况下,从第一步打开的Computer块内触发重新启动。确保在运行重新启动cmd之后立即离开节点块。例如。在Windows上:bat 'shutdown /t 2 /r'
  3. 等待直到机器不再连接以检测重新启动。为此,我们检查是否可以为该FilePath获得有效的ComputerComputer.getNode().createPath()
  4. 请确保致电Computer.disconnect()。至少对于Windows计算机而言,这是非常重要的,因为Jenkins有时不会注意到它失去了连接,并会尝试使用旧的连接-这样会失败。
  5. 等待操作系统启动。我们使用一个Linux节点对Windows计算机执行ping操作,直到ping响应得到答复为止。
  6. 触发Computer.connect(false)。等待直到重新建立连接。我们检查Computer.getChannel() != null
  7. 使节点重新联机:Computer.setTemporarilyOffline(true, 'foo')
  8. Computer.waitUntilOnline()
  9. 完成:)