9

Is it possible to specify that, in case on job (A) is triggered more than once, that previous jobs are removed from queue, and only latest one is left in queue or started if there are enough free slots?

Thanks in advance!

Dejan Menges
  • 325
  • 3
  • 13

3 Answers3

6

use execute system groovy script step:

import hudson.model.Result
import jenkins.model.CauseOfInterruption

//iterate through current project runs
build.getProject()._getRuns().each{id,run->
  def exec = run.getExecutor()
  //if the run is not a current build and it has executor (running) then stop it
  if( run!=build && exec!=null ){
    //prepare the cause of interruption
    def cause = new CauseOfInterruption(){ 
      public String getShortDescription(){
        return "interrupted by build #${build.getId()}"
      }
    }
    exec.interrupt(Result.ABORTED, cause)
  }
}

//just for test do something long...
Thread.sleep(10000)

and in the interrupted job there will be a log:

Build was aborted
interrupted by build #12
Finished: ABORTED 
daggett
  • 26,404
  • 3
  • 40
  • 56
3

You can do it with a system Groovy Script run via Groovy Script Plugin. Such a script has direct access to Jenkins via its programming API. I do not see any other way.

malenkiy_scot
  • 16,415
  • 6
  • 64
  • 87
  • 2
    There is a script console at `http://[jenkins_server]/script` which is extremely useful for experimenting with and debugging Groovy scripts. – malenkiy_scot Apr 23 '12 at 19:22
  • So I did investigation today, using advice from Scot, but it looks like it's possible to do exactly opposite of what I need. If I use groovy script and Jenkins API as first task, using that to determine information that I need, that script won't be run until job is not taken off the queue and run by Jenkins, what makes it useful if you want to kill all jobs behind you (in the queue in that moment) but it's not possible to start it somehow while it's on the queue, to kill oldest instead of newest. Continuing with investigation, will update if I figure out something. – Dejan Menges Apr 24 '12 at 15:37
  • Yes, of course - a job can't do anything until it's actually run. How about this: job _T_ (for Trigger) checks the queue for other instances of _T_ and kills all of them, except for the last one, and also exits itself. If the queue is empty - it starts job _A_. – malenkiy_scot Apr 24 '12 at 17:39
  • Sure, that should work. Or will test also with even simplier - kill myself if there's another instance of my own type. – Dejan Menges Apr 25 '12 at 07:13
  • 2
    @DejanMenges Did you manage to solve this? can you show your script? – Daniel Mar 06 '17 at 14:22
1

I don't think this problem can be solved perfectly by only adding a groovy script before build. If the new job come in while the older has already been building(it can't check the queue, since its pre-build part has passed), the new one still has to wait.

As I see, to achieve a preemptive job of jenkins, we need create another oversee job. This job should check that if there are new builds in the queue regularly and terminate older one if necessary.

But create a oversee job seems complex. I also expect a perfect solution.

R.Liu
  • 361
  • 3
  • 6