mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-20 03:45:02 +00:00
Plugins: Add support for platform specific plugins (#24265)
This commit adds support for plugins having a platform specific variant. It also adds unit tests for all official and maven urls.
This commit is contained in:
parent
b4cff19842
commit
cdcc75dd2a
@ -30,8 +30,7 @@ import java.util.Locale;
|
|||||||
public class Platforms {
|
public class Platforms {
|
||||||
|
|
||||||
private static final String PROGRAM_NAME = Constants.WINDOWS ? "controller.exe" : "controller";
|
private static final String PROGRAM_NAME = Constants.WINDOWS ? "controller.exe" : "controller";
|
||||||
private static final String PLATFORM_NAME =
|
public static final String PLATFORM_NAME = Platforms.platformName(Constants.OS_NAME, Constants.OS_ARCH);
|
||||||
Platforms.platformName(Constants.OS_NAME, Constants.OS_ARCH);
|
|
||||||
|
|
||||||
private Platforms() {}
|
private Platforms() {}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
@ -214,18 +215,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
/** 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) throws Exception {
|
||||||
if (OFFICIAL_PLUGINS.contains(pluginId)) {
|
if (OFFICIAL_PLUGINS.contains(pluginId)) {
|
||||||
final String version = Version.CURRENT.toString();
|
final String url = getElasticUrl(terminal, getStagingHash(), Version.CURRENT, pluginId, Platforms.PLATFORM_NAME);
|
||||||
final String url;
|
|
||||||
final String stagingHash = System.getProperty(PROPERTY_STAGING_ID);
|
|
||||||
if (stagingHash != null) {
|
|
||||||
url = String.format(Locale.ROOT,
|
|
||||||
"https://staging.elastic.co/%3$s-%1$s/downloads/elasticsearch-plugins/%2$s/%2$s-%3$s.zip",
|
|
||||||
stagingHash, pluginId, version);
|
|
||||||
} else {
|
|
||||||
url = String.format(Locale.ROOT,
|
|
||||||
"https://artifacts.elastic.co/downloads/elasticsearch-plugins/%1$s/%1$s-%2$s.zip",
|
|
||||||
pluginId, version);
|
|
||||||
}
|
|
||||||
terminal.println("-> Downloading " + pluginId + " from elastic");
|
terminal.println("-> Downloading " + pluginId + " from elastic");
|
||||||
return downloadZipAndChecksum(terminal, url, tmpDir);
|
return downloadZipAndChecksum(terminal, url, tmpDir);
|
||||||
}
|
}
|
||||||
@ -233,8 +223,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
// 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
|
||||||
String[] coordinates = pluginId.split(":");
|
String[] coordinates = pluginId.split(":");
|
||||||
if (coordinates.length == 3 && pluginId.contains("/") == false) {
|
if (coordinates.length == 3 && pluginId.contains("/") == false) {
|
||||||
String mavenUrl = String.format(Locale.ROOT, "https://repo1.maven.org/maven2/%1$s/%2$s/%3$s/%2$s-%3$s.zip",
|
String mavenUrl = getMavenUrl(terminal, coordinates, Platforms.PLATFORM_NAME);
|
||||||
coordinates[0].replace(".", "/") /* groupId */, coordinates[1] /* artifactId */, coordinates[2] /* version */);
|
|
||||||
terminal.println("-> Downloading " + pluginId + " from maven central");
|
terminal.println("-> Downloading " + pluginId + " from maven central");
|
||||||
return downloadZipAndChecksum(terminal, mavenUrl, tmpDir);
|
return downloadZipAndChecksum(terminal, mavenUrl, tmpDir);
|
||||||
}
|
}
|
||||||
@ -253,6 +242,60 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
return downloadZip(terminal, pluginId, tmpDir);
|
return downloadZip(terminal, pluginId, tmpDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pkg private so tests can override
|
||||||
|
String getStagingHash() {
|
||||||
|
return System.getProperty(PROPERTY_STAGING_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the url for an official elasticsearch plugin. */
|
||||||
|
private String getElasticUrl(Terminal terminal, String stagingHash, Version version,
|
||||||
|
String pluginId, String platform) throws IOException {
|
||||||
|
final String baseUrl;
|
||||||
|
if (stagingHash != null) {
|
||||||
|
baseUrl = String.format(Locale.ROOT,
|
||||||
|
"https://staging.elastic.co/%s-%s/downloads/elasticsearch-plugins/%s", version, stagingHash, pluginId);
|
||||||
|
} else {
|
||||||
|
baseUrl = String.format(Locale.ROOT,
|
||||||
|
"https://artifacts.elastic.co/downloads/elasticsearch-plugins/%s", pluginId);
|
||||||
|
}
|
||||||
|
final String platformUrl = String.format(Locale.ROOT, "%s/%s-%s-%s.zip", baseUrl, pluginId, platform, version);
|
||||||
|
if (urlExists(terminal, platformUrl)) {
|
||||||
|
return platformUrl;
|
||||||
|
}
|
||||||
|
return String.format(Locale.ROOT, "%s/%s-%s.zip", baseUrl, pluginId, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the url for an elasticsearch plugin in maven. */
|
||||||
|
private String getMavenUrl(Terminal terminal, String[] coordinates, String platform) throws IOException {
|
||||||
|
final String groupId = coordinates[0].replace(".", "/");
|
||||||
|
final String artifactId = coordinates[1];
|
||||||
|
final String version = coordinates[2];
|
||||||
|
final String baseUrl = String.format(Locale.ROOT, "https://repo1.maven.org/maven2/%s/%s/%s", groupId, artifactId, version);
|
||||||
|
final String platformUrl = String.format(Locale.ROOT, "%s/%s-%s-%s.zip", baseUrl, artifactId, platform, version);
|
||||||
|
if (urlExists(terminal, platformUrl)) {
|
||||||
|
return platformUrl;
|
||||||
|
}
|
||||||
|
return String.format(Locale.ROOT, "%s/%s-%s.zip", baseUrl, artifactId, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if the given url exists, and {@code false} otherwise.
|
||||||
|
*
|
||||||
|
* The given url must be {@code https} and existing means a {@code HEAD} request returns 200.
|
||||||
|
*/
|
||||||
|
// pkg private for tests to manipulate
|
||||||
|
@SuppressForbidden(reason = "Make HEAD request using URLConnection.connect()")
|
||||||
|
boolean urlExists(Terminal terminal, String urlString) throws IOException {
|
||||||
|
terminal.println(VERBOSE, "Checking if url exists: " + urlString);
|
||||||
|
URL url = new URL(urlString);
|
||||||
|
assert "https".equals(url.getProtocol()) : "Only http urls can be checked";
|
||||||
|
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
|
||||||
|
urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer");
|
||||||
|
urlConnection.setRequestMethod("HEAD");
|
||||||
|
urlConnection.connect();
|
||||||
|
return urlConnection.getResponseCode() == 200;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns all the official plugin names that look similar to pluginId. **/
|
/** Returns all the official plugin names that look similar to pluginId. **/
|
||||||
private List<String> checkMisspelledPlugin(String pluginId) {
|
private List<String> checkMisspelledPlugin(String pluginId) {
|
||||||
LevensteinDistance ld = new LevensteinDistance();
|
LevensteinDistance ld = new LevensteinDistance();
|
||||||
@ -318,8 +361,9 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Downloads a zip from the url, as well as a SHA1 checksum, and checks the checksum. */
|
/** Downloads a zip from the url, as well as a SHA1 checksum, and checks the checksum. */
|
||||||
|
// 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) throws Exception {
|
Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir) throws Exception {
|
||||||
Path zip = downloadZip(terminal, urlString, tmpDir);
|
Path zip = downloadZip(terminal, urlString, tmpDir);
|
||||||
pathsToDeleteOnShutdown.add(zip);
|
pathsToDeleteOnShutdown.add(zip);
|
||||||
URL checksumUrl = new URL(urlString + ".sha1");
|
URL checksumUrl = new URL(urlString + ".sha1");
|
||||||
|
@ -52,6 +52,7 @@ import java.nio.file.FileVisitResult;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
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;
|
||||||
@ -77,6 +78,14 @@ import static org.hamcrest.Matchers.not;
|
|||||||
@LuceneTestCase.SuppressFileSystems("*")
|
@LuceneTestCase.SuppressFileSystems("*")
|
||||||
public class InstallPluginCommandTests extends ESTestCase {
|
public class InstallPluginCommandTests extends ESTestCase {
|
||||||
|
|
||||||
|
private static InstallPluginCommand SKIP_JARHELL_COMMAND = new InstallPluginCommand() {
|
||||||
|
@Override
|
||||||
|
void jarHellCheck(Path candidate, Path pluginsDir) throws Exception {
|
||||||
|
// no jarhell check
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private static InstallPluginCommand DEFAULT_COMMAND = new InstallPluginCommand();
|
||||||
|
|
||||||
private final Function<String, Path> temp;
|
private final Function<String, Path> temp;
|
||||||
|
|
||||||
private final FileSystem fs;
|
private final FileSystem fs;
|
||||||
@ -164,7 +173,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static String writeZip(Path structure, String prefix) throws IOException {
|
static Path writeZip(Path structure, String prefix) throws IOException {
|
||||||
Path zip = createTempDir().resolve(structure.getFileName() + ".zip");
|
Path zip = createTempDir().resolve(structure.getFileName() + ".zip");
|
||||||
try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(zip))) {
|
try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(zip))) {
|
||||||
Files.walkFileTree(structure, new SimpleFileVisitor<Path>() {
|
Files.walkFileTree(structure, new SimpleFileVisitor<Path>() {
|
||||||
@ -177,15 +186,15 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return zip.toUri().toURL().toString();
|
return zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** creates a plugin .zip and returns the url for testing */
|
/** creates a plugin .zip and returns the url for testing */
|
||||||
static String createPlugin(String name, Path structure) throws IOException {
|
static String createPluginUrl(String name, Path structure) throws IOException {
|
||||||
return createPlugin(name, structure, false);
|
return createPlugin(name, structure, false).toUri().toURL().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static String createPlugin(String name, Path structure, boolean createSecurityPolicyFile) throws IOException {
|
static Path createPlugin(String name, Path structure, boolean createSecurityPolicyFile) throws IOException {
|
||||||
PluginTestUtil.writeProperties(structure,
|
PluginTestUtil.writeProperties(structure,
|
||||||
"description", "fake desc",
|
"description", "fake desc",
|
||||||
"name", name,
|
"name", name,
|
||||||
@ -202,20 +211,13 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MockTerminal installPlugin(String pluginUrl, Path home) throws Exception {
|
static MockTerminal installPlugin(String pluginUrl, Path home) throws Exception {
|
||||||
return installPlugin(pluginUrl, home, false);
|
return installPlugin(pluginUrl, home, SKIP_JARHELL_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MockTerminal installPlugin(String pluginUrl, Path home, boolean jarHellCheck) throws Exception {
|
static MockTerminal installPlugin(String pluginUrl, Path home, InstallPluginCommand command) throws Exception {
|
||||||
Environment env = new Environment(Settings.builder().put("path.home", home).build());
|
Environment env = new Environment(Settings.builder().put("path.home", home).build());
|
||||||
MockTerminal terminal = new MockTerminal();
|
MockTerminal terminal = new MockTerminal();
|
||||||
new InstallPluginCommand() {
|
command.execute(terminal, pluginUrl, true, env);
|
||||||
@Override
|
|
||||||
void jarHellCheck(Path candidate, Path pluginsDir) throws Exception {
|
|
||||||
if (jarHellCheck) {
|
|
||||||
super.jarHellCheck(candidate, pluginsDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.execute(terminal, pluginUrl, true, env);
|
|
||||||
return terminal;
|
return terminal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +317,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
public void testSomethingWorks() throws Exception {
|
public void testSomethingWorks() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env.v1());
|
installPlugin(pluginZip, env.v1());
|
||||||
assertPlugin("fake", pluginDir, env.v2());
|
assertPlugin("fake", pluginDir, env.v2());
|
||||||
}
|
}
|
||||||
@ -323,7 +325,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
public void testSpaceInUrl() throws Exception {
|
public void testSpaceInUrl() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
Path pluginZipWithSpaces = createTempFile("foo bar", ".zip");
|
Path pluginZipWithSpaces = createTempFile("foo bar", ".zip");
|
||||||
try (InputStream in = FileSystemUtils.openFileURLStream(new URL(pluginZip))) {
|
try (InputStream in = FileSystemUtils.openFileURLStream(new URL(pluginZip))) {
|
||||||
Files.copy(in, pluginZipWithSpaces, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(in, pluginZipWithSpaces, StandardCopyOption.REPLACE_EXISTING);
|
||||||
@ -351,7 +353,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
try (PosixPermissionsResetter pluginsAttrs = new PosixPermissionsResetter(env.v2().pluginsFile())) {
|
try (PosixPermissionsResetter pluginsAttrs = new PosixPermissionsResetter(env.v2().pluginsFile())) {
|
||||||
pluginsAttrs.setPermissions(new HashSet<>());
|
pluginsAttrs.setPermissions(new HashSet<>());
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
IOException e = expectThrows(IOException.class, () -> installPlugin(pluginZip, env.v1()));
|
IOException e = expectThrows(IOException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains(env.v2().pluginsFile().toString()));
|
assertTrue(e.getMessage(), e.getMessage().contains(env.v2().pluginsFile().toString()));
|
||||||
}
|
}
|
||||||
@ -361,7 +363,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
public void testBuiltinModule() throws Exception {
|
public void testBuiltinModule() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPlugin("lang-painless", pluginDir);
|
String pluginZip = createPluginUrl("lang-painless", pluginDir);
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("is a system module"));
|
assertTrue(e.getMessage(), e.getMessage().contains("is a system module"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
@ -373,8 +375,9 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Tuple<Path, Environment> environment = createEnv(fs, temp);
|
Tuple<Path, Environment> environment = createEnv(fs, temp);
|
||||||
Path pluginDirectory = createPluginDir(temp);
|
Path pluginDirectory = createPluginDir(temp);
|
||||||
writeJar(pluginDirectory.resolve("other.jar"), "FakePlugin");
|
writeJar(pluginDirectory.resolve("other.jar"), "FakePlugin");
|
||||||
String pluginZip = createPlugin("fake", pluginDirectory); // adds plugin.jar with FakePlugin
|
String pluginZip = createPluginUrl("fake", pluginDirectory); // adds plugin.jar with FakePlugin
|
||||||
IllegalStateException e = expectThrows(IllegalStateException.class, () -> installPlugin(pluginZip, environment.v1(), true));
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> installPlugin(pluginZip, environment.v1(), DEFAULT_COMMAND));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("jar hell"));
|
assertTrue(e.getMessage(), e.getMessage().contains("jar hell"));
|
||||||
assertInstallCleaned(environment.v2());
|
assertInstallCleaned(environment.v2());
|
||||||
}
|
}
|
||||||
@ -383,10 +386,10 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
// these both share the same FakePlugin class
|
// these both share the same FakePlugin class
|
||||||
Path pluginDir1 = createPluginDir(temp);
|
Path pluginDir1 = createPluginDir(temp);
|
||||||
String pluginZip1 = createPlugin("fake1", pluginDir1);
|
String pluginZip1 = createPluginUrl("fake1", pluginDir1);
|
||||||
installPlugin(pluginZip1, env.v1());
|
installPlugin(pluginZip1, env.v1());
|
||||||
Path pluginDir2 = createPluginDir(temp);
|
Path pluginDir2 = createPluginDir(temp);
|
||||||
String pluginZip2 = createPlugin("fake2", pluginDir2);
|
String pluginZip2 = createPluginUrl("fake2", pluginDir2);
|
||||||
installPlugin(pluginZip2, env.v1());
|
installPlugin(pluginZip2, env.v1());
|
||||||
assertPlugin("fake1", pluginDir1, env.v2());
|
assertPlugin("fake1", pluginDir1, env.v2());
|
||||||
assertPlugin("fake2", pluginDir2, env.v2());
|
assertPlugin("fake2", pluginDir2, env.v2());
|
||||||
@ -395,7 +398,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
public void testExistingPlugin() throws Exception {
|
public void testExistingPlugin() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env.v1());
|
installPlugin(pluginZip, env.v1());
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("already exists"));
|
assertTrue(e.getMessage(), e.getMessage().contains("already exists"));
|
||||||
@ -408,7 +411,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path binDir = pluginDir.resolve("bin");
|
Path binDir = pluginDir.resolve("bin");
|
||||||
Files.createDirectory(binDir);
|
Files.createDirectory(binDir);
|
||||||
Files.createFile(binDir.resolve("somescript"));
|
Files.createFile(binDir.resolve("somescript"));
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env.v1());
|
installPlugin(pluginZip, env.v1());
|
||||||
assertPlugin("fake", pluginDir, env.v2());
|
assertPlugin("fake", pluginDir, env.v2());
|
||||||
}
|
}
|
||||||
@ -418,7 +421,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
Path binDir = pluginDir.resolve("bin");
|
Path binDir = pluginDir.resolve("bin");
|
||||||
Files.createFile(binDir);
|
Files.createFile(binDir);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("not a directory"));
|
assertTrue(e.getMessage(), e.getMessage().contains("not a directory"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
@ -430,7 +433,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path dirInBinDir = pluginDir.resolve("bin").resolve("foo");
|
Path dirInBinDir = pluginDir.resolve("bin").resolve("foo");
|
||||||
Files.createDirectories(dirInBinDir);
|
Files.createDirectories(dirInBinDir);
|
||||||
Files.createFile(dirInBinDir.resolve("somescript"));
|
Files.createFile(dirInBinDir.resolve("somescript"));
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Directories not allowed in bin dir for plugin"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Directories not allowed in bin dir for plugin"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
@ -442,7 +445,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path binDir = pluginDir.resolve("bin");
|
Path binDir = pluginDir.resolve("bin");
|
||||||
Files.createDirectory(binDir);
|
Files.createDirectory(binDir);
|
||||||
Files.createFile(binDir.resolve("somescript"));
|
Files.createFile(binDir.resolve("somescript"));
|
||||||
String pluginZip = createPlugin("elasticsearch", pluginDir);
|
String pluginZip = createPluginUrl("elasticsearch", pluginDir);
|
||||||
FileAlreadyExistsException e = expectThrows(FileAlreadyExistsException.class, () -> installPlugin(pluginZip, env.v1()));
|
FileAlreadyExistsException e = expectThrows(FileAlreadyExistsException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains(env.v2().binFile().resolve("elasticsearch").toString()));
|
assertTrue(e.getMessage(), e.getMessage().contains(env.v2().binFile().resolve("elasticsearch").toString()));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
@ -455,7 +458,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path binDir = pluginDir.resolve("bin");
|
Path binDir = pluginDir.resolve("bin");
|
||||||
Files.createDirectory(binDir);
|
Files.createDirectory(binDir);
|
||||||
Files.createFile(binDir.resolve("somescript"));
|
Files.createFile(binDir.resolve("somescript"));
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
try (PosixPermissionsResetter binAttrs = new PosixPermissionsResetter(env.v2().binFile())) {
|
try (PosixPermissionsResetter binAttrs = new PosixPermissionsResetter(env.v2().binFile())) {
|
||||||
Set<PosixFilePermission> perms = binAttrs.getCopyPermissions();
|
Set<PosixFilePermission> perms = binAttrs.getCopyPermissions();
|
||||||
// make sure at least one execute perm is missing, so we know we forced it during installation
|
// make sure at least one execute perm is missing, so we know we forced it during installation
|
||||||
@ -480,7 +483,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
assertFalse(sourcePerms.contains(PosixFilePermission.OWNER_EXECUTE));
|
assertFalse(sourcePerms.contains(PosixFilePermission.OWNER_EXECUTE));
|
||||||
assertFalse(sourcePerms.contains(PosixFilePermission.GROUP_EXECUTE));
|
assertFalse(sourcePerms.contains(PosixFilePermission.GROUP_EXECUTE));
|
||||||
assertFalse(sourcePerms.contains(PosixFilePermission.OTHERS_EXECUTE));
|
assertFalse(sourcePerms.contains(PosixFilePermission.OTHERS_EXECUTE));
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env.v1());
|
installPlugin(pluginZip, env.v1());
|
||||||
assertPlugin("fake", pluginDir, env.v2());
|
assertPlugin("fake", pluginDir, env.v2());
|
||||||
// check that the installed program has execute permissions, even though the one added to the plugin didn't
|
// check that the installed program has execute permissions, even though the one added to the plugin didn't
|
||||||
@ -500,7 +503,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path configDir = pluginDir.resolve("config");
|
Path configDir = pluginDir.resolve("config");
|
||||||
Files.createDirectory(configDir);
|
Files.createDirectory(configDir);
|
||||||
Files.createFile(configDir.resolve("custom.yaml"));
|
Files.createFile(configDir.resolve("custom.yaml"));
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env.v1());
|
installPlugin(pluginZip, env.v1());
|
||||||
assertPlugin("fake", pluginDir, env.v2());
|
assertPlugin("fake", pluginDir, env.v2());
|
||||||
}
|
}
|
||||||
@ -515,7 +518,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Files.createDirectory(configDir);
|
Files.createDirectory(configDir);
|
||||||
Files.write(configDir.resolve("custom.yaml"), "new config".getBytes(StandardCharsets.UTF_8));
|
Files.write(configDir.resolve("custom.yaml"), "new config".getBytes(StandardCharsets.UTF_8));
|
||||||
Files.createFile(configDir.resolve("other.yaml"));
|
Files.createFile(configDir.resolve("other.yaml"));
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env.v1());
|
installPlugin(pluginZip, env.v1());
|
||||||
assertPlugin("fake", pluginDir, env.v2());
|
assertPlugin("fake", pluginDir, env.v2());
|
||||||
List<String> configLines = Files.readAllLines(envConfigDir.resolve("custom.yaml"), StandardCharsets.UTF_8);
|
List<String> configLines = Files.readAllLines(envConfigDir.resolve("custom.yaml"), StandardCharsets.UTF_8);
|
||||||
@ -529,7 +532,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
Path configDir = pluginDir.resolve("config");
|
Path configDir = pluginDir.resolve("config");
|
||||||
Files.createFile(configDir);
|
Files.createFile(configDir);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("not a directory"));
|
assertTrue(e.getMessage(), e.getMessage().contains("not a directory"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
@ -541,7 +544,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path dirInConfigDir = pluginDir.resolve("config").resolve("foo");
|
Path dirInConfigDir = pluginDir.resolve("config").resolve("foo");
|
||||||
Files.createDirectories(dirInConfigDir);
|
Files.createDirectories(dirInConfigDir);
|
||||||
Files.createFile(dirInConfigDir.resolve("myconfig.yml"));
|
Files.createFile(dirInConfigDir.resolve("myconfig.yml"));
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Directories not allowed in config dir for plugin"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Directories not allowed in config dir for plugin"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
@ -553,7 +556,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path configDir = pluginDir.resolve("config");
|
Path configDir = pluginDir.resolve("config");
|
||||||
Files.createDirectory(configDir);
|
Files.createDirectory(configDir);
|
||||||
Files.createFile(configDir.resolve("myconfig.yml"));
|
Files.createFile(configDir.resolve("myconfig.yml"));
|
||||||
String pluginZip = createPlugin("elasticsearch.yml", pluginDir);
|
String pluginZip = createPluginUrl("elasticsearch.yml", pluginDir);
|
||||||
FileAlreadyExistsException e = expectThrows(FileAlreadyExistsException.class, () -> installPlugin(pluginZip, env.v1()));
|
FileAlreadyExistsException e = expectThrows(FileAlreadyExistsException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains(env.v2().configFile().resolve("elasticsearch.yml").toString()));
|
assertTrue(e.getMessage(), e.getMessage().contains(env.v2().configFile().resolve("elasticsearch.yml").toString()));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
@ -563,7 +566,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
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("fake.yml"));
|
Files.createFile(pluginDir.resolve("fake.yml"));
|
||||||
String pluginZip = writeZip(pluginDir, "elasticsearch");
|
String pluginZip = writeZip(pluginDir, "elasticsearch").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());
|
||||||
@ -573,7 +576,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
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);
|
String pluginZip = writeZip(pluginDir, null).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"));
|
assertTrue(e.getMessage(), e.getMessage().contains("`elasticsearch` directory is missing in the plugin zip"));
|
||||||
assertInstallCleaned(env.v2());
|
assertInstallCleaned(env.v2());
|
||||||
@ -666,9 +669,10 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
public void testPluginAlreadyInstalled() throws Exception {
|
public void testPluginAlreadyInstalled() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env.v1());
|
installPlugin(pluginZip, env.v1());
|
||||||
final UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1(), randomBoolean()));
|
final UserException e = expectThrows(UserException.class,
|
||||||
|
() -> installPlugin(pluginZip, env.v1(), randomFrom(SKIP_JARHELL_COMMAND, DEFAULT_COMMAND)));
|
||||||
assertThat(
|
assertThat(
|
||||||
e.getMessage(),
|
e.getMessage(),
|
||||||
equalTo("plugin directory [" + env.v2().pluginsFile().resolve("fake") + "] already exists; " +
|
equalTo("plugin directory [" + env.v2().pluginsFile().resolve("fake") + "] already exists; " +
|
||||||
@ -679,15 +683,71 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
// if batch is enabled, we also want to add a security policy
|
// if batch is enabled, we also want to add a security policy
|
||||||
String pluginZip = createPlugin("fake", pluginDir, isBatch);
|
String pluginZip = createPlugin("fake", pluginDir, isBatch).toUri().toURL().toString();
|
||||||
|
SKIP_JARHELL_COMMAND.execute(terminal, pluginZip, isBatch, env.v2());
|
||||||
|
}
|
||||||
|
|
||||||
new InstallPluginCommand() {
|
public void assertInstallPluginFromUrl(String pluginId, String name, String url, String stagingHash) throws Exception {
|
||||||
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
|
Path pluginDir = createPluginDir(temp);
|
||||||
|
Path pluginZip = createPlugin(name, pluginDir, false);
|
||||||
|
InstallPluginCommand command = new InstallPluginCommand() {
|
||||||
|
@Override
|
||||||
|
Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir) throws Exception {
|
||||||
|
assertEquals(url, urlString);
|
||||||
|
Path downloadedPath = tmpDir.resolve("downloaded.zip");
|
||||||
|
Files.copy(pluginZip, downloadedPath);
|
||||||
|
return downloadedPath;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
boolean urlExists(Terminal terminal, String urlString) throws IOException {
|
||||||
|
return urlString.equals(url);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
String getStagingHash() {
|
||||||
|
return stagingHash;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
void jarHellCheck(Path candidate, Path pluginsDir) throws Exception {
|
void jarHellCheck(Path candidate, Path pluginsDir) throws Exception {
|
||||||
|
// no jarhell check
|
||||||
}
|
}
|
||||||
}.execute(terminal, pluginZip, isBatch, env.v2());
|
};
|
||||||
|
installPlugin(pluginId, env.v1(), command);
|
||||||
|
assertPlugin(name, pluginDir, env.v2());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOfficalPlugin() throws Exception {
|
||||||
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + Version.CURRENT + ".zip";
|
||||||
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOfficalPluginStaging() throws Exception {
|
||||||
|
String url = "https://staging.elastic.co/" + Version.CURRENT + "-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
|
+ Version.CURRENT + ".zip";
|
||||||
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOfficalPlatformPlugin() throws Exception {
|
||||||
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + Platforms.PLATFORM_NAME +
|
||||||
|
"-" + Version.CURRENT + ".zip";
|
||||||
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOfficalPlatformPluginStaging() throws Exception {
|
||||||
|
String url = "https://staging.elastic.co/" + Version.CURRENT + "-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
|
+ Platforms.PLATFORM_NAME + "-"+ Version.CURRENT + ".zip";
|
||||||
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMavenPlugin() throws Exception {
|
||||||
|
String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-1.0.0.zip";
|
||||||
|
assertInstallPluginFromUrl("mygroup:myplugin:1.0.0", "myplugin", url, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMavenPlatformPlugin() throws Exception {
|
||||||
|
String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-" + Platforms.PLATFORM_NAME + "-1.0.0.zip";
|
||||||
|
assertInstallPluginFromUrl("mygroup:myplugin:1.0.0", "myplugin", url, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test checksum (need maven/official below)
|
// TODO: test checksum (need maven/official below)
|
||||||
// TODO: test maven, official, and staging install...need tests with fixtures...
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user