Improve error message for installing plugin (#28298)

Provide more actionable error message when installing an offline plugin
in the plugins directory, and the `plugins` directory for the node
contains plugin distribution.

Closes #27401
This commit is contained in:
Mayya Sharipova 2018-03-14 16:19:04 -07:00 committed by GitHub
parent 8425257593
commit 0cc1ffdf20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 10 deletions

View File

@ -53,6 +53,7 @@ import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor; import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
@ -218,17 +219,17 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
throw new UserException(ExitCodes.USAGE, "plugin id is required"); throw new UserException(ExitCodes.USAGE, "plugin id is required");
} }
Path pluginZip = download(terminal, pluginId, env.tmpFile()); Path pluginZip = download(terminal, pluginId, env.tmpFile(), env.pluginsFile());
Path extractedZip = unzip(pluginZip, env.pluginsFile()); Path extractedZip = unzip(pluginZip, env.pluginsFile());
install(terminal, isBatch, extractedZip, env); install(terminal, isBatch, extractedZip, env);
} }
/** Downloads the plugin and returns the file it was downloaded to. */ /** Downloads the plugin and returns the file it was downloaded to. */
private Path download(Terminal terminal, String pluginId, Path tmpDir) throws Exception { private Path download(Terminal terminal, String pluginId, Path tmpDir, Path pluginsDir) throws Exception {
if (OFFICIAL_PLUGINS.contains(pluginId)) { if (OFFICIAL_PLUGINS.contains(pluginId)) {
final String url = getElasticUrl(terminal, getStagingHash(), Version.CURRENT, pluginId, Platforms.PLATFORM_NAME); final String url = getElasticUrl(terminal, getStagingHash(), Version.CURRENT, pluginId, Platforms.PLATFORM_NAME);
terminal.println("-> Downloading " + pluginId + " from elastic"); terminal.println("-> Downloading " + pluginId + " from elastic");
return downloadZipAndChecksum(terminal, url, tmpDir, false); return downloadZipAndChecksum(terminal, url, tmpDir, pluginsDir, false);
} }
// now try as maven coordinates, a valid URL would only have a colon and slash // now try as maven coordinates, a valid URL would only have a colon and slash
@ -236,7 +237,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
if (coordinates.length == 3 && pluginId.contains("/") == false && pluginId.startsWith("file:") == false) { if (coordinates.length == 3 && pluginId.contains("/") == false && pluginId.startsWith("file:") == false) {
String mavenUrl = getMavenUrl(terminal, coordinates, Platforms.PLATFORM_NAME); String mavenUrl = getMavenUrl(terminal, coordinates, Platforms.PLATFORM_NAME);
terminal.println("-> Downloading " + pluginId + " from maven central"); terminal.println("-> Downloading " + pluginId + " from maven central");
return downloadZipAndChecksum(terminal, mavenUrl, tmpDir, true); return downloadZipAndChecksum(terminal, mavenUrl, tmpDir, pluginsDir, true);
} }
// fall back to plain old URL // fall back to plain old URL
@ -250,7 +251,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
throw new UserException(ExitCodes.USAGE, msg); throw new UserException(ExitCodes.USAGE, msg);
} }
terminal.println("-> Downloading " + URLDecoder.decode(pluginId, "UTF-8")); terminal.println("-> Downloading " + URLDecoder.decode(pluginId, "UTF-8"));
return downloadZip(terminal, pluginId, tmpDir); return downloadZip(terminal, pluginId, tmpDir, pluginsDir);
} }
// pkg private so tests can override // pkg private so tests can override
@ -324,9 +325,17 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
/** Downloads a zip from the url, into a temp file under the given temp dir. */ /** Downloads a zip from the url, into a temp file under the given temp dir. */
// pkg private for tests // pkg private for tests
@SuppressForbidden(reason = "We use getInputStream to download plugins") @SuppressForbidden(reason = "We use getInputStream to download plugins")
Path downloadZip(Terminal terminal, String urlString, Path tmpDir) throws IOException { Path downloadZip(Terminal terminal, String urlString, Path tmpDir, Path pluginsDir) throws IOException {
terminal.println(VERBOSE, "Retrieving zip from " + urlString); terminal.println(VERBOSE, "Retrieving zip from " + urlString);
URL url = new URL(urlString); URL url = new URL(urlString);
if (url.getProtocol().equals("file")) {
Path pluginsFile = Paths.get(url.getFile());
if (pluginsFile.startsWith(pluginsDir)) {
throw new IllegalStateException("Installation failed! " +
"Make sure the plugins directory [" + pluginsDir + "] can not contain the plugin distribution [" +
pluginsFile + "]; move the distribution to an alternate location!");
}
}
Path zip = Files.createTempFile(tmpDir, null, ".zip"); Path zip = Files.createTempFile(tmpDir, null, ".zip");
URLConnection urlConnection = url.openConnection(); URLConnection urlConnection = url.openConnection();
urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer"); urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer");
@ -375,8 +384,9 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
/** Downloads a zip from the url, as well as a SHA512 (or SHA1) checksum, and checks the checksum. */ /** Downloads a zip from the url, as well as a SHA512 (or SHA1) checksum, and checks the checksum. */
// pkg private for tests // pkg private for tests
@SuppressForbidden(reason = "We use openStream to download plugins") @SuppressForbidden(reason = "We use openStream to download plugins")
private Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir, boolean allowSha1) throws Exception { private Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir, Path pluginsDir, boolean allowSha1)
Path zip = downloadZip(terminal, urlString, tmpDir); throws Exception {
Path zip = downloadZip(terminal, urlString, tmpDir, pluginsDir);
pathsToDeleteOnShutdown.add(zip); pathsToDeleteOnShutdown.add(zip);
String checksumUrlString = urlString + ".sha512"; String checksumUrlString = urlString + ".sha512";
URL checksumUrl = openUrl(checksumUrlString); URL checksumUrl = openUrl(checksumUrlString);

View File

@ -981,7 +981,7 @@ public class InstallPluginCommandTests extends ESTestCase {
Path pluginZip = createPlugin(name, pluginDir); Path pluginZip = createPlugin(name, pluginDir);
InstallPluginCommand command = new InstallPluginCommand() { InstallPluginCommand command = new InstallPluginCommand() {
@Override @Override
Path downloadZip(Terminal terminal, String urlString, Path tmpDir) throws IOException { Path downloadZip(Terminal terminal, String urlString, Path tmpDir, Path pluginsDir) throws IOException {
assertEquals(url, urlString); assertEquals(url, urlString);
Path downloadedPath = tmpDir.resolve("downloaded.zip"); Path downloadedPath = tmpDir.resolve("downloaded.zip");
Files.copy(pluginZip, downloadedPath); Files.copy(pluginZip, downloadedPath);