0

精简版

在 Jenkins 构建后的 groovy 脚本中,有没有办法让Computer.waitUntilOnline函数在一段时间后超时?

背景

我们对嵌入式设备进行测试,我们的 jenkins slave 是连接到某些硬件设置的笔记本电脑。在某些情况下,我们需要一个 groovy post-build 脚本重新启动计算机,然后等待它再次上线。然而,有时这些机器不会再次上线,而我们的 groovy 脚本只是无限期地等待。

waitUntilOnline函数可以抛出 InterruptedException,但据我所知,您需要运行多个线程才能触发该异常。运行多个线程只是为了触发超时似乎是错误的处理方式。

我还找到了一些关于使用timeout. 这是为 Jenkins Pipelines 设计的,所以我不确定我是否可以在构建后的 groovy 中使用它,而且我还没有让它工作。我尝试了各种组合,包括:

timeout(20)
{
    computer.waitUntilOnline()
}

timeout(20)
{
    waitUntil{
        try {
            computer.waitUntilOnline()
        }catch (exception){
            manager.listener.logger.println("caught exception!");
        }
    }
}

但似乎都抛出了这样的异常:

groovy.lang.MissingMethodException: No signature of method: Script1.timeout() is applicable for argument types: (java.lang.Integer, Script1$_rebootAndWait_closure1) values: [20, Script1$_rebootAndWait_closure1@7b6564fc]

任何建议表示赞赏。

编辑:我也尝试过@groovy.transform.TimedInterrupt注释,正如这个问题中提到的,我得到了奇怪的结果。

当我运行这个简单的循环示例时,我得到了预期的结果:它为 i 打印了一些值。但是,如果我尝试将此与重新启动计算机相结合,如下所示:

import hudson.util.RemotingDiagnostics

def runCmd(computer, cmd)
{
    def channel = computer.getChannel()

    str = RemotingDiagnostics.executeGroovy( """
        p = '$cmd'.execute()
        p.waitFor()
        p.in.text
    """, channel ) 
}

@groovy.transform.TimedInterrupt( 3L )
def loopy()
{
  int i = 0
  try {
    while( true ) {
      i++
    }
  }
  catch( e ) {
    manager.listener.logger.println("i is "+i);
  }
}

def rebootAndWait(computer)
{

    manager.listener.logger.println("about to loopy : " +computer.name);

    cmd = 'shutdown /r /t 10 /c "Restarting after Jenkins test completed"'
//    cmd = "cmd.exe /c  echo loopy test > c:\\\\Users\\\\frederikvs\\\\fvs_test.txt"

    runCmd(computer, cmd)

// eventually we want to wait here for the computer to come back online, but for now we'll just have loopy
    loopy();
}

rebootAndWait(manager.build.getBuiltOn().toComputer())

我得到了奇怪的结果:有时我得到 i 的一些值的预期输出,有时我得到一个未捕获的异常:

java.util.concurrent.TimeoutException: Execution timed out after 3 units. Start time: Fri Aug 17 10:48:07 CEST 2018
    at sun.reflect.GeneratedConstructorAccessor5665.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
    at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:247)
    at Script1.loopy(Script1.groovy)
    at Script1.rebootAndWait(Script1.groovy:47)
    at Script1$rebootAndWait.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
    at Script1.run(Script1.groovy:51)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:585)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:623)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:594)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:343)
    at org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder.perform(GroovyPostbuildRecorder.java:380)
    at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:744)
    at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
    at hudson.model.Build$BuildExecution.post2(Build.java:186)
    at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
    at hudson.model.Run.execute(Run.java:1819)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:429)

这是踢球者:我是否获得 i 的值或异常,似乎取决于先前的运行。

如果我用 reboot 命令运行它几次,我总是会得到异常。如果我用 echo 命令(当前已注释掉)运行它几次,我总是得到打印 i 的预期结果。但是,如果我使用 reboot 命令运行它,然后将其切换到 echo 命令并运行几次,第一次使用 echo 它会给出异常,之后它会给出 i 的值。如果我从 echo 命令切换到 reboot 命令,第一次运行 reboot 也会很好(打印 i 的值),然后它会开始给出异常。

我不太明白上一次运行如何影响当前运行的超时......

再次感谢任何输入!

4

0 回答 0