Peruuta jonossa olevat rakennukset ja keskeyttävät suorittavat rakennukset käyttämällä Groovy for Jenkins -sovellusta

original title: "Cancel queued builds and aborting executing builds using Groovy for Jenkins"


Translate

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.



Jenkinsille, jotka käyttävät Groovy System Scriptiä, onko olemassa tapa etsiä helposti rakennusjonosta ja suorittavien rakennusten luettelosta joillekin kriteereille (erityisesti parametrille, joka vastaa ...

Tämä on yhteenveto käännöksen jälkeen. Jos haluat tarkastella koko käännöstä, napsauta käännä-kuvaketta


Kaikki vastaukset
  • Translate

    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:


  • Translate

    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()
            }
          }
        }
      }
    

  • Translate

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

    Run this in Manage Jenkins > Script Console:

    Jenkins.instance.queue.clear()
    

  • Translate

    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) }
    

  • Translate

    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) }
    

  • Translate

    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()  
    }   
    }  
    

  • Translate

    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:

    1. 'All' view contains all the jobs
    2. Use System groovy
    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();
    
                }
    
    
            }
    
        }
    
    }
    
    

  • Translate

    To control Job build queue, you can use this Plugin also: https://wiki.jenkins-ci.org/display/JENKINS/Block+queued+job+plugin

    • To block job when last build of defined target project is in building status
    • To block job when last build of defined target project has result

  • Translate

    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"