Merge pull request #17208 from jasontedor/install-plugin-permissions
Install plugin permissions
This commit is contained in:
commit
17dd60dd31
|
@ -660,7 +660,6 @@
|
||||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]node[/\\]internal[/\\]InternalSettingsPreparer.java" checks="LineLength" />
|
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]node[/\\]internal[/\\]InternalSettingsPreparer.java" checks="LineLength" />
|
||||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]percolator[/\\]PercolatorQuery.java" checks="LineLength" />
|
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]percolator[/\\]PercolatorQuery.java" checks="LineLength" />
|
||||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]plugins[/\\]DummyPluginInfo.java" checks="LineLength" />
|
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]plugins[/\\]DummyPluginInfo.java" checks="LineLength" />
|
||||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]plugins[/\\]InstallPluginCommand.java" checks="LineLength" />
|
|
||||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]plugins[/\\]PluginsService.java" checks="LineLength" />
|
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]plugins[/\\]PluginsService.java" checks="LineLength" />
|
||||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]plugins[/\\]RemovePluginCommand.java" checks="LineLength" />
|
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]plugins[/\\]RemovePluginCommand.java" checks="LineLength" />
|
||||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]repositories[/\\]RepositoriesModule.java" checks="LineLength" />
|
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]repositories[/\\]RepositoriesModule.java" checks="LineLength" />
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.plugins;
|
||||||
|
|
||||||
import joptsimple.OptionSet;
|
import joptsimple.OptionSet;
|
||||||
import joptsimple.OptionSpec;
|
import joptsimple.OptionSpec;
|
||||||
import org.apache.lucene.util.Constants;
|
|
||||||
import org.apache.lucene.util.IOUtils;
|
import org.apache.lucene.util.IOUtils;
|
||||||
import org.elasticsearch.Build;
|
import org.elasticsearch.Build;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
|
@ -56,6 +55,7 @@ import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
@ -183,11 +183,18 @@ class InstallPluginCommand extends Command {
|
||||||
final String version = Version.CURRENT.toString();
|
final String version = Version.CURRENT.toString();
|
||||||
final String url;
|
final String url;
|
||||||
if (System.getProperty(PROPERTY_SUPPORT_STAGING_URLS, "false").equals("true")) {
|
if (System.getProperty(PROPERTY_SUPPORT_STAGING_URLS, "false").equals("true")) {
|
||||||
url = String.format(Locale.ROOT, "https://download.elastic.co/elasticsearch/staging/%1$s-%2$s/org/elasticsearch/plugin/%3$s/%1$s/%3$s-%1$s.zip",
|
url = String.format(
|
||||||
version, Build.CURRENT.shortHash(), pluginId);
|
Locale.ROOT,
|
||||||
|
"https://download.elastic.co/elasticsearch/staging/%1$s-%2$s/org/elasticsearch/plugin/%3$s/%1$s/%3$s-%1$s.zip",
|
||||||
|
version,
|
||||||
|
Build.CURRENT.shortHash(),
|
||||||
|
pluginId);
|
||||||
} else {
|
} else {
|
||||||
url = String.format(Locale.ROOT, "https://download.elastic.co/elasticsearch/release/org/elasticsearch/plugin/%1$s/%2$s/%1$s-%2$s.zip",
|
url = String.format(
|
||||||
pluginId, version);
|
Locale.ROOT,
|
||||||
|
"https://download.elastic.co/elasticsearch/release/org/elasticsearch/plugin/%1$s/%2$s/%1$s-%2$s.zip",
|
||||||
|
pluginId,
|
||||||
|
version);
|
||||||
}
|
}
|
||||||
terminal.println("-> Downloading " + pluginId + " from elastic");
|
terminal.println("-> Downloading " + pluginId + " from elastic");
|
||||||
return downloadZipAndChecksum(url, tmpDir);
|
return downloadZipAndChecksum(url, tmpDir);
|
||||||
|
@ -243,21 +250,8 @@ class InstallPluginCommand extends Command {
|
||||||
|
|
||||||
private Path unzip(Path zip, Path pluginsDir) throws IOException, UserError {
|
private Path unzip(Path zip, Path pluginsDir) throws IOException, UserError {
|
||||||
// unzip plugin to a staging temp dir
|
// unzip plugin to a staging temp dir
|
||||||
final Path target;
|
|
||||||
if (Constants.WINDOWS) {
|
final Path target = stagingDirectory(pluginsDir);
|
||||||
target = Files.createTempDirectory(pluginsDir, ".installing-");
|
|
||||||
} else {
|
|
||||||
Set<PosixFilePermission> perms = new HashSet<>();
|
|
||||||
perms.add(PosixFilePermission.OWNER_EXECUTE);
|
|
||||||
perms.add(PosixFilePermission.OWNER_READ);
|
|
||||||
perms.add(PosixFilePermission.OWNER_WRITE);
|
|
||||||
perms.add(PosixFilePermission.GROUP_READ);
|
|
||||||
perms.add(PosixFilePermission.GROUP_EXECUTE);
|
|
||||||
perms.add(PosixFilePermission.OTHERS_READ);
|
|
||||||
perms.add(PosixFilePermission.OTHERS_EXECUTE);
|
|
||||||
target = Files.createTempDirectory(pluginsDir, ".installing-", PosixFilePermissions.asFileAttribute(perms));
|
|
||||||
}
|
|
||||||
Files.createDirectories(target);
|
|
||||||
|
|
||||||
boolean hasEsDir = false;
|
boolean hasEsDir = false;
|
||||||
// TODO: we should wrap this in a try/catch and try deleting the target dir on failure?
|
// TODO: we should wrap this in a try/catch and try deleting the target dir on failure?
|
||||||
|
@ -302,6 +296,39 @@ class InstallPluginCommand extends Command {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Path stagingDirectory(Path pluginsDir) throws IOException {
|
||||||
|
try {
|
||||||
|
Set<PosixFilePermission> perms = new HashSet<>();
|
||||||
|
perms.add(PosixFilePermission.OWNER_EXECUTE);
|
||||||
|
perms.add(PosixFilePermission.OWNER_READ);
|
||||||
|
perms.add(PosixFilePermission.OWNER_WRITE);
|
||||||
|
perms.add(PosixFilePermission.GROUP_READ);
|
||||||
|
perms.add(PosixFilePermission.GROUP_EXECUTE);
|
||||||
|
perms.add(PosixFilePermission.OTHERS_READ);
|
||||||
|
perms.add(PosixFilePermission.OTHERS_EXECUTE);
|
||||||
|
return Files.createTempDirectory(pluginsDir, ".installing-", PosixFilePermissions.asFileAttribute(perms));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// Jimfs throws an IAE where it should throw an UOE
|
||||||
|
// remove when google/jimfs#30 is integrated into Jimfs
|
||||||
|
// and the Jimfs test dependency is upgraded to include
|
||||||
|
// this pull request
|
||||||
|
final StackTraceElement[] elements = e.getStackTrace();
|
||||||
|
if (elements.length >= 1 &&
|
||||||
|
elements[0].getClassName().equals("com.google.common.jimfs.AttributeService") &&
|
||||||
|
elements[0].getMethodName().equals("setAttributeInternal")) {
|
||||||
|
return stagingDirectoryWithoutPosixPermissions(pluginsDir);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
return stagingDirectoryWithoutPosixPermissions(pluginsDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path stagingDirectoryWithoutPosixPermissions(Path pluginsDir) throws IOException {
|
||||||
|
return Files.createTempDirectory(pluginsDir, ".installing-");
|
||||||
|
}
|
||||||
|
|
||||||
/** Load information about the plugin, and verify it can be installed with no errors. */
|
/** Load information about the plugin, and verify it can be installed with no errors. */
|
||||||
private PluginInfo verify(Terminal terminal, Path pluginRoot, boolean isBatch) throws Exception {
|
private PluginInfo verify(Terminal terminal, Path pluginRoot, boolean isBatch) throws Exception {
|
||||||
// read and validate the plugin descriptor
|
// read and validate the plugin descriptor
|
||||||
|
@ -328,7 +355,7 @@ class InstallPluginCommand extends Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** check a candidate plugin for jar hell before installing it */
|
/** check a candidate plugin for jar hell before installing it */
|
||||||
private void jarHellCheck(Path candidate, Path pluginsDir, boolean isolated) throws Exception {
|
void jarHellCheck(Path candidate, Path pluginsDir, boolean isolated) throws Exception {
|
||||||
// create list of current jars in classpath
|
// create list of current jars in classpath
|
||||||
final List<URL> jars = new ArrayList<>();
|
final List<URL> jars = new ArrayList<>();
|
||||||
jars.addAll(Arrays.asList(JarHell.parseClassPath()));
|
jars.addAll(Arrays.asList(JarHell.parseClassPath()));
|
||||||
|
@ -367,7 +394,10 @@ class InstallPluginCommand extends Command {
|
||||||
|
|
||||||
final Path destination = env.pluginsFile().resolve(info.getName());
|
final Path destination = env.pluginsFile().resolve(info.getName());
|
||||||
if (Files.exists(destination)) {
|
if (Files.exists(destination)) {
|
||||||
throw new UserError(ExitCodes.USAGE, "plugin directory " + destination.toAbsolutePath() + " already exists. To update the plugin, uninstall it first using 'remove " + info.getName() + "' command");
|
throw new UserError(
|
||||||
|
ExitCodes.USAGE,
|
||||||
|
"plugin directory " + destination.toAbsolutePath() +
|
||||||
|
" already exists. To update the plugin, uninstall it first using 'remove " + info.getName() + "' command");
|
||||||
}
|
}
|
||||||
|
|
||||||
Path tmpBinDir = tmpRoot.resolve("bin");
|
Path tmpBinDir = tmpRoot.resolve("bin");
|
||||||
|
@ -404,30 +434,30 @@ class InstallPluginCommand extends Command {
|
||||||
}
|
}
|
||||||
Files.createDirectory(destBinDir);
|
Files.createDirectory(destBinDir);
|
||||||
|
|
||||||
Set<PosixFilePermission> perms = new HashSet<>();
|
|
||||||
if (Constants.WINDOWS == false) {
|
|
||||||
// setup file attributes for the installed files to those of the parent dir
|
// setup file attributes for the installed files to those of the parent dir
|
||||||
PosixFileAttributeView binAttrs = Files.getFileAttributeView(destBinDir.getParent(), PosixFileAttributeView.class);
|
final Set<PosixFilePermission> perms = new HashSet<>();
|
||||||
if (binAttrs != null) {
|
final PosixFileAttributeView binAttributeView = Files.getFileAttributeView(destBinDir.getParent(), PosixFileAttributeView.class);
|
||||||
perms = new HashSet<>(binAttrs.readAttributes().permissions());
|
if (binAttributeView != null) {
|
||||||
|
perms.addAll(binAttributeView.readAttributes().permissions());
|
||||||
// setting execute bits, since this just means "the file is executable", and actual execution requires read
|
// setting execute bits, since this just means "the file is executable", and actual execution requires read
|
||||||
perms.add(PosixFilePermission.OWNER_EXECUTE);
|
perms.add(PosixFilePermission.OWNER_EXECUTE);
|
||||||
perms.add(PosixFilePermission.GROUP_EXECUTE);
|
perms.add(PosixFilePermission.GROUP_EXECUTE);
|
||||||
perms.add(PosixFilePermission.OTHERS_EXECUTE);
|
perms.add(PosixFilePermission.OTHERS_EXECUTE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpBinDir)) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpBinDir)) {
|
||||||
for (Path srcFile : stream) {
|
for (Path srcFile : stream) {
|
||||||
if (Files.isDirectory(srcFile)) {
|
if (Files.isDirectory(srcFile)) {
|
||||||
throw new UserError(ExitCodes.DATA_ERROR, "Directories not allowed in bin dir for plugin " + info.getName() + ", found " + srcFile.getFileName());
|
throw new UserError(
|
||||||
|
ExitCodes.DATA_ERROR,
|
||||||
|
"Directories not allowed in bin dir for plugin " + info.getName() + ", found " + srcFile.getFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
Path destFile = destBinDir.resolve(tmpBinDir.relativize(srcFile));
|
Path destFile = destBinDir.resolve(tmpBinDir.relativize(srcFile));
|
||||||
Files.copy(srcFile, destFile);
|
Files.copy(srcFile, destFile);
|
||||||
|
|
||||||
if (perms.isEmpty() == false) {
|
final PosixFileAttributeView view = Files.getFileAttributeView(destFile, PosixFileAttributeView.class);
|
||||||
PosixFileAttributeView view = Files.getFileAttributeView(destFile, PosixFileAttributeView.class);
|
if (view != null) {
|
||||||
view.setPermissions(perms);
|
view.setPermissions(perms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,15 +476,12 @@ class InstallPluginCommand extends Command {
|
||||||
|
|
||||||
// create the plugin's config dir "if necessary"
|
// create the plugin's config dir "if necessary"
|
||||||
Files.createDirectories(destConfigDir);
|
Files.createDirectories(destConfigDir);
|
||||||
|
final PosixFileAttributeView destConfigDirAttributesView =
|
||||||
final PosixFileAttributes destConfigDirAttributes;
|
Files.getFileAttributeView(destConfigDir.getParent(), PosixFileAttributeView.class);
|
||||||
if (Constants.WINDOWS) {
|
final PosixFileAttributes destConfigDirAttributes =
|
||||||
destConfigDirAttributes = null;
|
destConfigDirAttributesView != null ? destConfigDirAttributesView.readAttributes() : null;
|
||||||
} else {
|
if (destConfigDirAttributes != null) {
|
||||||
destConfigDirAttributes =
|
|
||||||
Files.getFileAttributeView(destConfigDir.getParent(), PosixFileAttributeView.class).readAttributes();
|
|
||||||
setOwnerGroup(destConfigDir, destConfigDirAttributes);
|
setOwnerGroup(destConfigDir, destConfigDirAttributes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpConfigDir)) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpConfigDir)) {
|
||||||
|
@ -466,7 +493,7 @@ class InstallPluginCommand extends Command {
|
||||||
Path destFile = destConfigDir.resolve(tmpConfigDir.relativize(srcFile));
|
Path destFile = destConfigDir.resolve(tmpConfigDir.relativize(srcFile));
|
||||||
if (Files.exists(destFile) == false) {
|
if (Files.exists(destFile) == false) {
|
||||||
Files.copy(srcFile, destFile);
|
Files.copy(srcFile, destFile);
|
||||||
if (Constants.WINDOWS == false) {
|
if (destConfigDirAttributes != null) {
|
||||||
setOwnerGroup(destFile, destConfigDirAttributes);
|
setOwnerGroup(destFile, destConfigDirAttributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -475,8 +502,10 @@ class InstallPluginCommand extends Command {
|
||||||
IOUtils.rm(tmpConfigDir); // clean up what we just copied
|
IOUtils.rm(tmpConfigDir); // clean up what we just copied
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setOwnerGroup(Path path, PosixFileAttributes attributes) throws IOException {
|
private static void setOwnerGroup(final Path path, final PosixFileAttributes attributes) throws IOException {
|
||||||
|
Objects.requireNonNull(attributes);
|
||||||
PosixFileAttributeView fileAttributeView = Files.getFileAttributeView(path, PosixFileAttributeView.class);
|
PosixFileAttributeView fileAttributeView = Files.getFileAttributeView(path, PosixFileAttributeView.class);
|
||||||
|
assert fileAttributeView != null;
|
||||||
fileAttributeView.setOwner(attributes.owner());
|
fileAttributeView.setOwner(attributes.owner());
|
||||||
fileAttributeView.setGroup(attributes.group());
|
fileAttributeView.setGroup(attributes.group());
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,22 @@
|
||||||
|
|
||||||
package org.elasticsearch.plugins;
|
package org.elasticsearch.plugins;
|
||||||
|
|
||||||
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
import com.google.common.jimfs.Configuration;
|
||||||
|
import com.google.common.jimfs.Jimfs;
|
||||||
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
import org.apache.lucene.util.SuppressForbidden;
|
||||||
|
import org.elasticsearch.Version;
|
||||||
|
import org.elasticsearch.cli.MockTerminal;
|
||||||
|
import org.elasticsearch.cli.UserError;
|
||||||
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
|
import org.elasticsearch.common.io.PathUtilsForTesting;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.env.Environment;
|
||||||
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
import org.elasticsearch.test.PosixPermissionsResetter;
|
||||||
|
import org.junit.After;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
@ -26,6 +42,7 @@ import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.DirectoryStream;
|
import java.nio.file.DirectoryStream;
|
||||||
import java.nio.file.FileAlreadyExistsException;
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
import java.nio.file.FileVisitResult;
|
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;
|
||||||
|
@ -36,46 +53,100 @@ import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.nio.file.attribute.PosixFileAttributeView;
|
import java.nio.file.attribute.PosixFileAttributeView;
|
||||||
import java.nio.file.attribute.PosixFileAttributes;
|
import java.nio.file.attribute.PosixFileAttributes;
|
||||||
import java.nio.file.attribute.PosixFilePermission;
|
import java.nio.file.attribute.PosixFilePermission;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import org.elasticsearch.Version;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import org.elasticsearch.cli.MockTerminal;
|
|
||||||
import org.elasticsearch.cli.UserError;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.env.Environment;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.test.PosixPermissionsResetter;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
|
|
||||||
@LuceneTestCase.SuppressFileSystems("*")
|
@LuceneTestCase.SuppressFileSystems("*")
|
||||||
public class InstallPluginCommandTests extends ESTestCase {
|
public class InstallPluginCommandTests extends ESTestCase {
|
||||||
|
|
||||||
private static boolean isPosix;
|
private final Function<String, Path> temp;
|
||||||
|
|
||||||
@BeforeClass
|
private final FileSystem fs;
|
||||||
public static void checkPosix() throws IOException {
|
private final boolean isPosix;
|
||||||
isPosix = Files.getFileAttributeView(createTempFile(), PosixFileAttributeView.class) != null;
|
private final boolean isReal;
|
||||||
|
private final String javaIoTmpdir;
|
||||||
|
|
||||||
|
@SuppressForbidden(reason = "sets java.io.tmpdir")
|
||||||
|
public InstallPluginCommandTests(FileSystem fs, Function<String, Path> temp) {
|
||||||
|
this.fs = fs;
|
||||||
|
this.temp = temp;
|
||||||
|
this.isPosix = fs.supportedFileAttributeViews().contains("posix");
|
||||||
|
this.isReal = fs == PathUtils.getDefaultFileSystem();
|
||||||
|
PathUtilsForTesting.installMock(fs);
|
||||||
|
javaIoTmpdir = System.getProperty("java.io.tmpdir");
|
||||||
|
System.setProperty("java.io.tmpdir", temp.apply("tmpdir").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@SuppressForbidden(reason = "resets java.io.tmpdir")
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
System.setProperty("java.io.tmpdir", javaIoTmpdir);
|
||||||
|
PathUtilsForTesting.teardown();
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersFactory
|
||||||
|
public static Iterable<Object[]> parameters() {
|
||||||
|
class Parameter {
|
||||||
|
private final FileSystem fileSystem;
|
||||||
|
private final Function<String, Path> temp;
|
||||||
|
|
||||||
|
public Parameter(FileSystem fileSystem, String root) {
|
||||||
|
this(fileSystem, s -> {
|
||||||
|
try {
|
||||||
|
return Files.createTempDirectory(fileSystem.getPath(root), s);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Parameter(FileSystem fileSystem, Function<String, Path> temp) {
|
||||||
|
this.fileSystem = fileSystem;
|
||||||
|
this.temp = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Parameter> parameters = new ArrayList<>();
|
||||||
|
parameters.add(new Parameter(Jimfs.newFileSystem(Configuration.windows()), "c:\\"));
|
||||||
|
parameters.add(new Parameter(Jimfs.newFileSystem(toPosix(Configuration.osX())), "/"));
|
||||||
|
parameters.add(new Parameter(Jimfs.newFileSystem(toPosix(Configuration.unix())), "/"));
|
||||||
|
parameters.add(new Parameter(PathUtils.getDefaultFileSystem(), LuceneTestCase::createTempDir ));
|
||||||
|
return parameters.stream().map(p -> new Object[] { p.fileSystem, p.temp }).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Configuration toPosix(Configuration configuration) {
|
||||||
|
return configuration.toBuilder().setAttributeViews("basic", "owner", "posix", "unix").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a test environment with bin, config and plugins directories. */
|
/** Creates a test environment with bin, config and plugins directories. */
|
||||||
static Environment createEnv() throws IOException {
|
static Environment createEnv(FileSystem fs, Function<String, Path> temp) throws IOException {
|
||||||
Path home = createTempDir();
|
Path home = temp.apply("install-plugin-command-tests");
|
||||||
Files.createDirectories(home.resolve("bin"));
|
Files.createDirectories(home.resolve("bin"));
|
||||||
Files.createFile(home.resolve("bin").resolve("elasticsearch"));
|
Files.createFile(home.resolve("bin").resolve("elasticsearch"));
|
||||||
Files.createDirectories(home.resolve("config"));
|
Files.createDirectories(home.resolve("config"));
|
||||||
Files.createFile(home.resolve("config").resolve("elasticsearch.yml"));
|
Files.createFile(home.resolve("config").resolve("elasticsearch.yml"));
|
||||||
Files.createDirectories(home.resolve("plugins"));
|
Path plugins = Files.createDirectories(home.resolve("plugins"));
|
||||||
|
assertTrue(Files.exists(plugins));
|
||||||
Settings settings = Settings.builder()
|
Settings settings = Settings.builder()
|
||||||
.put("path.home", home)
|
.put("path.home", home)
|
||||||
.build();
|
.build();
|
||||||
return new Environment(settings);
|
return new Environment(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Path createPluginDir(Function<String, Path> temp) throws IOException {
|
||||||
|
return temp.apply("pluginDir");
|
||||||
|
}
|
||||||
|
|
||||||
/** creates a fake jar file with empty class files */
|
/** creates a fake jar file with empty class files */
|
||||||
static void writeJar(Path jar, String... classes) throws IOException {
|
static void writeJar(Path jar, String... classes) throws IOException {
|
||||||
try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(jar))) {
|
try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(jar))) {
|
||||||
|
@ -115,14 +186,40 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
static MockTerminal installPlugin(String pluginUrl, Environment env) throws Exception {
|
static MockTerminal installPlugin(String pluginUrl, Environment env) throws Exception {
|
||||||
|
return installPlugin(pluginUrl, env, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MockTerminal installPlugin(String pluginUrl, Environment env, boolean jarHellCheck) throws Exception {
|
||||||
MockTerminal terminal = new MockTerminal();
|
MockTerminal terminal = new MockTerminal();
|
||||||
new InstallPluginCommand(env).execute(terminal, pluginUrl, true);
|
new InstallPluginCommand(env) {
|
||||||
|
@Override
|
||||||
|
void jarHellCheck(Path candidate, Path pluginsDir, boolean isolated) throws Exception {
|
||||||
|
if (jarHellCheck) {
|
||||||
|
super.jarHellCheck(candidate, pluginsDir, isolated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.execute(terminal, pluginUrl, true);
|
||||||
return terminal;
|
return terminal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assertPlugin(String name, Path original, Environment env) throws IOException {
|
void assertPlugin(String name, Path original, Environment env) throws IOException {
|
||||||
Path got = env.pluginsFile().resolve(name);
|
Path got = env.pluginsFile().resolve(name);
|
||||||
assertTrue("dir " + name + " exists", Files.exists(got));
|
assertTrue("dir " + name + " exists", Files.exists(got));
|
||||||
|
|
||||||
|
if (isPosix) {
|
||||||
|
Set<PosixFilePermission> perms = Files.getPosixFilePermissions(got);
|
||||||
|
assertThat(
|
||||||
|
perms,
|
||||||
|
containsInAnyOrder(
|
||||||
|
PosixFilePermission.OWNER_READ,
|
||||||
|
PosixFilePermission.OWNER_WRITE,
|
||||||
|
PosixFilePermission.OWNER_EXECUTE,
|
||||||
|
PosixFilePermission.GROUP_READ,
|
||||||
|
PosixFilePermission.GROUP_EXECUTE,
|
||||||
|
PosixFilePermission.OTHERS_READ,
|
||||||
|
PosixFilePermission.OTHERS_EXECUTE));
|
||||||
|
}
|
||||||
|
|
||||||
assertTrue("jar was copied", Files.exists(got.resolve("plugin.jar")));
|
assertTrue("jar was copied", Files.exists(got.resolve("plugin.jar")));
|
||||||
assertFalse("bin was not copied", Files.exists(got.resolve("bin")));
|
assertFalse("bin was not copied", Files.exists(got.resolve("bin")));
|
||||||
assertFalse("config was not copied", Files.exists(got.resolve("config")));
|
assertFalse("config was not copied", Files.exists(got.resolve("config")));
|
||||||
|
@ -152,6 +249,16 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
Path configDir = env.configFile().resolve(name);
|
Path configDir = env.configFile().resolve(name);
|
||||||
assertTrue("config dir exists", Files.exists(configDir));
|
assertTrue("config dir exists", Files.exists(configDir));
|
||||||
assertTrue("config is a dir", Files.isDirectory(configDir));
|
assertTrue("config is a dir", Files.isDirectory(configDir));
|
||||||
|
|
||||||
|
if (isPosix) {
|
||||||
|
Path configRoot = env.configFile();
|
||||||
|
PosixFileAttributes configAttributes =
|
||||||
|
Files.getFileAttributeView(configRoot, PosixFileAttributeView.class).readAttributes();
|
||||||
|
PosixFileAttributes attributes = Files.getFileAttributeView(configDir, PosixFileAttributeView.class).readAttributes();
|
||||||
|
assertThat(attributes.owner(), equalTo(configAttributes.owner()));
|
||||||
|
assertThat(attributes.group(), equalTo(configAttributes.group()));
|
||||||
|
}
|
||||||
|
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(configDir)) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(configDir)) {
|
||||||
for (Path file : stream) {
|
for (Path file : stream) {
|
||||||
assertFalse("not a dir", Files.isDirectory(file));
|
assertFalse("not a dir", Files.isDirectory(file));
|
||||||
|
@ -172,16 +279,16 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSomethingWorks() throws Exception {
|
public void testSomethingWorks() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPlugin("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env);
|
installPlugin(pluginZip, env);
|
||||||
assertPlugin("fake", pluginDir, env);
|
assertPlugin("fake", pluginDir, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSpaceInUrl() throws Exception {
|
public void testSpaceInUrl() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPlugin("fake", pluginDir);
|
||||||
Path pluginZipWithSpaces = createTempFile("foo bar", ".zip");
|
Path pluginZipWithSpaces = createTempFile("foo bar", ".zip");
|
||||||
try (InputStream in = new URL(pluginZip).openStream()) {
|
try (InputStream in = new URL(pluginZip).openStream()) {
|
||||||
|
@ -192,28 +299,30 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMalformedUrlNotMaven() throws Exception {
|
public void testMalformedUrlNotMaven() throws Exception {
|
||||||
|
Environment env = createEnv(fs, temp);
|
||||||
// has two colons, so it appears similar to maven coordinates
|
// has two colons, so it appears similar to maven coordinates
|
||||||
MalformedURLException e = expectThrows(MalformedURLException.class, () -> {
|
MalformedURLException e = expectThrows(MalformedURLException.class, () -> {
|
||||||
installPlugin("://host:1234", createEnv());
|
installPlugin("://host:1234", env);
|
||||||
});
|
});
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("no protocol"));
|
assertTrue(e.getMessage(), e.getMessage().contains("no protocol"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPluginsDirMissing() throws Exception {
|
public void testPluginsDirMissing() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Files.delete(env.pluginsFile());
|
Files.delete(env.pluginsFile());
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPlugin("fake", pluginDir);
|
String pluginZip = createPlugin("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env);
|
installPlugin(pluginZip, env);
|
||||||
assertPlugin("fake", pluginDir, env);
|
assertPlugin("fake", pluginDir, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPluginsDirReadOnly() throws Exception {
|
public void testPluginsDirReadOnly() throws Exception {
|
||||||
assumeTrue("posix filesystem", isPosix);
|
assumeTrue("posix and filesystem", isPosix && isReal);
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
|
Path pluginDir = createPluginDir(temp);
|
||||||
try (PosixPermissionsResetter pluginsAttrs = new PosixPermissionsResetter(env.pluginsFile())) {
|
try (PosixPermissionsResetter pluginsAttrs = new PosixPermissionsResetter(env.pluginsFile())) {
|
||||||
pluginsAttrs.setPermissions(new HashSet<>());
|
pluginsAttrs.setPermissions(new HashSet<>());
|
||||||
String pluginZip = createPlugin("fake", createTempDir());
|
String pluginZip = createPlugin("fake", pluginDir);
|
||||||
IOException e = expectThrows(IOException.class, () -> {
|
IOException e = expectThrows(IOException.class, () -> {
|
||||||
installPlugin(pluginZip, env);
|
installPlugin(pluginZip, env);
|
||||||
});
|
});
|
||||||
|
@ -223,8 +332,9 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBuiltinModule() throws Exception {
|
public void testBuiltinModule() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
String pluginZip = createPlugin("lang-groovy", createTempDir());
|
Path pluginDir = createPluginDir(temp);
|
||||||
|
String pluginZip = createPlugin("lang-groovy", pluginDir);
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
installPlugin(pluginZip, env);
|
installPlugin(pluginZip, env);
|
||||||
});
|
});
|
||||||
|
@ -233,24 +343,26 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testJarHell() throws Exception {
|
public void testJarHell() throws Exception {
|
||||||
Environment env = createEnv();
|
// jar hell test needs a real filesystem
|
||||||
Path pluginDir = createTempDir();
|
assumeTrue("real filesystem", isReal);
|
||||||
writeJar(pluginDir.resolve("other.jar"), "FakePlugin");
|
Environment environment = createEnv(fs, temp);
|
||||||
String pluginZip = createPlugin("fake", pluginDir); // adds plugin.jar with FakePlugin
|
Path pluginDirectory = createPluginDir(temp);
|
||||||
|
writeJar(pluginDirectory.resolve("other.jar"), "FakePlugin");
|
||||||
|
String pluginZip = createPlugin("fake", pluginDirectory); // adds plugin.jar with FakePlugin
|
||||||
IllegalStateException e = expectThrows(IllegalStateException.class, () -> {
|
IllegalStateException e = expectThrows(IllegalStateException.class, () -> {
|
||||||
installPlugin(pluginZip, env);
|
installPlugin(pluginZip, environment, true);
|
||||||
});
|
});
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("jar hell"));
|
assertTrue(e.getMessage(), e.getMessage().contains("jar hell"));
|
||||||
assertInstallCleaned(env);
|
assertInstallCleaned(environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIsolatedPlugins() throws Exception {
|
public void testIsolatedPlugins() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
// these both share the same FakePlugin class
|
// these both share the same FakePlugin class
|
||||||
Path pluginDir1 = createTempDir();
|
Path pluginDir1 = createPluginDir(temp);
|
||||||
String pluginZip1 = createPlugin("fake1", pluginDir1);
|
String pluginZip1 = createPlugin("fake1", pluginDir1);
|
||||||
installPlugin(pluginZip1, env);
|
installPlugin(pluginZip1, env);
|
||||||
Path pluginDir2 = createTempDir();
|
Path pluginDir2 = createPluginDir(temp);
|
||||||
String pluginZip2 = createPlugin("fake2", pluginDir2);
|
String pluginZip2 = createPlugin("fake2", pluginDir2);
|
||||||
installPlugin(pluginZip2, env);
|
installPlugin(pluginZip2, env);
|
||||||
assertPlugin("fake1", pluginDir1, env);
|
assertPlugin("fake1", pluginDir1, env);
|
||||||
|
@ -258,8 +370,9 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPurgatoryJarHell() throws Exception {
|
public void testPurgatoryJarHell() throws Exception {
|
||||||
Environment env = createEnv();
|
assumeTrue("real filesystem", isReal);
|
||||||
Path pluginDir1 = createTempDir();
|
Environment environment = createEnv(fs, temp);
|
||||||
|
Path pluginDir1 = createPluginDir(temp);
|
||||||
PluginTestUtil.writeProperties(pluginDir1,
|
PluginTestUtil.writeProperties(pluginDir1,
|
||||||
"description", "fake desc",
|
"description", "fake desc",
|
||||||
"name", "fake1",
|
"name", "fake1",
|
||||||
|
@ -270,9 +383,9 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
"isolated", "false");
|
"isolated", "false");
|
||||||
writeJar(pluginDir1.resolve("plugin.jar"), "FakePlugin");
|
writeJar(pluginDir1.resolve("plugin.jar"), "FakePlugin");
|
||||||
String pluginZip1 = writeZip(pluginDir1, "elasticsearch");
|
String pluginZip1 = writeZip(pluginDir1, "elasticsearch");
|
||||||
installPlugin(pluginZip1, env);
|
installPlugin(pluginZip1, environment);
|
||||||
|
|
||||||
Path pluginDir2 = createTempDir();
|
Path pluginDir2 = createPluginDir(temp);
|
||||||
PluginTestUtil.writeProperties(pluginDir2,
|
PluginTestUtil.writeProperties(pluginDir2,
|
||||||
"description", "fake desc",
|
"description", "fake desc",
|
||||||
"name", "fake2",
|
"name", "fake2",
|
||||||
|
@ -284,15 +397,16 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
writeJar(pluginDir2.resolve("plugin.jar"), "FakePlugin");
|
writeJar(pluginDir2.resolve("plugin.jar"), "FakePlugin");
|
||||||
String pluginZip2 = writeZip(pluginDir2, "elasticsearch");
|
String pluginZip2 = writeZip(pluginDir2, "elasticsearch");
|
||||||
IllegalStateException e = expectThrows(IllegalStateException.class, () -> {
|
IllegalStateException e = expectThrows(IllegalStateException.class, () -> {
|
||||||
installPlugin(pluginZip2, env);
|
installPlugin(pluginZip2, environment, true);
|
||||||
});
|
});
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("jar hell"));
|
assertTrue(e.getMessage(), e.getMessage().contains("jar hell"));
|
||||||
assertInstallCleaned(env);
|
assertInstallCleaned(environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExistingPlugin() throws Exception {
|
public void testExistingPlugin() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
String pluginZip = createPlugin("fake", createTempDir());
|
Path pluginDir = createPluginDir(temp);
|
||||||
|
String pluginZip = createPlugin("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env);
|
installPlugin(pluginZip, env);
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
installPlugin(pluginZip, env);
|
installPlugin(pluginZip, env);
|
||||||
|
@ -302,8 +416,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBin() throws Exception {
|
public void testBin() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
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"));
|
||||||
|
@ -313,8 +427,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBinNotDir() throws Exception {
|
public void testBinNotDir() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
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 = createPlugin("fake", pluginDir);
|
||||||
|
@ -326,8 +440,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBinContainsDir() throws Exception {
|
public void testBinContainsDir() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
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"));
|
||||||
|
@ -340,8 +454,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBinConflict() throws Exception {
|
public void testBinConflict() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
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"));
|
||||||
|
@ -355,8 +469,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
|
|
||||||
public void testBinPermissions() throws Exception {
|
public void testBinPermissions() throws Exception {
|
||||||
assumeTrue("posix filesystem", isPosix);
|
assumeTrue("posix filesystem", isPosix);
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
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"));
|
||||||
|
@ -372,8 +486,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConfig() throws Exception {
|
public void testConfig() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
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"));
|
||||||
|
@ -383,11 +497,11 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExistingConfig() throws Exception {
|
public void testExistingConfig() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path envConfigDir = env.configFile().resolve("fake");
|
Path envConfigDir = env.configFile().resolve("fake");
|
||||||
Files.createDirectories(envConfigDir);
|
Files.createDirectories(envConfigDir);
|
||||||
Files.write(envConfigDir.resolve("custom.yaml"), "existing config".getBytes(StandardCharsets.UTF_8));
|
Files.write(envConfigDir.resolve("custom.yaml"), "existing config".getBytes(StandardCharsets.UTF_8));
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
Path configDir = pluginDir.resolve("config");
|
Path configDir = pluginDir.resolve("config");
|
||||||
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));
|
||||||
|
@ -402,8 +516,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConfigNotDir() throws Exception {
|
public void testConfigNotDir() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
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 = createPlugin("fake", pluginDir);
|
||||||
|
@ -415,8 +529,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConfigContainsDir() throws Exception {
|
public void testConfigContainsDir() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
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"));
|
||||||
|
@ -429,8 +543,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConfigConflict() throws Exception {
|
public void testConfigConflict() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
Path pluginDir = createPluginDir(temp);
|
||||||
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"));
|
||||||
|
@ -443,8 +557,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMissingDescriptor() throws Exception {
|
public void testMissingDescriptor() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
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");
|
||||||
NoSuchFileException e = expectThrows(NoSuchFileException.class, () -> {
|
NoSuchFileException e = expectThrows(NoSuchFileException.class, () -> {
|
||||||
|
@ -455,8 +569,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMissingDirectory() throws Exception {
|
public void testMissingDirectory() throws Exception {
|
||||||
Environment env = createEnv();
|
Environment env = createEnv(fs, temp);
|
||||||
Path pluginDir = createTempDir();
|
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);
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
|
@ -467,13 +581,14 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testZipRelativeOutsideEntryName() throws Exception {
|
public void testZipRelativeOutsideEntryName() throws Exception {
|
||||||
|
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("elasticsearch/../blah"));
|
||||||
}
|
}
|
||||||
String pluginZip = zip.toUri().toURL().toString();
|
String pluginZip = zip.toUri().toURL().toString();
|
||||||
IOException e = expectThrows(IOException.class, () -> {
|
IOException e = expectThrows(IOException.class, () -> {
|
||||||
installPlugin(pluginZip, createEnv());
|
installPlugin(pluginZip, env);
|
||||||
});
|
});
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("resolving outside of plugin directory"));
|
assertTrue(e.getMessage(), e.getMessage().contains("resolving outside of plugin directory"));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue