We have a Jenkins server which is running somewhere between 20 and 30 jobs.
Since the build process is reasonably complex we're broken the actual build down into 1 sub-builds, some of which can run concurrently, others have to follow previous build steps. As a result we've grouped each of the build steps into 3 groups, which block while the builds are in pogress.
For example:
Main Build : GroupA : Builds A1, A2 & A3 : GroupB : Builds B1, B2 & B3 : GroupC : Builds C1, C2, C3, C4, C5 & C6 : GroupD : HW_Tests T1, T2, T3, T4 & T5 Builds B1, B2 & B3 rely on the output from A1, A2, A3 etc
Since there are builds and tests running pretty much 24/7, I am finding it difficult to schedule a restart of the Jenkins Master. Choosing "Prepare for shutdown" will mean new jobs are queued, but it will invariably block a running job since, to use my example above, if GroupB is active, builds C1, C2, etc will be queued also, and the Main Build will be blocked.
As a work around, I would like to disable the SCM polling on the server until all running jobs have finished. This will prevent new jobs from triggering but also allow the running jobs to finish. I can then restart Jenkins and , re-enable SCM polling, allowing normal service to resume.
The SCM we are using is Perforce.
I have not been able to find anywhere which suggests the above is possible, however, I am sure it must be feasible in System Groovy ... just not sure how. Does anyone here have any ideas please?
Many Thanks
You could disable only those jobs which have an SCM polling trigger. This groovy script will do that:
Hudson.instance.items.each { job -> if ( job.getTrigger( hudson.triggers.SCMTrigger ) != null ) { println "will disable job ${job.name}" job.disable() } }
Re-enabling the jobs will be left as an exercise : )
Try following Groovy script to comment out SCM Polling:
// WARNING: Use on your own risk! Without any warranty! import hudson.triggers.SCMTrigger import hudson.triggers.TriggerDescriptor // from: https://issues.jenkins-ci.org/browse/JENKINS-12785 TriggerDescriptor SCM_TRIGGER_DESCRIPTOR = Hudson.instance.getDescriptorOrDie(SCMTrigger.class) assert SCM_TRIGGER_DESCRIPTOR != null; MAGIC = "#MAGIC# " // comment out SCM Trigger def disable_scmpoll_trigger(trig){ if ( !trig.spec.startsWith(MAGIC) ){ return new SCMTrigger(MAGIC + trig.spec) } return null } // enable commented out SCM Trigger def enable_scmpoll_trigger(trig){ if ( trig.spec.startsWith(MAGIC) ){ return new SCMTrigger(trig.spec.substring(MAGIC.length())) } return null } Hudson.instance.items.each { job -> //println("Checking job ${job.name} of type ${job.getClass().getName()} ...") // from https://stackoverflow.com/a/39100687 def trig = job.getTrigger( hudson.triggers.SCMTrigger ) if ( trig == null ) return println("Job ${job.name} has SCMTrigger: '${trig.spec}'") SCMTrigger newTrig = disable_scmpoll_trigger(trig) // SCMTrigger newTrig = enable_scmpoll_trigger(trig) if (newTrig != null ){ newTrig.ignorePostCommitHooks = trig.ignorePostCommitHooks newTrig.job = job println("Updating SCMTrigger '${trig.spec}' -> '${newTrig.spec}' for job: ${job.name}") job.removeTrigger(SCM_TRIGGER_DESCRIPTOR) job.addTrigger(newTrig) job.save() } } return ''
To enable SCM polling again just change these two lines
//SCMTrigger newTrig = disable_scmpoll_trigger(trig) SCMTrigger newTrig = enable_scmpoll_trigger(trig)
Tested on Jenkins ver. 2.121.3
Known limitations:
- supports single line "Schedule" (
spec
property) only