Skip to content

Commit 0cc1ffd

Browse files
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
1 parent 8425257 commit 0cc1ffd

File tree

3 files changed

+20
-10
lines changed

3 files changed

+20
-10
lines changed

distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import java.nio.file.FileVisitResult;
5454
import java.nio.file.Files;
5555
import java.nio.file.Path;
56+
import java.nio.file.Paths;
5657
import java.nio.file.SimpleFileVisitor;
5758
import java.nio.file.StandardCopyOption;
5859
import java.nio.file.attribute.BasicFileAttributes;
@@ -218,25 +219,25 @@ void execute(Terminal terminal, String pluginId, boolean isBatch, Environment en
218219
throw new UserException(ExitCodes.USAGE, "plugin id is required");
219220
}
220221

221-
Path pluginZip = download(terminal, pluginId, env.tmpFile());
222+
Path pluginZip = download(terminal, pluginId, env.tmpFile(), env.pluginsFile());
222223
Path extractedZip = unzip(pluginZip, env.pluginsFile());
223224
install(terminal, isBatch, extractedZip, env);
224225
}
225226

226227
/** Downloads the plugin and returns the file it was downloaded to. */
227-
private Path download(Terminal terminal, String pluginId, Path tmpDir) throws Exception {
228+
private Path download(Terminal terminal, String pluginId, Path tmpDir, Path pluginsDir) throws Exception {
228229
if (OFFICIAL_PLUGINS.contains(pluginId)) {
229230
final String url = getElasticUrl(terminal, getStagingHash(), Version.CURRENT, pluginId, Platforms.PLATFORM_NAME);
230231
terminal.println("-> Downloading " + pluginId + " from elastic");
231-
return downloadZipAndChecksum(terminal, url, tmpDir, false);
232+
return downloadZipAndChecksum(terminal, url, tmpDir, pluginsDir, false);
232233
}
233234

234235
// now try as maven coordinates, a valid URL would only have a colon and slash
235236
String[] coordinates = pluginId.split(":");
236237
if (coordinates.length == 3 && pluginId.contains("/") == false && pluginId.startsWith("file:") == false) {
237238
String mavenUrl = getMavenUrl(terminal, coordinates, Platforms.PLATFORM_NAME);
238239
terminal.println("-> Downloading " + pluginId + " from maven central");
239-
return downloadZipAndChecksum(terminal, mavenUrl, tmpDir, true);
240+
return downloadZipAndChecksum(terminal, mavenUrl, tmpDir, pluginsDir, true);
240241
}
241242

242243
// fall back to plain old URL
@@ -250,7 +251,7 @@ private Path download(Terminal terminal, String pluginId, Path tmpDir) throws Ex
250251
throw new UserException(ExitCodes.USAGE, msg);
251252
}
252253
terminal.println("-> Downloading " + URLDecoder.decode(pluginId, "UTF-8"));
253-
return downloadZip(terminal, pluginId, tmpDir);
254+
return downloadZip(terminal, pluginId, tmpDir, pluginsDir);
254255
}
255256

256257
// pkg private so tests can override
@@ -324,9 +325,17 @@ private List<String> checkMisspelledPlugin(String pluginId) {
324325
/** Downloads a zip from the url, into a temp file under the given temp dir. */
325326
// pkg private for tests
326327
@SuppressForbidden(reason = "We use getInputStream to download plugins")
327-
Path downloadZip(Terminal terminal, String urlString, Path tmpDir) throws IOException {
328+
Path downloadZip(Terminal terminal, String urlString, Path tmpDir, Path pluginsDir) throws IOException {
328329
terminal.println(VERBOSE, "Retrieving zip from " + urlString);
329330
URL url = new URL(urlString);
331+
if (url.getProtocol().equals("file")) {
332+
Path pluginsFile = Paths.get(url.getFile());
333+
if (pluginsFile.startsWith(pluginsDir)) {
334+
throw new IllegalStateException("Installation failed! " +
335+
"Make sure the plugins directory [" + pluginsDir + "] can not contain the plugin distribution [" +
336+
pluginsFile + "]; move the distribution to an alternate location!");
337+
}
338+
}
330339
Path zip = Files.createTempFile(tmpDir, null, ".zip");
331340
URLConnection urlConnection = url.openConnection();
332341
urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer");
@@ -375,8 +384,9 @@ public void onProgress(int percent) {
375384
/** Downloads a zip from the url, as well as a SHA512 (or SHA1) checksum, and checks the checksum. */
376385
// pkg private for tests
377386
@SuppressForbidden(reason = "We use openStream to download plugins")
378-
private Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir, boolean allowSha1) throws Exception {
379-
Path zip = downloadZip(terminal, urlString, tmpDir);
387+
private Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir, Path pluginsDir, boolean allowSha1)
388+
throws Exception {
389+
Path zip = downloadZip(terminal, urlString, tmpDir, pluginsDir);
380390
pathsToDeleteOnShutdown.add(zip);
381391
String checksumUrlString = urlString + ".sha512";
382392
URL checksumUrl = openUrl(checksumUrlString);

distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ void assertInstallPluginFromUrl(String pluginId, String name, String url, String
981981
Path pluginZip = createPlugin(name, pluginDir);
982982
InstallPluginCommand command = new InstallPluginCommand() {
983983
@Override
984-
Path downloadZip(Terminal terminal, String urlString, Path tmpDir) throws IOException {
984+
Path downloadZip(Terminal terminal, String urlString, Path tmpDir, Path pluginsDir) throws IOException {
985985
assertEquals(url, urlString);
986986
Path downloadedPath = tmpDir.resolve("downloaded.zip");
987987
Files.copy(pluginZip, downloadedPath);

server/src/main/java/org/elasticsearch/plugins/PluginsService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ public String name() {
328328
public Collection<Bundle> bundles() {
329329
return bundles;
330330
}
331-
331+
332332
}
333333

334334
/**

0 commit comments

Comments
 (0)