58

对于使用 Groovy 系统脚本的 Jenkins,有没有一种方法可以轻松地搜索构建队列和执行构建列表的某些条件(特别是匹配某些条件的参数),然后杀死/取消它们?

我似乎找不到任何方法来做到这一点,但它似乎应该是可能的。

4

10 回答 10

88

我自己没有测试过,但是看看API应该可以通过以下方式:

import hudson.model.*
import jenkins.model.Jenkins

def q = Jenkins.instance.queue

q.items.findAll { it.task.name.startsWith('my') }.each { q.cancel(it.task) }

相关API链接:

于 2012-09-11T05:41:58.397 回答
54

我知道这是一个老问题,但谷歌给我指出了这个问题。此处显示的脚本仅从队列中删除作业,并且不会停止运行构建。以下脚本只是从队列中删除所有内容并终止所有正在运行的构建:

  import java.util.ArrayList
  import hudson.model.*;
  import jenkins.model.Jenkins

  // Remove everything which is currently queued
  def q = Jenkins.instance.queue
  for (queued in Jenkins.instance.queue.items) {
    q.cancel(queued.task)
  }

  // stop all the currently running jobs
  for (job in Jenkins.instance.items) {
    stopJobs(job)
  }

  def stopJobs(job) {
    if (job in com.cloudbees.hudson.plugins.folder.Folder) {
      for (child in job.items) {
        stopJobs(child)
      }    
    } else if (job in org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject) {
      for (child in job.items) {
        stopJobs(child)
      }
    } else if (job in org.jenkinsci.plugins.workflow.job.WorkflowJob) {

      if (job.isBuilding()) {
        for (build in job.builds) {
        build.doKill()
        }
      }
    }
  }
于 2017-12-04T10:58:34.070 回答
41

参考:https ://xanderx.com/post/cancel-all-queued-jenkins-jobs/

在 Manage Jenkins > Script Console 中运行它:

Jenkins.instance.queue.clear()
于 2019-08-08T09:47:52.223 回答
9

无法添加为评论,但截至今天最新的詹金斯,安德烈的脚本(很好)需要另一个导入才能工作。作为系统 Groovy 脚本执行。

詹金斯错误并提到了缺失的课程。我包括了提到这个问题的网址:

//import hudson.model.*
// per http://stackoverflow.com/questions/17429050/running-groovy-command-from-jenkins-using-groovy-script-plugin
// requires this now
import jenkins.model.Jenkins 

def q = Jenkins.instance.queue

q.items.findAll { it.task.name.startsWith('my') }.each { q.cancel(it.task) }
于 2015-06-09T08:08:29.327 回答
7

经过一番调查,我想出了这段代码,它对我来说绝对没问题。它清除队列并中止当前正在执行的所有作业。

先决条件:

  1. “全部”视图包含所有作业
  2. 使用系统常规
import jenkins.model.Jenkins
import hudson.*
import hudson.model.*
import jenkins.*

// Remove everything which is currently queued

Jenkins.instance.queue.clear()
def buildingJobs = Jenkins.instance.getAllItems(Job.class).findAll {
    it.isBuilding()
}

buildingJobs.each {
    def jobName = it.toString()
    def val = jobName.split("\\[|\\]")

    // 'Abort jobs' is the name of the job I have created, and I do not want it to abort itself.

    if((val[1].trim())!='Abort jobs') {
        def job = Jenkins.instance.getItemByFullName(val[1].trim())
        for (build in job.builds) {
            if (build.isBuilding()) {
                println(build)
                build.doStop();
            }
        }
    }
}

于 2019-09-25T09:03:53.303 回答
4

这是我的解决方案,如果您只想从构建队列中运行同一项目的最新作业并取消其他作业:

