msrb pushed to jenkins (master). "Migrate to plugins containing symlinks"
notifications at fedoraproject.org
notifications at fedoraproject.org
Thu Apr 16 06:36:59 UTC 2015
>From 6136db2d08f638c0093bb77ea101001213ee9c98 Mon Sep 17 00:00:00 2001
From: Michal Srb <msrb at redhat.com>
Date: Thu, 16 Apr 2015 08:36:26 +0200
Subject: Migrate to plugins containing symlinks
diff --git a/add-support-for-plugins-from-RPMs.patch b/add-support-for-plugins-from-RPMs.patch
deleted file mode 100644
index cb9b263..0000000
--- a/add-support-for-plugins-from-RPMs.patch
+++ /dev/null
@@ -1,322 +0,0 @@
-diff --git a/core/src/main/java/hudson/LocalPluginManager.java b/core/src/main/java/hudson/LocalPluginManager.java
-index 4cfbf6a..ceaaf7f 100644
---- a/core/src/main/java/hudson/LocalPluginManager.java
-+++ b/core/src/main/java/hudson/LocalPluginManager.java
-@@ -27,9 +27,11 @@ package hudson;
- import jenkins.model.Jenkins;
-
- import javax.servlet.ServletContext;
-+
- import java.io.File;
- import java.io.IOException;
- import java.net.URL;
-+import java.nio.file.Paths;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashSet;
-@@ -69,12 +71,13 @@ public class LocalPluginManager extends PluginManager {
- ServletContext context = Jenkins.getInstance().servletContext;
-
- for( String path : Util.fixNull((Set<String>)context.getResourcePaths("/WEB-INF/plugins"))) {
-- String fileName = path.substring(path.lastIndexOf('/')+1);
-- if(fileName.length()==0) {
-- // see http://www.nabble.com/404-Not-Found-error-when-clicking-on-help-td24508544.html
-- // I suspect some containers are returning directory names.
-- continue;
-- }
-+// String fileName = path.substring(path.lastIndexOf('/')+1);
-+// if(fileName.length()==0) {
-+// // see http://www.nabble.com/404-Not-Found-error-when-clicking-on-help-td24508544.html
-+// // I suspect some containers are returning directory names.
-+// continue;
-+// }
-+ String fileName = Paths.get(path).getFileName().toString();
- try {
- names.add(fileName);
-
-diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java
-index 41605ee..8fc9ccd 100644
---- a/core/src/main/java/hudson/PluginManager.java
-+++ b/core/src/main/java/hudson/PluginManager.java
-@@ -53,6 +53,7 @@ import jenkins.model.Jenkins;
- import jenkins.util.io.OnMaster;
- import net.sf.json.JSONArray;
- import net.sf.json.JSONObject;
-+
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
-@@ -81,13 +82,18 @@ import javax.servlet.ServletException;
- import javax.xml.parsers.ParserConfigurationException;
- import javax.xml.parsers.SAXParserFactory;
- import java.io.Closeable;
-+
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.lang.ref.WeakReference;
- import java.lang.reflect.Method;
-+import java.net.URISyntaxException;
- import java.net.URL;
- import java.net.URLClassLoader;
-+import java.nio.file.Files;
-+import java.nio.file.Path;
-+import java.nio.file.Paths;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
-@@ -108,6 +114,7 @@ import java.util.jar.JarFile;
- import java.util.jar.Manifest;
- import java.util.logging.Level;
- import java.util.logging.Logger;
-+
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
-@@ -116,6 +123,7 @@ import static hudson.init.InitMilestone.*;
- import hudson.model.DownloadService;
- import hudson.util.FormValidation;
- import static java.util.logging.Level.WARNING;
-+
- import org.kohsuke.accmod.Restricted;
- import org.kohsuke.accmod.restrictions.NoExternalUse;
-
-@@ -143,6 +151,9 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
- */
- public final File rootDir;
-
-+ // FIXME: pass this location to Jenkins via system property
-+ private final File rpmRootDir = new File("/usr/share/jenkins/plugins/");
-+
- /**
- * @deprecated as of 1.355
- * {@link PluginManager} can now live longer than {@link jenkins.model.Jenkins} instance, so
-@@ -211,6 +222,47 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
- return new Api(this);
- }
-
-+ private void symlinkRpmPlugins() {
-+ if (!rpmRootDir.exists()) {
-+ return;
-+ }
-+
-+ File[] rpmPluginDirs = rpmRootDir.listFiles();
-+ File[] currentPlugins = rootDir.listFiles();
-+ boolean isAlreadyInstalled = false;
-+
-+ for (File rpmPlugin : rpmPluginDirs) {
-+ if (rpmPlugin.isDirectory()) {
-+ for (File plugin : currentPlugins) {
-+ // remove broken symlinks from $JENKINS_HOME/plugins/
-+ if (Files.isSymbolicLink(plugin.toPath())) {
-+ if (Files.notExists(plugin.toPath())) {
-+ LOGGER.info("Removing broken symbolic link from plugins directory: " + plugin);
-+ plugin.delete();
-+ }
-+ }
-+ if (rpmPlugin.getName().equals(plugin.getName()) || plugin.getName().equals(rpmPlugin.getName() + ".jpi")) {
-+ LOGGER.info(rpmPlugin.getName() + " already exists in plugin directory, skipping");
-+ isAlreadyInstalled = true;
-+ break;
-+ }
-+ }
-+ if (!isAlreadyInstalled) {
-+ Path link = Paths.get(rootDir.getPath(), rpmPlugin.getName() + ".jpi");
-+ Path target = Paths.get(rpmPlugin.getPath());
-+ try {
-+ Files.createSymbolicLink(link, target);
-+ } catch (IOException e) {
-+ LOGGER.info(e.toString());
-+ }
-+ }
-+ isAlreadyInstalled = false;
-+ } else {
-+ LOGGER.info(rpmRootDir + rpmPlugin.getName() + " is not a directory, ignoring");
-+ }
-+ }
-+ }
-+
- /**
- * Called immediately after the construction.
- * This is a separate method so that code executed from here will see a valid value in
-@@ -218,6 +270,9 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
- */
- public TaskBuilder initTasks(final InitStrategy initStrategy) {
- TaskBuilder builder;
-+
-+ symlinkRpmPlugins();
-+
- if (!pluginListed) {
- builder = new TaskGraphBuilder() {
- List<File> archives;
-@@ -537,8 +592,24 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
- // - no file exists today
- // - bundled version and current version differs (by timestamp), and the file isn't pinned.
- if (!file.exists() || (file.lastModified() != lastModified && !pinFile.exists())) {
-- FileUtils.copyURLToFile(src, file);
-- file.setLastModified(src.openConnection().getLastModified());
-+ Path sourcePath = null;
-+ try {
-+ sourcePath = Paths.get(src.toURI());
-+ } catch (URISyntaxException e) {
-+ throw new IOException(e);
-+ }
-+ Path linkPath = Paths.get(rootDir.getAbsolutePath(), fileName);
-+ if (Files.isDirectory(sourcePath)) {
-+ if (Files.isDirectory(linkPath)) {
-+ FileUtils.deleteDirectory(linkPath.toFile());
-+ } else if (Files.exists(linkPath)) {
-+ Files.delete(linkPath);
-+ }
-+ Files.createSymbolicLink(linkPath, sourcePath);
-+ } else {
-+ FileUtils.copyURLToFile(src, file);
-+ file.setLastModified(src.openConnection().getLastModified());
-+ }
- // lastModified is set for two reasons:
- // - to avoid unpacking as much as possible, but still do it on both upgrade and downgrade
- // - to make sure the value is not changed after each restart, so we can avoid
-diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java
-index aa683e6..2de708a 100644
---- a/core/src/main/java/hudson/PluginWrapper.java
-+++ b/core/src/main/java/hudson/PluginWrapper.java
-@@ -34,15 +34,22 @@ import hudson.model.UpdateSite;
- import hudson.util.VersionNumber;
-
- import java.io.File;
-+import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
-+import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.Closeable;
- import java.net.URL;
-+import java.nio.file.Files;
-+import java.nio.file.Path;
-+import java.nio.file.Paths;
- import java.util.ArrayList;
- import java.util.List;
-+import java.util.jar.Attributes;
- import java.util.jar.Manifest;
- import java.util.logging.Logger;
-+
- import static java.util.logging.Level.WARNING;
- import static org.apache.commons.io.FilenameUtils.getBaseName;
- import org.apache.commons.lang.StringUtils;
-@@ -56,6 +63,7 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
- import java.util.Enumeration;
- import java.util.jar.JarFile;
- import java.util.logging.Level;
-+
- import javax.annotation.CheckForNull;
-
- /**
-@@ -431,6 +439,13 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
- return isBundled;
- }
-
-+ public boolean isFromRPM() {
-+ if (Files.isSymbolicLink(archive.toPath())) {
-+ return true;
-+ }
-+ return false;
-+ }
-+
- /**
- * If true, the plugin is going to be activated next time
- * Jenkins runs.
-@@ -565,13 +580,27 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
- @Exported
- public String getBackupVersion() {
- File backup = getBackupFile();
-+ Path backupPath = Paths.get(backup.toURI());
- if (backup.exists()) {
- try {
-- JarFile backupPlugin = new JarFile(backup);
-- try {
-- return backupPlugin.getManifest().getMainAttributes().getValue("Plugin-Version");
-- } finally {
-- backupPlugin.close();
-+ if (!Files.isDirectory(backupPath)) {
-+
-+ JarFile backupPlugin = new JarFile(backup);
-+ try {
-+ return backupPlugin.getManifest().getMainAttributes().getValue("Plugin-Version");
-+ } finally {
-+ backupPlugin.close();
-+ }
-+
-+ } else {
-+ InputStream is = new FileInputStream(new File(backup, "META-INF/MANIFEST.MF"));
-+ Manifest manifest = new Manifest(is);
-+ Attributes attributes = manifest.getMainAttributes();
-+ try {
-+ return attributes.getValue("Plugin-Version");
-+ } finally {
-+ is.close();
-+ }
- }
- } catch (IOException e) {
- LOGGER.log(WARNING, "Failed to get backup version from " + backup, e);
-diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java
-index f5aecb5..12a2bb1 100644
---- a/core/src/main/java/hudson/model/UpdateCenter.java
-+++ b/core/src/main/java/hudson/model/UpdateCenter.java
-@@ -52,8 +52,10 @@ import hudson.util.XStream2;
- import jenkins.RestartRequiredException;
- import jenkins.model.Jenkins;
- import jenkins.util.io.OnMaster;
-+
- import org.acegisecurity.Authentication;
- import org.acegisecurity.context.SecurityContext;
-+import org.apache.commons.io.FileUtils;
- import org.apache.commons.io.input.CountingInputStream;
- import org.apache.commons.io.output.NullOutputStream;
- import org.jvnet.localizer.Localizable;
-@@ -63,6 +65,7 @@ import org.kohsuke.stapler.StaplerResponse;
-
- import javax.net.ssl.SSLHandshakeException;
- import javax.servlet.ServletException;
-+
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
-@@ -89,7 +92,9 @@ import java.util.jar.Attributes;
- import java.util.jar.JarFile;
- import java.util.logging.Level;
- import java.util.logging.Logger;
-+
- import javax.annotation.CheckForNull;
-+
- import org.acegisecurity.context.SecurityContextHolder;
- import org.kohsuke.accmod.Restricted;
- import org.kohsuke.accmod.restrictions.NoExternalUse;
-@@ -1427,6 +1432,9 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
- if(!backup.renameTo(dst)) {
- throw new IOException("Failed to rename "+backup+" to "+dst);
- }
-+ // remove old unpacked version
-+ File baseDir = pm.rootDir;
-+ FileUtils.deleteQuietly(new File(baseDir, plugin.name));
- }
-
- protected void onSuccess() {
-diff --git a/core/src/main/resources/hudson/PluginManager/installed.jelly b/core/src/main/resources/hudson/PluginManager/installed.jelly
-index 2d439b3..ef14603 100644
---- a/core/src/main/resources/hudson/PluginManager/installed.jelly
-+++ b/core/src/main/resources/hudson/PluginManager/installed.jelly
-@@ -112,9 +112,11 @@ THE SOFTWARE.
- <p>${%Uninstallation pending}</p>
- </j:when>
- <j:when test="${!p.isBundled()}">
-- <form method="post" action="plugin/${p.shortName}/uninstall">
-- <input type="submit" value="${%Uninstall}"/>
-- </form>
-+ <j:when test="${!p.isFromRPM()}">
-+ <form method="post" action="plugin/${p.shortName}/uninstall">
-+ <input type="submit" value="${%Uninstall}"/>
-+ </form>
-+ </j:when>
- </j:when>
- </j:choose>
- </td>
diff --git a/hpi-unpack-temp-hack.patch b/hpi-unpack-temp-hack.patch
new file mode 100644
index 0000000..3dd009e
--- /dev/null
+++ b/hpi-unpack-temp-hack.patch
@@ -0,0 +1,26 @@
+diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java
+index 727bdd7..98b74d9 100644
+--- a/core/src/main/java/hudson/ClassicPluginStrategy.java
++++ b/core/src/main/java/hudson/ClassicPluginStrategy.java
+@@ -590,15 +590,12 @@ public class ClassicPluginStrategy implements PluginStrategy {
+ }
+
+ private static void unzipExceptClasses(File archive, File destDir, Project prj) {
+- Expand e = new Expand();
+- e.setProject(prj);
+- e.setTaskType("unzip");
+- e.setSrc(archive);
+- e.setDest(destDir);
+- PatternSet p = new PatternSet();
+- p.setExcludes("WEB-INF/classes/");
+- e.addPatternset(p);
+- e.execute();
++ // TODO: quick hack, this needs to be solved properly
++ try {
++ Runtime.getRuntime().exec("/usr/bin/unzip -d " + destDir.getAbsolutePath() + " " + archive.getAbsolutePath() + " -x 'WEB-INF/classes/*'");
++ } catch (IOException e) {
++ LOGGER.log(Level.SEVERE, "Failed to unzip plugin " + archive, e);
++ }
+ }
+
+ /**
diff --git a/jenkins.spec b/jenkins.spec
index 8467a20..7801450 100644
--- a/jenkins.spec
+++ b/jenkins.spec
@@ -11,7 +11,7 @@
Name: jenkins
Version: 1.606
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: An extendable open source continuous integration server
# The project's primary license is MIT
@@ -44,8 +44,8 @@ Patch7: use-guava-13.0.patch
Patch9: remove-windows-support-from-processtree.patch
Patch10: remove-dotnet-support.patch
Patch11: remove-windows-installer-support.patch
-Patch13: add-support-for-plugins-from-RPMs.patch
Patch14: do-not-check-for-core-updates.patch
+Patch15: hpi-unpack-temp-hack.patch
BuildArch: noarch
@@ -352,8 +352,8 @@ This package contains API documentation for %{name}.
%patch9 -p1
%patch10 -p1
%patch11 -p1
-%patch13 -p1 -F2
%patch14 -p1
+%patch15 -p1
# Remove bundled JARs and classes
find . -name "*.jar" -delete
@@ -709,6 +709,9 @@ exit 0
%doc LICENSE.txt
%changelog
+* Mon Apr 13 2015 Michal Srb <msrb at redhat.com> - 1.606-2
+- Migrate to plugins containing symlinks
+
* Thu Mar 26 2015 Michal Srb <msrb at redhat.com> - 1.606-1
- Update to upstream release 1.606
- Resolves: CVE-2015-1806
--
cgit v0.10.2
http://pkgs.fedoraproject.org/cgit/jenkins.git/commit/?h=master&id=6136db2d08f638c0093bb77ea101001213ee9c98
More information about the scm-commits
mailing list