Added logic to allow {dot} files on startup (#1437)
* Added logic to allow {dot} files on startup Signed-off-by: Ryan Bogan <rbogan@amazon.com> * Ensures that only plugin directories are returned by findPluginDirs() Signed-off-by: Ryan Bogan <rbogan@amazon.com> * Prevents . files from being returned as plugins Signed-off-by: Ryan Bogan <rbogan@amazon.com>
This commit is contained in:
parent
f54cc382d5
commit
286121f0dc
|
@ -215,33 +215,6 @@ public class SpawnerNoBootstrapTests extends LuceneTestCase {
|
||||||
equalTo("module [test_plugin] does not have permission to fork native controller"));
|
equalTo("module [test_plugin] does not have permission to fork native controller"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSpawnerHandlingOfDesktopServicesStoreFiles() throws IOException {
|
|
||||||
final Path esHome = createTempDir().resolve("home");
|
|
||||||
final Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), esHome.toString()).build();
|
|
||||||
|
|
||||||
final Environment environment = TestEnvironment.newEnvironment(settings);
|
|
||||||
|
|
||||||
Files.createDirectories(environment.modulesFile());
|
|
||||||
Files.createDirectories(environment.pluginsFile());
|
|
||||||
|
|
||||||
final Path desktopServicesStore = environment.modulesFile().resolve(".DS_Store");
|
|
||||||
Files.createFile(desktopServicesStore);
|
|
||||||
|
|
||||||
final Spawner spawner = new Spawner();
|
|
||||||
if (Constants.MAC_OS_X) {
|
|
||||||
// if the spawner were not skipping the Desktop Services Store files on macOS this would explode
|
|
||||||
spawner.spawnNativeControllers(environment, false);
|
|
||||||
} else {
|
|
||||||
// we do not ignore these files on non-macOS systems
|
|
||||||
final FileSystemException e = expectThrows(FileSystemException.class, () -> spawner.spawnNativeControllers(environment, false));
|
|
||||||
if (Constants.WINDOWS) {
|
|
||||||
assertThat(e, instanceOf(NoSuchFileException.class));
|
|
||||||
} else {
|
|
||||||
assertThat(e, hasToString(containsString("Not a directory")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createControllerProgram(final Path outputFile) throws IOException {
|
private void createControllerProgram(final Path outputFile) throws IOException {
|
||||||
final Path outputDir = outputFile.getParent();
|
final Path outputDir = outputFile.getParent();
|
||||||
Files.createDirectories(outputDir);
|
Files.createDirectories(outputDir);
|
||||||
|
|
|
@ -50,7 +50,6 @@ import org.opensearch.common.Strings;
|
||||||
import org.opensearch.common.collect.Tuple;
|
import org.opensearch.common.collect.Tuple;
|
||||||
import org.opensearch.common.component.LifecycleComponent;
|
import org.opensearch.common.component.LifecycleComponent;
|
||||||
import org.opensearch.common.inject.Module;
|
import org.opensearch.common.inject.Module;
|
||||||
import org.opensearch.common.io.FileSystemUtils;
|
|
||||||
import org.opensearch.common.settings.Setting;
|
import org.opensearch.common.settings.Setting;
|
||||||
import org.opensearch.common.settings.Setting.Property;
|
import org.opensearch.common.settings.Setting.Property;
|
||||||
import org.opensearch.common.settings.Settings;
|
import org.opensearch.common.settings.Settings;
|
||||||
|
@ -365,7 +364,10 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
|
||||||
if (Files.exists(rootPath)) {
|
if (Files.exists(rootPath)) {
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(rootPath)) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(rootPath)) {
|
||||||
for (Path plugin : stream) {
|
for (Path plugin : stream) {
|
||||||
if (FileSystemUtils.isDesktopServicesStore(plugin) || plugin.getFileName().toString().startsWith(".removing-")) {
|
if (plugin.getFileName().toString().startsWith(".") && !Files.isDirectory(plugin)) {
|
||||||
|
logger.warn(
|
||||||
|
"Non-plugin file located in the plugins folder with the following name: [" + plugin.getFileName() + "]"
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (seen.add(plugin.getFileName().toString()) == false) {
|
if (seen.add(plugin.getFileName().toString()) == false) {
|
||||||
|
|
|
@ -32,7 +32,10 @@
|
||||||
|
|
||||||
package org.opensearch.plugins;
|
package org.opensearch.plugins;
|
||||||
|
|
||||||
|
import org.opensearch.common.logging.Loggers;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.lucene.util.Constants;
|
import org.apache.lucene.util.Constants;
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
import org.opensearch.LegacyESVersion;
|
import org.opensearch.LegacyESVersion;
|
||||||
|
@ -44,6 +47,7 @@ import org.opensearch.common.settings.Settings;
|
||||||
import org.opensearch.env.Environment;
|
import org.opensearch.env.Environment;
|
||||||
import org.opensearch.env.TestEnvironment;
|
import org.opensearch.env.TestEnvironment;
|
||||||
import org.opensearch.index.IndexModule;
|
import org.opensearch.index.IndexModule;
|
||||||
|
import org.opensearch.test.MockLogAppender;
|
||||||
import org.opensearch.test.OpenSearchTestCase;
|
import org.opensearch.test.OpenSearchTestCase;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
|
||||||
|
@ -51,9 +55,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.FileSystemException;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.NoSuchFileException;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -154,50 +156,17 @@ public class PluginsServiceTests extends OpenSearchTestCase {
|
||||||
assertEquals(FilterablePlugin.class, scriptPlugins.get(0).getClass());
|
assertEquals(FilterablePlugin.class, scriptPlugins.get(0).getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHiddenFiles() throws IOException {
|
public void testHiddenDirectories() throws IOException {
|
||||||
final Path home = createTempDir();
|
final Path home = createTempDir();
|
||||||
final Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), home).build();
|
final Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), home).build();
|
||||||
final Path hidden = home.resolve("plugins").resolve(".hidden");
|
final Path hidden = home.resolve("plugins").resolve(".hidden");
|
||||||
Files.createDirectories(hidden);
|
Files.createDirectories(hidden);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final IllegalStateException e = expectThrows(IllegalStateException.class, () -> newPluginsService(settings));
|
final IllegalStateException e = expectThrows(IllegalStateException.class, () -> newPluginsService(settings));
|
||||||
|
|
||||||
final String expected = "Could not load plugin descriptor for plugin directory [.hidden]";
|
final String expected = "Could not load plugin descriptor for plugin directory [.hidden]";
|
||||||
assertThat(e, hasToString(containsString(expected)));
|
assertThat(e, hasToString(containsString(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDesktopServicesStoreFiles() throws IOException {
|
|
||||||
final Path home = createTempDir();
|
|
||||||
final Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), home).build();
|
|
||||||
final Path plugins = home.resolve("plugins");
|
|
||||||
Files.createDirectories(plugins);
|
|
||||||
final Path desktopServicesStore = plugins.resolve(".DS_Store");
|
|
||||||
Files.createFile(desktopServicesStore);
|
|
||||||
if (Constants.MAC_OS_X) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
final PluginsService pluginsService = newPluginsService(settings);
|
|
||||||
assertNotNull(pluginsService);
|
|
||||||
} else {
|
|
||||||
final IllegalStateException e = expectThrows(IllegalStateException.class, () -> newPluginsService(settings));
|
|
||||||
assertThat(e.getMessage(), containsString("Could not load plugin descriptor for plugin directory [.DS_Store]"));
|
|
||||||
assertNotNull(e.getCause());
|
|
||||||
assertThat(e.getCause(), instanceOf(FileSystemException.class));
|
|
||||||
if (Constants.WINDOWS) {
|
|
||||||
assertThat(e.getCause(), instanceOf(NoSuchFileException.class));
|
|
||||||
} else {
|
|
||||||
// force a "Not a directory" exception to be thrown so that we can extract the locale-dependent message
|
|
||||||
final String expected;
|
|
||||||
try (InputStream ignored = Files.newInputStream(desktopServicesStore.resolve("not-a-directory"))) {
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (final FileSystemException inner) {
|
|
||||||
// locale-dependent translation of "Not a directory"
|
|
||||||
expected = inner.getReason();
|
|
||||||
}
|
|
||||||
assertThat(e.getCause(), hasToString(containsString(expected)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testStartupWithRemovingMarker() throws IOException {
|
public void testStartupWithRemovingMarker() throws IOException {
|
||||||
final Path home = createTempDir();
|
final Path home = createTempDir();
|
||||||
final Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), home).build();
|
final Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), home).build();
|
||||||
|
@ -765,10 +734,25 @@ public class PluginsServiceTests extends OpenSearchTestCase {
|
||||||
assertThat(e.getMessage(), containsString("my_plugin requires Java"));
|
assertThat(e.getMessage(), containsString("my_plugin requires Java"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFindPluginDirs() throws IOException {
|
public void testFindPluginDirs() throws Exception {
|
||||||
final Path plugins = createTempDir();
|
final Path plugins = createTempDir();
|
||||||
|
|
||||||
|
final MockLogAppender mockLogAppender = new MockLogAppender();
|
||||||
|
mockLogAppender.start();
|
||||||
|
mockLogAppender.addExpectation(
|
||||||
|
new MockLogAppender.SeenEventExpectation(
|
||||||
|
"[.test] warning",
|
||||||
|
"org.opensearch.plugins.PluginsService",
|
||||||
|
Level.WARN,
|
||||||
|
"Non-plugin file located in the plugins folder with the following name: [.DS_Store]"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
final Logger testLogger = LogManager.getLogger(PluginsService.class);
|
||||||
|
Loggers.addAppender(testLogger, mockLogAppender);
|
||||||
|
|
||||||
final Path fake = plugins.resolve("fake");
|
final Path fake = plugins.resolve("fake");
|
||||||
|
Path testFile = plugins.resolve(".DS_Store");
|
||||||
|
Files.createFile(testFile);
|
||||||
|
|
||||||
PluginTestUtil.writePluginProperties(
|
PluginTestUtil.writePluginProperties(
|
||||||
fake,
|
fake,
|
||||||
|
@ -791,6 +775,7 @@ public class PluginsServiceTests extends OpenSearchTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(PluginsService.findPluginDirs(plugins), containsInAnyOrder(fake));
|
assertThat(PluginsService.findPluginDirs(plugins), containsInAnyOrder(fake));
|
||||||
|
mockLogAppender.assertAllExpectationsMatched();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExistingMandatoryClasspathPlugin() {
|
public void testExistingMandatoryClasspathPlugin() {
|
||||||
|
|
Loading…
Reference in New Issue