如何在Computer.waitUntilOnline上设置超时

时间:2018-08-13 07:44:15

标签: jenkins groovy post-build

短版

在Jenkins构建后的Groovy脚本中,是否有一种方法可以使Computer.waitUntilOnline函数在一段时间后超时?

背景

我们对嵌入式设备进行测试,而我们的jenkins奴隶是连接到某些硬件设置的笔记本电脑。在某些情况下,我们需要使用繁琐的构建后脚本重新启动计算机,然后等待计算机再次联机。但是,有时这些机器不会再次联机,我们的常规脚本会无限期地等待。

waitUntilOnline函数可以引发InterruptedException,但是from what I can tell您需要运行多个线程才能触发该异常。运行多个线程只是为了触发超时,这似乎是错误的处理方式。

我还发现some information是使用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]

任何建议都值得赞赏。

编辑: 我也尝试过this question中提到的@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的预期结果。 但是,如果我使用重新启动命令运行它,然后将其切换到echo命令并运行几次,第一次使用echo将给出异常,此后它将给出i的值。 而且,如果我从echo命令切换到reboot命令,则第一次重新启动也可以(打印i的值),然后再开始给出异常。

我不太了解前一次运行如何影响当前运行的超时...

再次感谢您的任何投入!

0 个答案:

没有答案