Plugins: Allow modules to spawn controllers (#28968)

This commit makes the controller spawner also look under modules. It
also fixes a bug in module security policy loading where the module is a
meta plugin.
This commit is contained in:
Ryan Ernst 2018-03-11 09:01:27 -07:00 committed by GitHub
parent 4f644d04a3
commit 4216fc9f64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 35 deletions

View File

@ -42,6 +42,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
@ -77,6 +78,7 @@ public class SpawnerNoBootstrapTests extends LuceneTestCase {
// This plugin will NOT have a controller daemon
Path plugin = environment.pluginsFile().resolve("a_plugin");
Files.createDirectories(environment.modulesFile());
Files.createDirectories(plugin);
PluginTestUtil.writePluginProperties(
plugin,
@ -97,7 +99,12 @@ public class SpawnerNoBootstrapTests extends LuceneTestCase {
/**
* Two plugins - one with a controller daemon and one without.
*/
public void testControllerSpawn() throws IOException, InterruptedException {
public void testControllerSpawn() throws Exception {
assertControllerSpawns(Environment::pluginsFile);
assertControllerSpawns(Environment::modulesFile);
}
private void assertControllerSpawns(Function<Environment, Path> pluginsDirFinder) throws Exception {
/*
* On Windows you can not directly run a batch file - you have to run cmd.exe with the batch
* file as an argument and that's out of the remit of the controller daemon process spawner.
@ -112,7 +119,9 @@ public class SpawnerNoBootstrapTests extends LuceneTestCase {
Environment environment = TestEnvironment.newEnvironment(settings);
// this plugin will have a controller daemon
Path plugin = environment.pluginsFile().resolve("test_plugin");
Path plugin = pluginsDirFinder.apply(environment).resolve("test_plugin");
Files.createDirectories(environment.modulesFile());
Files.createDirectories(environment.pluginsFile());
Files.createDirectories(plugin);
PluginTestUtil.writePluginProperties(
plugin,
@ -127,7 +136,7 @@ public class SpawnerNoBootstrapTests extends LuceneTestCase {
createControllerProgram(controllerProgram);
// this plugin will not have a controller daemon
Path otherPlugin = environment.pluginsFile().resolve("other_plugin");
Path otherPlugin = pluginsDirFinder.apply(environment).resolve("other_plugin");
Files.createDirectories(otherPlugin);
PluginTestUtil.writePluginProperties(
otherPlugin,
@ -181,6 +190,7 @@ public class SpawnerNoBootstrapTests extends LuceneTestCase {
Environment environment = TestEnvironment.newEnvironment(settings);
Path metaPlugin = environment.pluginsFile().resolve("meta_plugin");
Files.createDirectories(environment.modulesFile());
Files.createDirectories(metaPlugin);
PluginTestUtil.writeMetaPluginProperties(
metaPlugin,
@ -279,6 +289,7 @@ public class SpawnerNoBootstrapTests extends LuceneTestCase {
final Environment environment = TestEnvironment.newEnvironment(settings);
Files.createDirectories(environment.modulesFile());
Files.createDirectories(environment.pluginsFile());
final Path desktopServicesStore = environment.pluginsFile().resolve(".DS_Store");

View File

@ -163,16 +163,8 @@ final class Security {
Map<String,Policy> map = new HashMap<>();
// collect up set of plugins and modules by listing directories.
Set<Path> pluginsAndModules = new LinkedHashSet<>(PluginsService.findPluginDirs(environment.pluginsFile()));
pluginsAndModules.addAll(PluginsService.findPluginDirs(environment.modulesFile()));
if (Files.exists(environment.modulesFile())) {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(environment.modulesFile())) {
for (Path module : stream) {
if (pluginsAndModules.add(module) == false) {
throw new IllegalStateException("duplicate module: " + module);
}
}
}
}
// now process each one
for (Path plugin : pluginsAndModules) {
Path policyFile = plugin.resolve(PluginInfo.ES_PLUGIN_POLICY);

View File

@ -63,15 +63,20 @@ final class Spawner implements Closeable {
if (!spawned.compareAndSet(false, true)) {
throw new IllegalStateException("native controllers already spawned");
}
final Path pluginsFile = environment.pluginsFile();
if (!Files.exists(pluginsFile)) {
throw new IllegalStateException("plugins directory [" + pluginsFile + "] not found");
spawnControllers(environment.pluginsFile(), "plugins", environment.tmpFile());
spawnControllers(environment.modulesFile(), "modules", environment.tmpFile());
}
/** Spawn controllers in plugins found within the given directory. */
private void spawnControllers(Path pluginsDir, String type, Path tmpDir) throws IOException {
if (!Files.exists(pluginsDir)) {
throw new IllegalStateException(type + " directory [" + pluginsDir + "] not found");
}
/*
* For each plugin, attempt to spawn the controller daemon. Silently ignore any plugin that
* don't include a controller for the correct platform.
*/
List<Path> paths = PluginsService.findPluginDirs(pluginsFile);
List<Path> paths = PluginsService.findPluginDirs(pluginsDir);
for (Path plugin : paths) {
final PluginInfo info = PluginInfo.readFromProperties(plugin);
final Path spawnPath = Platforms.nativeControllerPath(plugin);
@ -85,8 +90,7 @@ final class Spawner implements Closeable {
plugin.getFileName());
throw new IllegalArgumentException(message);
}
final Process process =
spawnNativePluginController(spawnPath, environment.tmpFile());
final Process process = spawnNativePluginController(spawnPath, tmpDir);
processes.add(process);
}
}