From 0c95d25c28c3f71d395d7e7d9121dbd3bd4bc2aa Mon Sep 17 00:00:00 2001 From: kzantow Date: Fri, 29 Apr 2016 11:58:04 -0400 Subject: [PATCH] Fix dynamic load for disabled plugins which are enabled as part of required dependencies; this may still have some issues in unknown cases such as a plugin disabled, then re-enabled without restarting Jenkins but it fixes one of the primary cases --- core/src/main/java/hudson/PluginManager.java | 27 ++++++++++++++-- .../main/java/hudson/model/UpdateCenter.java | 32 ++++++++++++------- .../main/java/hudson/model/UpdateSite.java | 4 +-- .../model/UpdateCenter/EnableJob/row.jelly | 2 +- .../model/UpdateCenter/NoOpJob/row.jelly | 2 +- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 1062ae467a..05050ffeb5 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -108,6 +108,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.ListIterator; @@ -659,6 +660,14 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas * TODO: revisit where/how to expose this. This is an experiment. */ public void dynamicLoad(File arc) throws IOException, InterruptedException, RestartRequiredException { + dynamicLoad(arc, false); + } + + /** + * Try the dynamicLoad, removeExisting to attempt to dynamic load disabled plugins + */ + @Restricted(NoExternalUse.class) + public void dynamicLoad(File arc, boolean removeExisting) throws IOException, InterruptedException, RestartRequiredException { LOGGER.info("Attempting to dynamic load "+arc); PluginWrapper p = null; String sn; @@ -669,9 +678,21 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas p = strategy.createPluginWrapper(arc); sn = p.getShortName(); } - if (getPlugin(sn)!=null) - throw new RestartRequiredException(Messages._PluginManager_PluginIsAlreadyInstalled_RestartRequired(sn)); - + PluginWrapper pw = getPlugin(sn); + if (pw!=null) { + if (removeExisting) { // try to load disabled plugins + for (Iterator i = plugins.iterator(); i.hasNext();) { + pw = i.next(); + if(sn.equals(pw.getShortName())) { + i.remove(); + pw = null; + break; + } + } + } else { + throw new RestartRequiredException(Messages._PluginManager_PluginIsAlreadyInstalled_RestartRequired(sn)); + } + } if (p == null) { p = strategy.createPluginWrapper(arc); } diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java index 67b42d356d..7bb1e6bebe 100644 --- a/core/src/main/java/hudson/model/UpdateCenter.java +++ b/core/src/main/java/hudson/model/UpdateCenter.java @@ -1408,12 +1408,9 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas /** * Enables a required plugin, provides feedback in the update center */ - public class EnableJob extends UpdateCenterJob { - private final Plugin plugin; - - public EnableJob(UpdateSite site, @Nonnull Plugin plugin) { - super(site); - this.plugin = plugin; + public class EnableJob extends InstallationJob { + public EnableJob(UpdateSite site, Authentication auth, @Nonnull Plugin plugin, boolean dynamicLoad) { + super(plugin, site, auth, dynamicLoad); } public Plugin getPlugin() { @@ -1428,6 +1425,19 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas LOGGER.log(Level.SEVERE, "Failed to enable " + plugin.getDisplayName(), e); error = e; } + + if (dynamicLoad) { + try { + // remove the existing, disabled inactive plugin to force a new one to load + pm.dynamicLoad(getDestination(), true); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Failed to dynamically load " + plugin.getDisplayName(), e); + error = e; + requiresRestart = true; + } + } else { + requiresRestart = true; + } } } @@ -1435,8 +1445,8 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas * A no-op, e.g. this plugin is already installed */ public class NoOpJob extends EnableJob { - public NoOpJob(UpdateSite site, @Nonnull Plugin plugin) { - super(site, plugin); + public NoOpJob(UpdateSite site, Authentication auth, @Nonnull Plugin plugin) { + super(site, auth, plugin, false); } } @@ -1653,19 +1663,19 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas /** * Represents the state of the installation activity of one plugin. */ - public final class InstallationJob extends DownloadJob { + public class InstallationJob extends DownloadJob { /** * What plugin are we trying to install? */ @Exported public final Plugin plugin; - private final PluginManager pm = Jenkins.getInstance().getPluginManager(); + protected final PluginManager pm = Jenkins.getInstance().getPluginManager(); /** * True to load the plugin into this Jenkins, false to wait until restart. */ - private final boolean dynamicLoad; + protected final boolean dynamicLoad; /** * @deprecated as of 1.442 diff --git a/core/src/main/java/hudson/model/UpdateSite.java b/core/src/main/java/hudson/model/UpdateSite.java index aaef48c0fb..5b3a0adfa4 100644 --- a/core/src/main/java/hudson/model/UpdateSite.java +++ b/core/src/main/java/hudson/model/UpdateSite.java @@ -861,12 +861,12 @@ public class UpdateSite { if(pw != null) { // JENKINS-34494 - check for this plugin being disabled Future enableJob = null; if(!pw.isEnabled()) { - UpdateCenter.EnableJob job = uc.new EnableJob(UpdateSite.this, this); + UpdateCenter.EnableJob job = uc.new EnableJob(UpdateSite.this, null, this, dynamicLoad); job.setCorrelationId(correlationId); enableJob = uc.addJob(job); } if(pw.getVersionNumber().equals(new VersionNumber(version))) { - return enableJob != null ? enableJob : uc.addJob(uc.new NoOpJob(UpdateSite.this, this)); + return enableJob != null ? enableJob : uc.addJob(uc.new NoOpJob(UpdateSite.this, null, this)); } } UpdateCenter.InstallationJob job = uc.new InstallationJob(this, UpdateSite.this, Jenkins.getAuthentication(), dynamicLoad); diff --git a/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row.jelly b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row.jelly index f5b8b8c485..f98ff8bc4a 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row.jelly +++ b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row.jelly @@ -27,7 +27,7 @@ THE SOFTWARE. ${it.plugin.displayName} - ${%Enabled} + ${%Enabled Dependency} diff --git a/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row.jelly b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row.jelly index 0dc1670b3b..c6a2e93587 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row.jelly +++ b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row.jelly @@ -27,7 +27,7 @@ THE SOFTWARE. ${it.plugin.displayName} - ${%Already Installed} + ${%Already Installed}