Plugins: Remove intermediate "elasticsearch" directory within plugin zips (#28589)
This commit removes the extra layer of all plugin files existing under "elasticsearch" within plugin zips. This simplifies building plugin zips and removes the need for special logic of modules vs plugins.
This commit is contained in:
parent
4e0c1463d5
commit
65f1dd424e
|
@ -58,12 +58,10 @@ class MetaPluginBuildPlugin implements Plugin<Project> {
|
||||||
|
|
||||||
// create the actual bundle task, which zips up all the files for the plugin
|
// create the actual bundle task, which zips up all the files for the plugin
|
||||||
Zip bundle = project.tasks.create(name: 'bundlePlugin', type: Zip, dependsOn: [buildProperties]) {
|
Zip bundle = project.tasks.create(name: 'bundlePlugin', type: Zip, dependsOn: [buildProperties]) {
|
||||||
into('elasticsearch') {
|
|
||||||
from(buildProperties.descriptorOutput.parentFile) {
|
from(buildProperties.descriptorOutput.parentFile) {
|
||||||
// plugin properties file
|
// plugin properties file
|
||||||
include(buildProperties.descriptorOutput.name)
|
include(buildProperties.descriptorOutput.name)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// due to how the renames work for each bundled plugin, we must exclude empty dirs or every subdir
|
// due to how the renames work for each bundled plugin, we must exclude empty dirs or every subdir
|
||||||
// within bundled plugin zips will show up at the root as an empty dir
|
// within bundled plugin zips will show up at the root as an empty dir
|
||||||
includeEmptyDirs = false
|
includeEmptyDirs = false
|
||||||
|
@ -85,10 +83,8 @@ class MetaPluginBuildPlugin implements Plugin<Project> {
|
||||||
dependsOn bundledPluginProject.bundlePlugin
|
dependsOn bundledPluginProject.bundlePlugin
|
||||||
from(project.zipTree(bundledPluginProject.bundlePlugin.outputs.files.singleFile)) {
|
from(project.zipTree(bundledPluginProject.bundlePlugin.outputs.files.singleFile)) {
|
||||||
eachFile { FileCopyDetails details ->
|
eachFile { FileCopyDetails details ->
|
||||||
// paths in the individual plugins begin with elasticsearch, and we want to add in the
|
// we want each path to have the plugin name interjected
|
||||||
// bundled plugin name between that and each filename
|
details.relativePath = new RelativePath(true, bundledPluginProjectName, details.relativePath.toString())
|
||||||
details.relativePath = new RelativePath(true, 'elasticsearch', bundledPluginProjectName,
|
|
||||||
details.relativePath.toString().replace('elasticsearch/', ''))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,9 +140,6 @@ public class PluginBuildPlugin extends BuildPlugin {
|
||||||
include 'config/**'
|
include 'config/**'
|
||||||
include 'bin/**'
|
include 'bin/**'
|
||||||
}
|
}
|
||||||
if (project.path.startsWith(':modules:') == false) {
|
|
||||||
into('elasticsearch')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
project.assemble.dependsOn(bundle)
|
project.assemble.dependsOn(bundle)
|
||||||
|
|
||||||
|
|
|
@ -462,17 +462,15 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
||||||
final Path target = stagingDirectory(pluginsDir);
|
final Path target = stagingDirectory(pluginsDir);
|
||||||
pathsToDeleteOnShutdown.add(target);
|
pathsToDeleteOnShutdown.add(target);
|
||||||
|
|
||||||
boolean hasEsDir = false;
|
|
||||||
try (ZipInputStream zipInput = new ZipInputStream(Files.newInputStream(zip))) {
|
try (ZipInputStream zipInput = new ZipInputStream(Files.newInputStream(zip))) {
|
||||||
ZipEntry entry;
|
ZipEntry entry;
|
||||||
byte[] buffer = new byte[8192];
|
byte[] buffer = new byte[8192];
|
||||||
while ((entry = zipInput.getNextEntry()) != null) {
|
while ((entry = zipInput.getNextEntry()) != null) {
|
||||||
if (entry.getName().startsWith("elasticsearch/") == false) {
|
if (entry.getName().startsWith("elasticsearch/")) {
|
||||||
// only extract the elasticsearch directory
|
throw new UserException(PLUGIN_MALFORMED, "This plugin was built with an older plugin structure." +
|
||||||
continue;
|
" Contact the plugin author to remove the intermediate \"elasticsearch\" directory within the plugin zip.");
|
||||||
}
|
}
|
||||||
hasEsDir = true;
|
Path targetFile = target.resolve(entry.getName());
|
||||||
Path targetFile = target.resolve(entry.getName().substring("elasticsearch/".length()));
|
|
||||||
|
|
||||||
// Using the entry name as a path can result in an entry outside of the plugin dir,
|
// Using the entry name as a path can result in an entry outside of the plugin dir,
|
||||||
// either if the name starts with the root of the filesystem, or it is a relative
|
// either if the name starts with the root of the filesystem, or it is a relative
|
||||||
|
@ -499,13 +497,11 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
||||||
}
|
}
|
||||||
zipInput.closeEntry();
|
zipInput.closeEntry();
|
||||||
}
|
}
|
||||||
|
} catch (UserException e) {
|
||||||
|
IOUtils.rm(target);
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
Files.delete(zip);
|
Files.delete(zip);
|
||||||
if (hasEsDir == false) {
|
|
||||||
IOUtils.rm(target);
|
|
||||||
throw new UserException(PLUGIN_MALFORMED,
|
|
||||||
"`elasticsearch` directory is missing in the plugin zip");
|
|
||||||
}
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -259,12 +259,12 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
|
|
||||||
static Path createPlugin(String name, Path structure, String... additionalProps) throws IOException {
|
static Path createPlugin(String name, Path structure, String... additionalProps) throws IOException {
|
||||||
writePlugin(name, structure, additionalProps);
|
writePlugin(name, structure, additionalProps);
|
||||||
return writeZip(structure, "elasticsearch");
|
return writeZip(structure, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Path createMetaPlugin(String name, Path structure) throws IOException {
|
static Path createMetaPlugin(String name, Path structure) throws IOException {
|
||||||
writeMetaPlugin(name, structure);
|
writeMetaPlugin(name, structure);
|
||||||
return writeZip(structure, "elasticsearch");
|
return writeZip(structure, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installPlugin(String pluginUrl, Path home) throws Exception {
|
void installPlugin(String pluginUrl, Path home) throws Exception {
|
||||||
|
@ -811,7 +811,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
Path pluginDir = metaDir.resolve("fake");
|
Path pluginDir = metaDir.resolve("fake");
|
||||||
Files.createDirectory(pluginDir);
|
Files.createDirectory(pluginDir);
|
||||||
Files.createFile(pluginDir.resolve("fake.yml"));
|
Files.createFile(pluginDir.resolve("fake.yml"));
|
||||||
String pluginZip = writeZip(pluginDir, "elasticsearch").toUri().toURL().toString();
|
String pluginZip = writeZip(pluginDir, null).toUri().toURL().toString();
|
||||||
NoSuchFileException e = expectThrows(NoSuchFileException.class, () -> installPlugin(pluginZip, env.v1()));
|
NoSuchFileException e = expectThrows(NoSuchFileException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("plugin-descriptor.properties"));
|
assertTrue(e.getMessage(), e.getMessage().contains("plugin-descriptor.properties"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
|
@ -822,23 +822,23 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMissingDirectory() throws Exception {
|
public void testContainsIntermediateDirectory() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
Files.createFile(pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES));
|
Files.createFile(pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES));
|
||||||
String pluginZip = writeZip(pluginDir, null).toUri().toURL().toString();
|
String pluginZip = writeZip(pluginDir, "elasticsearch").toUri().toURL().toString();
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("`elasticsearch` directory is missing in the plugin zip"));
|
assertThat(e.getMessage(), containsString("This plugin was built with an older plugin structure"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMissingDirectoryMeta() throws Exception {
|
public void testContainsIntermediateDirectoryMeta() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
Files.createFile(pluginDir.resolve(MetaPluginInfo.ES_META_PLUGIN_PROPERTIES));
|
Files.createFile(pluginDir.resolve(MetaPluginInfo.ES_META_PLUGIN_PROPERTIES));
|
||||||
String pluginZip = writeZip(pluginDir, null).toUri().toURL().toString();
|
String pluginZip = writeZip(pluginDir, "elasticsearch").toUri().toURL().toString();
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("`elasticsearch` directory is missing in the plugin zip"));
|
assertThat(e.getMessage(), containsString("This plugin was built with an older plugin structure"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,11 +846,12 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path zip = createTempDir().resolve("broken.zip");
|
Path zip = createTempDir().resolve("broken.zip");
|
||||||
try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(zip))) {
|
try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(zip))) {
|
||||||
stream.putNextEntry(new ZipEntry("elasticsearch/../blah"));
|
stream.putNextEntry(new ZipEntry("../blah"));
|
||||||
}
|
}
|
||||||
String pluginZip = zip.toUri().toURL().toString();
|
String pluginZip = zip.toUri().toURL().toString();
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("resolving outside of plugin directory"));
|
assertTrue(e.getMessage(), e.getMessage().contains("resolving outside of plugin directory"));
|
||||||
|
assertInstallCleaned(env.v2());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOfficialPluginsHelpSorted() throws Exception {
|
public void testOfficialPluginsHelpSorted() throws Exception {
|
||||||
|
|
Loading…
Reference in New Issue