def q = Jenkins.instance.queue
//Find items in queue that match <project name>
def queue = q.items.findAll { it.task.name.startsWith('sample_project') }
//get all jobs id to list
def queue_list = []
queue.each { queue_list.add(it.getId()) }
//sort id's, remove last one - in order to keep the newest job, cancel the rest
queue_list.sort().take(queue_list.size() - 1).each { q.doCancelItem(it) }
于 2016-09-22T09:51:52.187 回答
3

使用 jenkins groovy postbuild 插件:
我认为这将是 groovy 脚本:

import hudson.model.*  
def q = jenkins.model.Jenkins.getInstance().getQueue()   
def items = q.getItems()  
for (i=0;i<items.length;i++){  
  if(items[i].task.getName() == "job_name"){  
  items[i].doCancelQueue()  
}   
}  
于 2015-02-05T15:21:53.433 回答
0

我已经扩展了Igor Zilberman的代码片段,这样当队列中有相同原因的作业时,它也会中止正在运行的作业(当您将鼠标悬停在构建队列中的作业上时,您会看到,只查看第一行)。我将其作为构建步骤“执行系统 ​​Groovy 脚本”的作业运行。


import hudson.model.Result
import jenkins.model.CauseOfInterruption
import jenkins.model.*;

[ // setup job names here
'my-jobname-here'   
].each {jobName ->  
  def queue = Jenkins.instance.queue  
  def q = queue.items.findAll { it.task.name.equals(jobName) }  
  def r = [:]  
  def projs = jenkins.model.Jenkins.instance.items.findAll { it.name.equals(jobName) }  

  projs.each{p ->  
    x = p._getRuns()  
    x.each{id, y ->  
      r.put(id, y)  
    }  
  }  

  TreeMap queuedMap = [:]  
  TreeMap executingMap = [:]  

  q.each{i->  
    queuedMap.put(i.getId(), i.getCauses()[0].getShortDescription()) //first line  
  }  
  r.each{id, run->  
    def exec = run.getExecutor()  
    if(exec != null){  
      executingMap.put(id, run.getCauses()[0].getShortDescription()) //first line  
    }  
  }  

  println("Queued:")  
  queuedMap.each{ k, v -> println "${k}:${v}" }  
  println("Executing:")  
  executingMap.each{ k, v -> println "${k}:${v}" }  

  // First, if there is more than one queued entry, cancel all but the highest one.  
  // Afterwards, if there is a queued entry, cancel the running ones  

  def queuedNames = queuedMap.values();  
  queuedNames.each{n ->  
    def idsForName = []  
    queuedMap.each{ id, name ->  
      if(name.equals(n)){  
        idsForName.add(id)  
      }  
    }  
    if (idsForName.size() > 1){  
      println("Cancelling queued job: "+n)  
    }  
    // remove all but the latest from queue  
    idsForName.sort().take(idsForName.size() - 1).each { queue.doCancelItem(it) }  
  }  
  executingMap.each{ id, name ->  
    if(queuedMap.values().contains(name)){  
      r.each{rid, run->  
        if (id == rid){  
          def exec = run.getExecutor()  
          if(exec != null){  
            println("Aborting running job: "+id+": "+name)  
            exec.interrupt(Result.ABORTED)  
          }  
        }  
      }  
    }  
  }  
}  
return "Done"
于 2017-07-07T17:21:07.350 回答
0

导入 hudson.model.*

def queue = Hudson.instance.queue

println "队列包含 ${queue.items.length} 个项目"

queue.clear()

println "队列已清空"


将此粘贴到“脚本控制台”中 - jenkins > Manage Jenkins > Script Console 并点击运行。这有助于清除队列并显示已清除的号码。

于 2021-07-12T09:40:12.167 回答
-2

要控制作业构建队列,您也可以使用此插件: https ://wiki.jenkins-ci.org/display/JENKINS/Block+queued+job+plugin

  • 当定义的目标项目的最后一次构建处于构建状态时阻止作业
  • 当定义的目标项目的最后一次构建产生结果时阻止作业
于 2015-06-14T08:18:21.907 回答