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:
parent
4f644d04a3
commit
4216fc9f64
|
@ -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,32 +119,34 @@ 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,
|
||||
"description", "test_plugin",
|
||||
"version", Version.CURRENT.toString(),
|
||||
"elasticsearch.version", Version.CURRENT.toString(),
|
||||
"name", "test_plugin",
|
||||
"java.version", "1.8",
|
||||
"classname", "TestPlugin",
|
||||
"has.native.controller", "true");
|
||||
plugin,
|
||||
"description", "test_plugin",
|
||||
"version", Version.CURRENT.toString(),
|
||||
"elasticsearch.version", Version.CURRENT.toString(),
|
||||
"name", "test_plugin",
|
||||
"java.version", "1.8",
|
||||
"classname", "TestPlugin",
|
||||
"has.native.controller", "true");
|
||||
Path controllerProgram = Platforms.nativeControllerPath(plugin);
|
||||
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,
|
||||
"description", "other_plugin",
|
||||
"version", Version.CURRENT.toString(),
|
||||
"elasticsearch.version", Version.CURRENT.toString(),
|
||||
"name", "other_plugin",
|
||||
"java.version", "1.8",
|
||||
"classname", "OtherPlugin",
|
||||
"has.native.controller", "false");
|
||||
otherPlugin,
|
||||
"description", "other_plugin",
|
||||
"version", Version.CURRENT.toString(),
|
||||
"elasticsearch.version", Version.CURRENT.toString(),
|
||||
"name", "other_plugin",
|
||||
"java.version", "1.8",
|
||||
"classname", "OtherPlugin",
|
||||
"has.native.controller", "false");
|
||||
|
||||
Spawner spawner = new Spawner();
|
||||
spawner.spawnNativePluginControllers(environment);
|
||||
|
@ -150,7 +159,7 @@ public class SpawnerNoBootstrapTests extends LuceneTestCase {
|
|||
assertThat(processes, hasSize(1));
|
||||
Process process = processes.get(0);
|
||||
final InputStreamReader in =
|
||||
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8);
|
||||
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8);
|
||||
try (BufferedReader stdoutReader = new BufferedReader(in)) {
|
||||
String line = stdoutReader.readLine();
|
||||
assertEquals("I am alive", line);
|
||||
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue