Reputation: 1345
For Jenkins using a Groovy System Script, is there a way to easily search the build queue and list of executing builds for some criteria (specifically a parameter that matches some condition) and then kill/cancel them?
I cannot seem to find any way to do this, but it seems like it should be possible.
Upvotes: 82
Views: 133484
Reputation: 143
import hudson.model.*
def queue = Hudson.instance.queue
println "Queue contains ${queue.items.length} items"
queue.clear()
println "Queue cleared"
paste this in "Script Console" - jenkins > Manage Jenkins > Script Console and hit run. This helped in clearing the queue and also displays the number that is cleared.
Upvotes: 7
Reputation: 169
After some investigation, I came up with this code which works absolutely fine for me. It clears the queue and also aborts all the jobs currently getting executed.
Prerequisites:
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();
}
}
}
}
Upvotes: 14
Reputation: 20663
I haven't tested it myself, but looking at the API it should be possible in the following way:
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) }
Relevant API links:
Upvotes: 107
Reputation: 1903
I know it's kind of an old question, but Google points me to this one. The scripts shown here only remove the jobs from the queue, and don't stop running builds. The following script, just removes everything from the queue and kills all running builds:
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()
}
}
}
}
Upvotes: 67
Reputation: 904
Referencie: https://xanderx.com/post/cancel-all-queued-jenkins-jobs/
Run this in Manage Jenkins > Script Console:
Jenkins.instance.queue.clear()
Upvotes: 64
Reputation: 3109
I've expanded upon the snippet by Igor Zilberman so that it also aborts running jobs when there is a job in the queue with the same cause (what you see when you hover over the job in the build queue, only looking at the first line). I’m running this as a job with build step “Execute System Groovy Script”.
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"
Upvotes: 0
Reputation: 1208
Here is my solution, if you want to run only the newest job of same project from the build queue and cancel other:
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) }
Upvotes: 5
Reputation: 16971
To control Job build queue, you can use this Plugin also: https://wiki.jenkins-ci.org/display/JENKINS/Block+queued+job+plugin
Upvotes: -2
Reputation: 91
couldn't add as a comment, but as of today with latest jenkins, Andrey's script (nice) requires another import to work. Executing as system Groovy script.
Jenkins errors and mentions the missing class. I included the url that mentioned the issue:
//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) }
Upvotes: 9
Reputation: 101
Use the jenkins groovy postbuild plugin:
I think this would be the groovy script:
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()
}
}
Upvotes: 3