mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-04 07:35:53 +00:00
Basic implementation of prevalidateConfig working.
This commit is contained in:
1 parent
fe6dbcd779
commit
2658f36994
3 files changed
+119
-2
No files matched your search
@@ -98,6 +98,12 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static hudson.init.InitMilestone.*;
|
||||
import hudson.util.VersionNumber;
|
||||
import java.util.TreeMap;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
* Manages {@link PluginWrapper}s.
|
||||
@@ -740,7 +746,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
* If the configuration (typically a job’s {@code config.xml})
|
||||
* needs some plugins to be installed (or updated), those jobs
|
||||
* will be triggered.
|
||||
* Plugins are dynamically loaded if possible (see {@link hudson.model.UpdateSite.Plugin#deploy(boolean)}).
|
||||
* Plugins are dynamically loaded whenever possible.
|
||||
* Requires {@link Jenkins#ADMINISTER}.
|
||||
* @param configXml configuration that might be uploaded
|
||||
* @return an empty list if all is well, else a list of submitted jobs which must be completed before this configuration can be fully read
|
||||
@@ -748,11 +754,83 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
* @see ItemGroupMixIn#createProjectFromXML
|
||||
* @see AbstractItem#updateByXml(javax.xml.transform.Source)
|
||||
* @see XStream2
|
||||
* @see hudson.model.UpdateSite.Plugin#deploy(boolean)
|
||||
* @see PluginWrapper#supportsDynamicLoad
|
||||
* @see hudson.model.UpdateCenter.DownloadJob.SuccessButRequiresRestart
|
||||
* @since XXX
|
||||
*/
|
||||
public List<Future<UpdateCenter.UpdateCenterJob>> prevalidateConfig(InputStream configXml) throws IOException {
|
||||
Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER);
|
||||
return Collections.emptyList(); // XXX
|
||||
List<Future<UpdateCenter.UpdateCenterJob>> jobs = new ArrayList<Future<UpdateCenter.UpdateCenterJob>>();
|
||||
UpdateCenter uc = Jenkins.getInstance().getUpdateCenter();
|
||||
// XXX call uc.updateAllSites() when available? perhaps not, since we should not block on network here
|
||||
for (Map.Entry<String,VersionNumber> requestedPlugin : parseRequestedPlugins(configXml).entrySet()) {
|
||||
PluginWrapper pw = getPlugin(requestedPlugin.getKey());
|
||||
if (pw == null) { // install new
|
||||
UpdateSite.Plugin toInstall = uc.getPlugin(requestedPlugin.getKey());
|
||||
if (toInstall == null) {
|
||||
LOGGER.log(Level.WARNING, "No such plugin {0} to install", requestedPlugin.getKey());
|
||||
continue;
|
||||
}
|
||||
if (new VersionNumber(toInstall.version).compareTo(requestedPlugin.getValue()) < 0) {
|
||||
LOGGER.log(Level.WARNING, "{0} can only be satisfied in @{1}", new Object[] {requestedPlugin, toInstall.version});
|
||||
}
|
||||
if (toInstall.isForNewerHudson()) {
|
||||
LOGGER.log(Level.WARNING, "{0}@{1} was built for a newer Jenkins", new Object[] {toInstall.name, toInstall.version});
|
||||
}
|
||||
jobs.add(toInstall.deploy(true));
|
||||
} else if (pw.isOlderThan(requestedPlugin.getValue())) { // upgrade
|
||||
UpdateSite.Plugin toInstall = uc.getPlugin(requestedPlugin.getKey());
|
||||
if (toInstall == null) {
|
||||
LOGGER.log(Level.WARNING, "No such plugin {0} to upgrade", requestedPlugin.getKey());
|
||||
continue;
|
||||
}
|
||||
if (!pw.isOlderThan(new VersionNumber(toInstall.version))) {
|
||||
LOGGER.log(Level.WARNING, "{0}@{1} is no newer than what we already have", new Object[] {toInstall.name, toInstall.version});
|
||||
continue;
|
||||
}
|
||||
if (new VersionNumber(toInstall.version).compareTo(requestedPlugin.getValue()) < 0) {
|
||||
LOGGER.log(Level.WARNING, "{0} can only be satisfied in @{1}", new Object[] {requestedPlugin, toInstall.version});
|
||||
}
|
||||
if (toInstall.isForNewerHudson()) {
|
||||
LOGGER.log(Level.WARNING, "{0}@{1} was built for a newer Jenkins", new Object[] {toInstall.name, toInstall.version});
|
||||
}
|
||||
if (!toInstall.isCompatibleWithInstalledVersion()) {
|
||||
LOGGER.log(Level.WARNING, "{0}@{1} is incompatible with the installed @{2}", new Object[] {toInstall.name, toInstall.version, pw.getVersion()});
|
||||
}
|
||||
jobs.add(toInstall.deploy(true)); // dynamicLoad=true => sure to throw RestartRequiredException, but at least message is nicer
|
||||
} // else already good
|
||||
}
|
||||
return jobs;
|
||||
}
|
||||
|
||||
static Map<String,VersionNumber> parseRequestedPlugins(InputStream configXml) throws IOException {
|
||||
final Map<String,VersionNumber> requestedPlugins = new TreeMap<String,VersionNumber>();
|
||||
try {
|
||||
SAXParserFactory.newInstance().newSAXParser().parse(configXml, new DefaultHandler() {
|
||||
@Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
String plugin = attributes.getValue("plugin");
|
||||
if (plugin == null) {
|
||||
return;
|
||||
}
|
||||
if (!plugin.matches("[^@]+@[^@]+")) {
|
||||
throw new SAXException("Malformed plugin attribute: " + plugin);
|
||||
}
|
||||
int at = plugin.indexOf('@');
|
||||
String shortName = plugin.substring(0, at);
|
||||
VersionNumber existing = requestedPlugins.get(shortName);
|
||||
VersionNumber requested = new VersionNumber(plugin.substring(at + 1));
|
||||
if (existing == null || existing.compareTo(requested) < 0) {
|
||||
requestedPlugins.put(shortName, requested);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (IOException x) {
|
||||
throw x;
|
||||
} catch (Exception x) {
|
||||
throw (IOException) new IOException(x.toString()).initCause(x);
|
||||
}
|
||||
return requestedPlugins;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user