我们的Jenkins服务器有一个已经运行了三天的作业,但是没有做任何事情。单击角落里的小X没有任何作用,控制台输出日志也没有显示任何内容。我在我们的构建服务器上检查过,该作业实际上似乎根本没有在运行。

有没有办法告诉jenkins工作已经“完成”了,比如编辑一些文件或锁之类的?因为我们有很多任务,所以我们并不想重新启动服务器。


当前回答

我编写的一个名为jkillthread的实用程序可以用来停止任何Java进程中的任何线程,只要您能够以相同的帐户登录到运行该服务的机器。

其他回答

在https://my-jenkins/script上使用脚本控制台

import hudson.model.Job
import org.jenkinsci.plugins.workflow.job.WorkflowRun

Collection<Job> jobs = Jenkins.instance.getItem('My-Folder').getAllJobs()
for (int i = 0; i < jobs.size(); i++) {
  def job = jobs[i]
  for (int j = 0; j < job.builds.size(); j++) {
    WorkflowRun build = job.builds[j]
    if (build.isBuilding()) {
      println("Stopping $job ${build.number}")
      build.setResult(Result.FAILURE)
    }
  }
}

上面的答案对我来说几乎是可行的,但我有一个主要问题:由于Jenkins重启的时间特别糟糕,我有非常多的僵尸作业(大约100个),所以手动查找每个僵尸作业的作业名称和构建号,然后手动杀死它们是不可可行的。以下是我如何自动找到并杀死僵尸工作的方法:

Jenkins.instance.getItemByFullName(multibranchPipelineProjectName).getItems().each { repository->
  repository.getItems().each { branch->
    branch.builds.each { build->
      if (build.getResult().equals(null)) {
        build.doKill()
      }
    }
  }
}

该脚本遍历所有作业的所有构建,并使用getResult().equals(null)来确定作业是否已经完成。在队列中但尚未开始的构建将不会被迭代(因为该构建不会在job.builds中),并且已经完成的构建对于build. getresult()将返回非null的值。合法运行的作业的构建结果也会为null,因此在运行此作业之前,请确保没有不想终止的正在运行的作业。

在Multibranch Pipeline项目中,多个嵌套循环主要用于发现每个存储库的每个分支/PR;如果你没有使用Multibranch pipeline,你可以直接使用Jenkins.instance.getItems().each这样的东西来循环所有的作业。

我看了Jenkins源代码,似乎我要做的是不可能的,因为停止一个作业似乎是通过线程中断完成的。我不知道为什么这个工作被搁置了。

编辑:

就业势不可挡的可能原因:

如果Jenkins陷入了无限循环,它就永远不能中止。 如果Jenkins在Java虚拟机中进行网络或文件I/O(例如长时间的文件复制或SVN更新),则不能中止。

如果“X”按钮不起作用,作业被卡住,那么只需删除特定的版本号。这将解放遗嘱执行人。

在我的例子中,即使工作完成了,它仍然停留在执行者几个小时。删除构建对我来说是有效的。

有同样的问题,但没有堆栈线程。我们使用Jenkins控制台中的这个片段删除了作业。将jobname和build dnumber替换为您的。

def jobname = "Main/FolderName/BuildDefinition"
def buildnum = 6
Jenkins.instance.getItemByFullName(jobname).getBuildByNumber(buildnum).delete();