Skip to content

Commit

Permalink
[FIXED JENKINS-26175] Exclusive execution mode can now be configured to
Browse files Browse the repository at this point in the history
skip waiting for currently running jobs
[FIXED JENKINS-24854] Shutdown mode is now also cancelled if job is
canceled in pre-build phase
[FIXED JENKINS-26351] Spanish translation added
  • Loading branch information
fmiguelez committed Jan 15, 2015
1 parent 819ed43 commit a6175f1
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 66 deletions.
11 changes: 4 additions & 7 deletions README
Expand Up @@ -3,15 +3,12 @@ Allows a job to be executed when no other jobs are allowed to run
The pre-job steps are:

1. The plugin will initiate a shutdown mode which means that no other jobs can be started.
2. it waits until every job execept this one is finished and then starts to execute the job.
2. It waits until every job except this one has finished, unless it is indicated not to wait through optional flag.
3. Then it starts to execute the job.

The post-job steps are:
1. Inactivates jenkins shutdown mode

Combining this plugin with for instance scheduled build will pause the build queue and let executing jobs
finish before invoking this job. When this job is done, it unpauses the build queue.


Plugin is created by Marco Ambu but almost completely rewritten by Sam Tavakoli.

Combining this plugin with for instance scheduled build will pause the build queue. When this job is done, it unpauses the build queue.

Plugin was created by Marco Ambu but almost completely rewritten by Sam Tavakoli.
5 changes: 5 additions & 0 deletions pom.xml
Expand Up @@ -37,6 +37,11 @@
<name>Sam Tavakoli</name>
<email>sam@tavakoli.se</email>
</developer>
<developer>
<id>fmiguelez</id>
<name>Fernando Miguélez Palomo</name>
<email>fernando.miguelez@gmail.com</email>
</developer>
</developers>

<scm>
Expand Down
Expand Up @@ -44,70 +44,65 @@
*
* @author marco.ambu
* @author Sam Tavakoli
* @author Fernando Miguélez Palomo
*/
public class ExclusiveBuildWrapper extends BuildWrapper {
private boolean skipWait;

private boolean skipWaitOnRunningJobs;

@DataBoundConstructor
public ExclusiveBuildWrapper(boolean enabled, boolean skipWait) {
public ExclusiveBuildWrapper(boolean enabled, boolean skipWaitOnRunningJobs) {
super();
this.skipWait = skipWait;
this.skipWaitOnRunningJobs = skipWaitOnRunningJobs;
}

public boolean isSkipWait()
{
return skipWait;

public boolean isSkipWaitOnRunningJobs() {
return skipWaitOnRunningJobs;
}

@Override
public BuildWrapper.Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener)
throws InterruptedException{
public BuildWrapper.Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener)
throws InterruptedException {
String nodeName = Computer.currentComputer().getDisplayName();

DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_executingOn() + " " + nodeName);
DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_shutdownMessage());

try {
Jenkins.getInstance().doQuietDown();
} catch (IOException e) {
DebugHelper.fatalError(listener, Messages.ExclusiveBuildWrapper_errorQuietMode() + " " +
e.getMessage());
DebugHelper.fatalError(listener, Messages.ExclusiveBuildWrapper_errorQuietMode() + " "
+ e.getMessage());
e.printStackTrace(listener.getLogger());
}

if(skipWait)
{
DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_waitSkipped());
}
else
{
DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_waiting());
while (areComputersIdle(nodeName, Jenkins.getInstance().getComputers()) == false) {
try
{
Thread.sleep(500);
}
catch(InterruptedException e) {
// Gracefully cancel shutdown if job is canceled in pre-build phase
cancelShutdown(listener);
throw e;
}
}

DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_onlyJobRunning());
if (skipWaitOnRunningJobs) {
DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_waitSkipped());
} else {
DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_waiting());
while (areComputersIdle(nodeName, Jenkins.getInstance().getComputers()) == false) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
//Gracefully cancel shutdown if job is canceled in pre-build phase
cancelShutdown(listener);
throw e;
}
}

DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_onlyJobRunning());
}

return new ExclusiveEnvironment(listener);
}

