diff --git a/src/main/java/org/elasticsearch/plugins/PluginManager.java b/src/main/java/org/elasticsearch/plugins/PluginManager.java index 0a7662f14ed..44e6f671205 100644 --- a/src/main/java/org/elasticsearch/plugins/PluginManager.java +++ b/src/main/java/org/elasticsearch/plugins/PluginManager.java @@ -76,6 +76,13 @@ public class PluginManager { "plugin.bat", "service.bat").build(); + // Valid directory names for plugin ZIP files when it has only one single dir + private static final ImmutableSet VALID_TOP_LEVEL_PLUGIN_DIRS = ImmutableSet.builder() + .add("_site", + "bin", + "config", + "_dict").build(); + private final Environment environment; private String url; @@ -218,6 +225,8 @@ public class PluginManager { throw new IllegalArgumentException("Plugin installation assumed to be site plugin, but contains source code, aborting installation."); } + // It could potentially be a non explicit _site plugin + boolean potentialSitePlugin = true; File binFile = new File(extractLocation, "bin"); if (binFile.exists() && binFile.isDirectory()) { File toLocation = pluginHandle.binDir(environment); @@ -227,6 +236,7 @@ public class PluginManager { throw new IOException("Could not move ["+ binFile.getAbsolutePath() + "] to [" + toLocation.getAbsolutePath() + "]"); } debug("Installed " + name + " into " + toLocation.getAbsolutePath()); + potentialSitePlugin = false; } File configFile = new File(extractLocation, "config"); @@ -238,12 +248,13 @@ public class PluginManager { throw new IOException("Could not move ["+ configFile.getAbsolutePath() + "] to [" + configFile.getAbsolutePath() + "]"); } debug("Installed " + name + " into " + toLocation.getAbsolutePath()); + potentialSitePlugin = false; } // try and identify the plugin type, see if it has no .class or .jar files in it // so its probably a _site, and it it does not have a _site in it, move everything to _site if (!new File(extractLocation, "_site").exists()) { - if (!FileSystemUtils.hasExtensions(extractLocation, ".class", ".jar")) { + if (potentialSitePlugin && !FileSystemUtils.hasExtensions(extractLocation, ".class", ".jar")) { log("Identified as a _site plugin, moving to _site structure ..."); File site = new File(extractLocation, "_site"); File tmpLocation = new File(environment.pluginsFile(), extractLocation.getName() + ".tmp"); @@ -354,7 +365,12 @@ public class PluginManager { return false; } } - return topLevelDirNames.size() == 1 && !"_site".equals(topLevelDirNames.iterator().next()); + + if (topLevelDirNames.size() == 1) { + return !VALID_TOP_LEVEL_PLUGIN_DIRS.contains(topLevelDirNames.iterator().next()); + } + + return false; } private static final int EXIT_CODE_OK = 0; diff --git a/src/test/java/org/elasticsearch/plugin/PluginManagerTests.java b/src/test/java/org/elasticsearch/plugin/PluginManagerTests.java index e392ef712af..a1d31208efa 100644 --- a/src/test/java/org/elasticsearch/plugin/PluginManagerTests.java +++ b/src/test/java/org/elasticsearch/plugin/PluginManagerTests.java @@ -125,6 +125,30 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest { } } + // For #7152 + @Test + public void testLocalPluginInstallWithBinOnly_7152() throws Exception { + String pluginName = "plugin-test"; + Tuple initialSettings = InternalSettingsPreparer.prepareSettings( + ImmutableSettings.settingsBuilder().build(), false); + Environment env = initialSettings.v2(); + File binDir = new File(env.homeFile(), "bin"); + if (!binDir.exists() && !FileSystemUtils.mkdirs(binDir)) { + throw new IOException("Could not create bin directory [" + binDir.getAbsolutePath() + "]"); + } + File pluginBinDir = new File(binDir, pluginName); + try { + PluginManager pluginManager = pluginManager(getPluginUrlForResource("plugin_with_bin_only.zip"), initialSettings); + pluginManager.downloadAndExtract(pluginName); + File[] plugins = pluginManager.getListInstalledPlugins(); + assertThat(plugins.length, is(1)); + assertTrue(pluginBinDir.exists()); + } finally { + // we need to clean up the copied dirs + FileSystemUtils.deleteRecursively(pluginBinDir); + } + } + @Test public void testLocalPluginInstallSiteFolder() throws Exception { //When we have only a folder in top-level (no files either) but it's called _site, we make it work