-
Notifications
You must be signed in to change notification settings - Fork 411
/
ProperlyStopOnlyRunningPipelines.groovy
89 lines (77 loc) · 3.37 KB
/
ProperlyStopOnlyRunningPipelines.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/bin/env groovy
/*
Author: Alex Taylor, Allan Burdajewicz
Since: July 2019
Description: This script stop all or a series of running pipeline jobs, but only pipelines that have steps running on an heavyweight executor.
If the pipeline execution is not currently executing steps on a node, it is not interrupted (typically, when waiting on an input step outside
a node block)
Parameters: None
Scope: Cloudbees Jenkins Platform
*/
/* This script can be used to kill off all running jobs which have been running for a certain amount of time. This
script will guaranteed take 30 seconds to run because we want to ensure that each build command has the time needed
to run. It is best to set Jenkins in a Quietdown (Shutdown) mode before running the script. */
import groovy.time.TimeCategory
import hudson.model.Queue
import org.jenkinsci.plugins.workflow.job.WorkflowRun
import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution
/**
* Try to infer the WorkflowRun of the executable passed in.
* @param executable The executable
* @return The WorkflowRun, or null if this is not a Pipeline run
*/
WorkflowRun getPipelineRunFromExecutable(Queue.Executable executable) {
if (executable instanceof WorkflowRun) {
return ((WorkflowRun) executable)
}
if (executable.parent instanceof ExecutorStepExecution.PlaceholderTask) {
def executorPlaceholderTask = ((ExecutorStepExecution.PlaceholderTask) executable.parent)
return ((WorkflowRun) executorPlaceholderTask.runForDisplay())
}
return null
}
def doForAllPipelineInProgress = { Closure closure ->
use(TimeCategory) {
def delay = 1.hours
def processedPipeline = []
jenkins.model.Jenkins.instanceOrNull.getComputers().each { computer ->
computer.executors.findAll { exec -> exec.isBusy() && exec.currentExecutable && exec.elapsedTime > delay.toMilliseconds() }.each { exec ->
def currentPipelineRun = getPipelineRunFromExecutable(exec.currentExecutable)
if (currentPipelineRun) {
def pipelineRunId = currentPipelineRun.getExternalizableId()
if(!processedPipeline.contains(pipelineRunId)) {
processedPipeline.add(pipelineRunId)
closure(exec, currentPipelineRun)
} else {
println " (Already processed ${currentPipelineRun})"
}
}
}
}
}
}
boolean somethingHappened = false
doForAllPipelineInProgress { exec, run ->
println " * Stopping ${run.fullDisplayName} that spent ${exec.elapsedTime}ms building on ${exec.owner.displayName} #${exec.number}..."
run.doStop()
somethingHappened = true
}
if(somethingHappened) {
somethingHappened = false
sleep(30000)
doForAllPipelineInProgress { exec, run ->
println " * Forcibly Terminating ${run.fullDisplayName} that spent ${exec.elapsedTime}ms building on ${exec.owner.displayName} #${exec.number}..."
run.doTerm()
somethingHappened = true
}
}
if(somethingHappened) {
somethingHappened = false
sleep(30000)
doForAllPipelineInProgress { exec, run ->
println " * Forcibly Killing ${run.fullDisplayName} that spent ${exec.elapsedTime}ms building on ${exec.owner.displayName} #${exec.number}..."
run.doKill()
somethingHappened = true
}
}
return