/**
* @param nodeName the name of the node where this job is running from
* @param computers all computers who has executors available
* @return true if this job is the only one being executed on this node and all other nodes
* are idle. false otherwise
* @return true if this job is the only one being executed on this node and
* all other nodes are idle. false otherwise
*/
private boolean areComputersIdle(String nodeName, Computer[] computers){
private boolean areComputersIdle(String nodeName, Computer[] computers) {
for (Computer computer : computers) {
//any other computer than the one the job is executed on should be idle
if (computer.getDisplayName().equals(nodeName) == false && computer.isIdle() == false) {
Expand All @@ -122,8 +117,8 @@ private boolean areComputersIdle(String nodeName, Computer[] computers){
}

/**
* Descriptor for {@link ExclusiveBuildWrapper}. Used as a singleton.
* The class is marked as public so that it can be accessed from views.
* Descriptor for {@link ExclusiveBuildWrapper}. Used as a singleton. The
* class is marked as public so that it can be accessed from views.
*/
@Extension
public static final class DescriptorImpl extends BuildWrapperDescriptor {
Expand All @@ -137,15 +132,19 @@ public boolean isApplicable(AbstractProject item) {
return true;
}
}

private void cancelShutdown(BuildListener listener)
{

/**
* Cancels Jenkins shutdown mode
*
* @param listener the listener to get the logger from
*/
private void cancelShutdown(BuildListener listener) {
DebugHelper.info(listener, Messages.ExclusiveBuildWrapper_cancelShutDownMode());
Jenkins.getInstance().doCancelQuietDown();
}

/**
* handles the post-build tasks such as canceling the quiet down sequencing
* handles the post-build tasks such as canceling the quiet down sequencing
*
*/
private class ExclusiveEnvironment extends Environment {
Expand All @@ -157,9 +156,9 @@ public ExclusiveEnvironment(BuildListener listener) {

@Override
public boolean tearDown(AbstractBuild build, BuildListener listener) {
cancelShutdown(listener);
cancelShutdown(listener);
return true;
}
}

}
@@ -1,5 +1,5 @@
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:entry field="skipWait">
<f:entry field="skipWaitOnRunningJobs">
<f:checkbox title="${%Do not wait till running jobs end}"/>
</f:entry>
</j:jelly>
@@ -1,6 +1,6 @@
Set this flag to execute this job when you want no other jobs to run.<br />
Set this flag to prevent other jobs from starting once this job has started.<br />
<br />
Jenkins is put in shutdown mode when this job is started. Then the real execution of this job starts when this job is the only one running.<br/>
Waiting can be skipped by setting flag <i>"Do not wait till running jobs end"</i>.<br/>
Jenkins is put in shutdown mode when this job is started. Build steps are not actually executed until this job is the only one running,<br/>
unless optional flag "Do not wait till running jobs end"</i> is enabled.<br/>
<br />
At the end of the build the Jenkins shutdown mode is canceled.
At the end of the build the Jenkins shutdown mode is canceled.
@@ -1,6 +1,6 @@
Activar esta opción para ejecutar este trabajo sin que nigún otro más sea ejecutado a la vez.<br />
Activar esta opción para impedir que otros trabajos comiencen una vez que este trabajo ha comenzado.<br />
<br />
Cuando el trabajo comienza se pone Jenkins en modo apagado. Antes de continuar con la fase de ejecución el trabajo espera hasta que sólo queda él en ejecución.<br/>
Esta espera puede omitirse activando la opción <i>"No esperar a que terminen los trabajos en ejecución"</i>.<br />
Cuando el trabajo comienza se pone Jenkins en modo apagado. Los pasos de la fase de construcción no se ejecutan realmente hasta que éste <br/>
es el único trabajo que queda en ejecución, a menos que se habilite la opción <i>"No esperar a que terminen los trabajos en ejecución"</i>.<br/>
<br/>
Cuando finaliza la construcción se cancela el modo apagado de Jenkins.
Cuando finaliza la construcción se cancela el modo apagado de Jenkins.
4 changes: 2 additions & 2 deletions src/main/resources/index.jelly
@@ -1,3 +1,3 @@
<div>
This plugin allows to execute a job when no other jobs are allowed to run.
</div>
This plugin allows configuring a job to prevent the rest from starting its execution while this is running.
</div>

0 comments on commit a6175f1

Please sign in to comment.