Introduce licensed plugins (#65409)

Backport of #64850.

This PR introduces the concept of "licensed" plugins. Such plugins
may only be installed on installations of the default distribution,
and this is enforced by the plugin installer. This PR also moves
the `quote-aware-fs` plugin to the `x-pack` directory, and marks
it as licensed.

Note that I didn't move the plugin source under `x-pack/plugin`
because all the existing x-pack plugins are actually bundles as
modules into the default distribution, whereas the `quota-aware-fs`
plugin needs to remain a standalone plugin.
This commit is contained in:
Rory Hunter 2020-11-24 14:41:43 +00:00 committed by GitHub
parent cb79960d6f
commit a7ccbfa346
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 235 additions and 185 deletions

View file

@ -97,13 +97,14 @@ class PluginBuildPlugin implements Plugin<Project> {
'requiresKeystore' : extension1.requiresKeystore, 'requiresKeystore' : extension1.requiresKeystore,
'type' : extension1.type.toString(), 'type' : extension1.type.toString(),
'javaOpts' : extension1.javaOpts, 'javaOpts' : extension1.javaOpts,
'licensed' : extension1.licensed,
] ]
project.tasks.named('pluginProperties').configure { project.tasks.named('pluginProperties').configure {
expand(properties) expand(properties)
inputs.properties(properties) inputs.properties(properties)
} }
BuildParams.withInternalBuild { BuildParams.withInternalBuild {
boolean isXPackModule = project.path.startsWith(':x-pack:plugin') boolean isXPackModule = project.path.startsWith(':x-pack:plugin') || project.path.startsWith('x-pack:quota-aware-fs')
boolean isModule = project.path.startsWith(':modules:') || isXPackModule boolean isModule = project.path.startsWith(':modules:') || isXPackModule
if (isModule == false || isXPackModule) { if (isModule == false || isXPackModule) {
addNoticeGeneration(project, extension1) addNoticeGeneration(project, extension1)

View file

@ -47,6 +47,9 @@ public class PluginPropertiesExtension {
private String javaOpts = ""; private String javaOpts = "";
/** Whether a license agreement must be accepted before this plugin can be installed. */
private boolean isLicensed = false;
/** True if the plugin requires the elasticsearch keystore to exist, false otherwise. */ /** True if the plugin requires the elasticsearch keystore to exist, false otherwise. */
private boolean requiresKeystore; private boolean requiresKeystore;
@ -127,6 +130,14 @@ public class PluginPropertiesExtension {
this.javaOpts = javaOpts; this.javaOpts = javaOpts;
} }
public boolean isLicensed() {
return isLicensed;
}
public void setLicensed(boolean licensed) {
isLicensed = licensed;
}
public boolean isRequiresKeystore() { public boolean isRequiresKeystore() {
return requiresKeystore; return requiresKeystore;
} }

View file

@ -325,7 +325,7 @@ public class DistroTestPlugin implements Plugin<Project> {
private static Configuration configureQuotaAwareFsPlugin(Project project) { private static Configuration configureQuotaAwareFsPlugin(Project project) {
Configuration examplePlugin = project.getConfigurations().create(QUOTA_AWARE_FS_PLUGIN_CONFIGURATION); Configuration examplePlugin = project.getConfigurations().create(QUOTA_AWARE_FS_PLUGIN_CONFIGURATION);
DependencyHandler deps = project.getDependencies(); DependencyHandler deps = project.getDependencies();
Map<String, String> quotaAwareFsPluginProject = Map.of("path", ":plugins:quota-aware-fs", "configuration", "zip"); Map<String, String> quotaAwareFsPluginProject = Map.of("path", ":x-pack:quota-aware-fs", "configuration", "zip");
deps.add(QUOTA_AWARE_FS_PLUGIN_CONFIGURATION, deps.project(quotaAwareFsPluginProject)); deps.add(QUOTA_AWARE_FS_PLUGIN_CONFIGURATION, deps.project(quotaAwareFsPluginProject));
return examplePlugin; return examplePlugin;
} }

View file

@ -57,3 +57,7 @@ has.native.controller=${hasNativeController}
# Elasticsearch starts. Only applies to "bootstrap" plugins. # Elasticsearch starts. Only applies to "bootstrap" plugins.
java.opts=${javaOpts} java.opts=${javaOpts}
<% } %> <% } %>
<% if (licensed) { %>
# This plugin requires that a license agreement be accepted before installation
licensed=${licensed}
<% } %>

View file

@ -866,6 +866,9 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
private PluginInfo installPlugin(Terminal terminal, boolean isBatch, Path tmpRoot, Environment env, List<Path> deleteOnFailure) private PluginInfo installPlugin(Terminal terminal, boolean isBatch, Path tmpRoot, Environment env, List<Path> deleteOnFailure)
throws Exception { throws Exception {
final PluginInfo info = loadPluginInfo(terminal, tmpRoot, env); final PluginInfo info = loadPluginInfo(terminal, tmpRoot, env);
checkCanInstallationProceed(terminal, Build.CURRENT.flavor(), info);
PluginPolicyInfo pluginPolicy = PolicyUtil.getPluginPolicyInfo(tmpRoot, env.tmpFile()); PluginPolicyInfo pluginPolicy = PolicyUtil.getPluginPolicyInfo(tmpRoot, env.tmpFile());
if (pluginPolicy != null) { if (pluginPolicy != null) {
Set<String> permissions = PluginSecurity.getPermissionDescriptions(pluginPolicy, env.tmpFile()); Set<String> permissions = PluginSecurity.getPermissionDescriptions(pluginPolicy, env.tmpFile());
@ -1019,4 +1022,24 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
IOUtils.rm(pathsToDeleteOnShutdown.toArray(new Path[pathsToDeleteOnShutdown.size()])); IOUtils.rm(pathsToDeleteOnShutdown.toArray(new Path[pathsToDeleteOnShutdown.size()]));
} }
static void checkCanInstallationProceed(Terminal terminal, Build.Flavor flavor, PluginInfo info) throws Exception {
if (info.isLicensed() == false) {
return;
}
if (flavor == Build.Flavor.DEFAULT) {
return;
}
Arrays.asList(
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@ ERROR: This is a licensed plugin @",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"",
"This plugin is covered by the Elastic license, but this",
"installation of Elasticsearch is: [" + flavor + "]."
).forEach(terminal::errorPrintln);
throw new UserException(ExitCodes.NOPERM, "Plugin license is incompatible with [" + flavor + "] installation");
}
} }

View file

@ -0,0 +1,97 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.plugins;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import java.util.Collections;
import org.elasticsearch.Build;
import org.elasticsearch.Version;
import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.MockTerminal;
import org.elasticsearch.cli.UserException;
import org.elasticsearch.test.ESTestCase;
public class InstallLicensedPluginTests extends ESTestCase {
/**
* Check that an unlicensed plugin is accepted.
*/
public void testUnlicensedPlugin() throws Exception {
MockTerminal terminal = new MockTerminal();
PluginInfo pluginInfo = buildInfo(false);
InstallPluginCommand.checkCanInstallationProceed(terminal, Build.Flavor.OSS, pluginInfo);
}
/**
* Check that a licensed plugin cannot be installed on OSS.
*/
public void testInstallPluginCommandOnOss() throws Exception {
MockTerminal terminal = new MockTerminal();
PluginInfo pluginInfo = buildInfo(true);
final UserException userException = expectThrows(
UserException.class,
() -> InstallPluginCommand.checkCanInstallationProceed(terminal, Build.Flavor.OSS, pluginInfo)
);
assertThat(userException.exitCode, equalTo(ExitCodes.NOPERM));
assertThat(terminal.getErrorOutput(), containsString("ERROR: This is a licensed plugin"));
}
/**
* Check that a licensed plugin cannot be installed when the distribution type is unknown.
*/
public void testInstallPluginCommandOnUnknownDistribution() throws Exception {
MockTerminal terminal = new MockTerminal();
PluginInfo pluginInfo = buildInfo(true);
expectThrows(
UserException.class,
() -> InstallPluginCommand.checkCanInstallationProceed(terminal, Build.Flavor.UNKNOWN, pluginInfo)
);
assertThat(terminal.getErrorOutput(), containsString("ERROR: This is a licensed plugin"));
}
/**
* Check that a licensed plugin can be installed when the distribution type is default.
*/
public void testInstallPluginCommandOnDefault() throws Exception {
MockTerminal terminal = new MockTerminal();
PluginInfo pluginInfo = buildInfo(true);
InstallPluginCommand.checkCanInstallationProceed(terminal, Build.Flavor.DEFAULT, pluginInfo);
}
private PluginInfo buildInfo(boolean isLicensed) {
return new PluginInfo(
"name",
"description",
"version",
Version.CURRENT,
"java version",
"classname",
Collections.emptyList(),
false,
PluginType.ISOLATED,
"",
isLicensed
);
}
}

View file

@ -890,14 +890,14 @@ public class InstallPluginCommandTests extends ESTestCase {
); );
} }
private void installPlugin(MockTerminal terminal, boolean isBatch) throws Exception { private void installPlugin(MockTerminal terminal, boolean isBatch, String... additionalProperties) throws Exception {
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
if (isBatch) { if (isBatch) {
writePluginSecurityPolicy(pluginDir, "setFactory"); writePluginSecurityPolicy(pluginDir, "setFactory");
} }
String pluginZip = createPlugin("fake", pluginDir).toUri().toURL().toString(); String pluginZip = createPlugin("fake", pluginDir, additionalProperties).toUri().toURL().toString();
skipJarHellCommand.execute(terminal, Collections.singletonList(pluginZip), isBatch, env.v2()); skipJarHellCommand.execute(terminal, Collections.singletonList(pluginZip), isBatch, env.v2());
} }

View file

@ -85,9 +85,8 @@ testClusters.integTest {
project.rootProject.subprojects.findAll { it.parent.path == ':plugins' }.each { subproj -> project.rootProject.subprojects.findAll { it.parent.path == ':plugins' }.each { subproj ->
/* Skip repositories. We just aren't going to be able to test them so it /* Skip repositories. We just aren't going to be able to test them so it
* doesn't make sense to waste time installing them. * doesn't make sense to waste time installing them.
* Also skip quota-aware-fs since it has to be configured in order to use */
* it, otherwise ES will not start. */ if (subproj.path.startsWith(':plugins:repository-')) {
if (subproj.path.startsWith(':plugins:repository-') || subproj.path.startsWith(':plugins:quota-aware-fs')) {
return return
} }
// Do not install ingest-attachment in a FIPS 140 JVM as this is not supported // Do not install ingest-attachment in a FIPS 140 JVM as this is not supported

View file

@ -22,6 +22,7 @@ package org.elasticsearch.packaging.test;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.client.fluent.Request; import org.apache.http.client.fluent.Request;
import org.elasticsearch.packaging.util.Distribution;
import org.elasticsearch.packaging.util.ServerUtils; import org.elasticsearch.packaging.util.ServerUtils;
import org.elasticsearch.packaging.util.Shell; import org.elasticsearch.packaging.util.Shell;
import org.junit.After; import org.junit.After;
@ -53,6 +54,7 @@ public class QuotaAwareFsTests extends PackagingTestCase {
@BeforeClass @BeforeClass
public static void filterDistros() { public static void filterDistros() {
assumeTrue("only archives", distribution.isArchive()); assumeTrue("only archives", distribution.isArchive());
assumeTrue("only default distribution", distribution.flavor == Distribution.Flavor.DEFAULT);
} }
@After @After

View file

@ -33,10 +33,6 @@ testClusters.integTest {
//Do not attempt to install ingest-attachment in FIPS 140 as it is not supported (it depends on non-FIPS BouncyCastle //Do not attempt to install ingest-attachment in FIPS 140 as it is not supported (it depends on non-FIPS BouncyCastle
return return
} }
if (pluginName == 'quota-aware-fs') {
// This plugin has to be configured to work via system properties
return
}
plugin pluginProject.path plugin pluginProject.path
pluginsCount += 1 pluginsCount += 1
} }

View file

@ -50,7 +50,7 @@ public class PluginInfo implements Writeable, ToXContentObject {
public static final String ES_PLUGIN_PROPERTIES = "plugin-descriptor.properties"; public static final String ES_PLUGIN_PROPERTIES = "plugin-descriptor.properties";
public static final String ES_PLUGIN_POLICY = "plugin-security.policy"; public static final String ES_PLUGIN_POLICY = "plugin-security.policy";
private static final Version BOOSTRAP_PLUGINS_SUPPORT = Version.V_7_11_0; private static final Version LICENSED_PLUGINS_SUPPORT = Version.V_7_11_0;
private final String name; private final String name;
private final String description; private final String description;
@ -62,6 +62,7 @@ public class PluginInfo implements Writeable, ToXContentObject {
private final boolean hasNativeController; private final boolean hasNativeController;
private final PluginType type; private final PluginType type;
private final String javaOpts; private final String javaOpts;
private final boolean isLicensed;
/** /**
* Construct plugin info. * Construct plugin info.
@ -76,10 +77,11 @@ public class PluginInfo implements Writeable, ToXContentObject {
* @param hasNativeController whether or not the plugin has a native controller * @param hasNativeController whether or not the plugin has a native controller
* @param type the type of the plugin. Expects "bootstrap" or "isolated". * @param type the type of the plugin. Expects "bootstrap" or "isolated".
* @param javaOpts any additional JVM CLI parameters added by this plugin * @param javaOpts any additional JVM CLI parameters added by this plugin
* @param isLicensed whether is this a licensed plugin
*/ */
public PluginInfo(String name, String description, String version, Version elasticsearchVersion, String javaVersion, public PluginInfo(String name, String description, String version, Version elasticsearchVersion, String javaVersion,
String classname, List<String> extendedPlugins, boolean hasNativeController, String classname, List<String> extendedPlugins, boolean hasNativeController,
PluginType type, String javaOpts) { PluginType type, String javaOpts, boolean isLicensed) {
this.name = name; this.name = name;
this.description = description; this.description = description;
this.version = version; this.version = version;
@ -90,6 +92,7 @@ public class PluginInfo implements Writeable, ToXContentObject {
this.hasNativeController = hasNativeController; this.hasNativeController = hasNativeController;
this.type = type; this.type = type;
this.javaOpts = javaOpts; this.javaOpts = javaOpts;
this.isLicensed = isLicensed;
} }
/** /**
@ -125,12 +128,14 @@ public class PluginInfo implements Writeable, ToXContentObject {
*/ */
in.readBoolean(); in.readBoolean();
} }
if (in.getVersion().onOrAfter(BOOSTRAP_PLUGINS_SUPPORT)) { if (in.getVersion().onOrAfter(LICENSED_PLUGINS_SUPPORT)) {
type = PluginType.valueOf(in.readString()); type = PluginType.valueOf(in.readString());
javaOpts = in.readOptionalString(); javaOpts = in.readOptionalString();
isLicensed = in.readBoolean();
} else { } else {
type = PluginType.ISOLATED; type = PluginType.ISOLATED;
javaOpts = null; javaOpts = null;
isLicensed = false;
} }
} }
@ -155,9 +160,10 @@ public class PluginInfo implements Writeable, ToXContentObject {
*/ */
out.writeBoolean(false); out.writeBoolean(false);
} }
if (out.getVersion().onOrAfter(BOOSTRAP_PLUGINS_SUPPORT)) { if (out.getVersion().onOrAfter(LICENSED_PLUGINS_SUPPORT)) {
out.writeString(type.name()); out.writeString(type.name());
out.writeOptionalString(javaOpts); out.writeOptionalString(javaOpts);
out.writeBoolean(this.isLicensed);
} }
} }
@ -235,12 +241,17 @@ public class PluginInfo implements Writeable, ToXContentObject {
propsMap.remove("requires.keystore"); propsMap.remove("requires.keystore");
} }
boolean isLicensed = false;
if (esVersion.onOrAfter(LICENSED_PLUGINS_SUPPORT)) {
isLicensed = parseBooleanValue(name, "licensed", propsMap.remove("licensed"));
}
if (propsMap.isEmpty() == false) { if (propsMap.isEmpty() == false) {
throw new IllegalArgumentException("Unknown properties for plugin [" + name + "] in plugin descriptor: " + propsMap.keySet()); throw new IllegalArgumentException("Unknown properties for plugin [" + name + "] in plugin descriptor: " + propsMap.keySet());
} }
return new PluginInfo(name, description, version, esVersion, javaVersionString, return new PluginInfo(name, description, version, esVersion, javaVersionString,
classname, extendedPlugins, hasNativeController, type, javaOpts); classname, extendedPlugins, hasNativeController, type, javaOpts, isLicensed);
} }
private static PluginType getPluginType(String name, String rawType) { private static PluginType getPluginType(String name, String rawType) {
@ -381,6 +392,15 @@ public class PluginInfo implements Writeable, ToXContentObject {
return javaOpts; return javaOpts;
} }
/**
* Whether a license must be accepted before this plugin can be installed.
*
* @return {@code true} if a license must be accepted.
*/
public boolean isLicensed() {
return isLicensed;
}
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();

View file

@ -124,7 +124,7 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
for (Class<? extends Plugin> pluginClass : classpathPlugins) { for (Class<? extends Plugin> pluginClass : classpathPlugins) {
Plugin plugin = loadPlugin(pluginClass, settings, configPath); Plugin plugin = loadPlugin(pluginClass, settings, configPath);
PluginInfo pluginInfo = new PluginInfo(pluginClass.getName(), "classpath plugin", "NA", Version.CURRENT, "1.8", PluginInfo pluginInfo = new PluginInfo(pluginClass.getName(), "classpath plugin", "NA", Version.CURRENT, "1.8",
pluginClass.getName(), Collections.emptyList(), false, PluginType.ISOLATED, ""); pluginClass.getName(), Collections.emptyList(), false, PluginType.ISOLATED, "", false);
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("plugin loaded from classpath [{}]", pluginInfo); logger.trace("plugin loaded from classpath [{}]", pluginInfo);
} }

View file

@ -150,7 +150,7 @@ public class NodeInfoStreamingTests extends ESTestCase {
plugins.add(new PluginInfo(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10), plugins.add(new PluginInfo(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10),
randomAlphaOfLengthBetween(3, 10), VersionUtils.randomVersion(random()), "1.8", randomAlphaOfLengthBetween(3, 10), VersionUtils.randomVersion(random()), "1.8",
randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean(), randomFrom(PluginType.values()), randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean(), randomFrom(PluginType.values()),
randomAlphaOfLengthBetween(3, 10))); randomAlphaOfLengthBetween(3, 10), randomBoolean()));
} }
int numModules = randomIntBetween(0, 5); int numModules = randomIntBetween(0, 5);
List<PluginInfo> modules = new ArrayList<>(); List<PluginInfo> modules = new ArrayList<>();
@ -158,7 +158,7 @@ public class NodeInfoStreamingTests extends ESTestCase {
modules.add(new PluginInfo(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10), modules.add(new PluginInfo(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10),
randomAlphaOfLengthBetween(3, 10), VersionUtils.randomVersion(random()), "1.8", randomAlphaOfLengthBetween(3, 10), VersionUtils.randomVersion(random()), "1.8",
randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean(), randomFrom(PluginType.values()), randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean(), randomFrom(PluginType.values()),
randomAlphaOfLengthBetween(3, 10))); randomAlphaOfLengthBetween(3, 10), randomBoolean()));
} }
pluginsAndModules = new PluginsAndModules(plugins, modules); pluginsAndModules = new PluginsAndModules(plugins, modules);
} }

View file

@ -185,7 +185,8 @@ public class PluginInfoTests extends ESTestCase {
public void testSerialize() throws Exception { public void testSerialize() throws Exception {
PluginInfo info = new PluginInfo("c", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass", PluginInfo info = new PluginInfo("c", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
Collections.singletonList("foo"), randomBoolean(), PluginType.ISOLATED, "-Dfoo=bar"); Collections.singletonList("foo"), randomBoolean(), PluginType.ISOLATED, "-Dfoo=bar",
randomBoolean());
BytesStreamOutput output = new BytesStreamOutput(); BytesStreamOutput output = new BytesStreamOutput();
info.writeTo(output); info.writeTo(output);
ByteBuffer buffer = ByteBuffer.wrap(output.bytes().toBytesRef().bytes); ByteBuffer buffer = ByteBuffer.wrap(output.bytes().toBytesRef().bytes);
@ -198,15 +199,15 @@ public class PluginInfoTests extends ESTestCase {
public void testPluginListSorted() { public void testPluginListSorted() {
List<PluginInfo> plugins = new ArrayList<>(); List<PluginInfo> plugins = new ArrayList<>();
plugins.add(new PluginInfo("c", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass", plugins.add(new PluginInfo("c", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
Collections.emptyList(), randomBoolean(), PluginType.ISOLATED, "-Da")); Collections.emptyList(), randomBoolean(), PluginType.ISOLATED, "-Da", randomBoolean()));
plugins.add(new PluginInfo("b", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass", plugins.add(new PluginInfo("b", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
Collections.emptyList(), randomBoolean(), PluginType.BOOTSTRAP, "-Db")); Collections.emptyList(), randomBoolean(), PluginType.BOOTSTRAP, "-Db", randomBoolean()));
plugins.add(new PluginInfo( "e", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass", plugins.add(new PluginInfo( "e", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
Collections.emptyList(), randomBoolean(), PluginType.ISOLATED, "-Dc")); Collections.emptyList(), randomBoolean(), PluginType.ISOLATED, "-Dc", randomBoolean()));
plugins.add(new PluginInfo("a", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass", plugins.add(new PluginInfo("a", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
Collections.emptyList(), randomBoolean(), PluginType.BOOTSTRAP, "-Dd")); Collections.emptyList(), randomBoolean(), PluginType.BOOTSTRAP, "-Dd", randomBoolean()));
plugins.add(new PluginInfo("d", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass", plugins.add(new PluginInfo("d", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
Collections.emptyList(), randomBoolean(), PluginType.ISOLATED, "-De")); Collections.emptyList(), randomBoolean(), PluginType.ISOLATED, "-De", randomBoolean()));
PluginsAndModules pluginsInfo = new PluginsAndModules(plugins, Collections.emptyList()); PluginsAndModules pluginsInfo = new PluginsAndModules(plugins, Collections.emptyList());
final List<PluginInfo> infos = pluginsInfo.getPluginInfos(); final List<PluginInfo> infos = pluginsInfo.getPluginInfos();

View file

@ -309,7 +309,7 @@ public class PluginsServiceTests extends ESTestCase {
public void testSortBundlesCycleSelfReference() throws Exception { public void testSortBundlesCycleSelfReference() throws Exception {
Path pluginDir = createTempDir(); Path pluginDir = createTempDir();
PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("foo"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("foo"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir);
IllegalStateException e = expectThrows(IllegalStateException.class, () -> IllegalStateException e = expectThrows(IllegalStateException.class, () ->
PluginsService.sortBundles(Collections.singleton(bundle)) PluginsService.sortBundles(Collections.singleton(bundle))
@ -321,16 +321,16 @@ public class PluginsServiceTests extends ESTestCase {
Path pluginDir = createTempDir(); Path pluginDir = createTempDir();
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order, so we get know the beginning of the cycle Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order, so we get know the beginning of the cycle
PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Arrays.asList("bar", "other"), false, PluginType.ISOLATED, ""); "MyPlugin", Arrays.asList("bar", "other"), false, PluginType.ISOLATED, "", false);
bundles.add(new PluginsService.Bundle(info, pluginDir)); bundles.add(new PluginsService.Bundle(info, pluginDir));
PluginInfo info2 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info2 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("baz"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("baz"), false, PluginType.ISOLATED, "", false);
bundles.add(new PluginsService.Bundle(info2, pluginDir)); bundles.add(new PluginsService.Bundle(info2, pluginDir));
PluginInfo info3 = new PluginInfo("baz", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info3 = new PluginInfo("baz", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("foo"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("foo"), false, PluginType.ISOLATED, "", false);
bundles.add(new PluginsService.Bundle(info3, pluginDir)); bundles.add(new PluginsService.Bundle(info3, pluginDir));
PluginInfo info4 = new PluginInfo("other", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info4 = new PluginInfo("other", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
bundles.add(new PluginsService.Bundle(info4, pluginDir)); bundles.add(new PluginsService.Bundle(info4, pluginDir));
IllegalStateException e = expectThrows(IllegalStateException.class, () -> PluginsService.sortBundles(bundles)); IllegalStateException e = expectThrows(IllegalStateException.class, () -> PluginsService.sortBundles(bundles));
@ -340,7 +340,7 @@ public class PluginsServiceTests extends ESTestCase {
public void testSortBundlesSingle() throws Exception { public void testSortBundlesSingle() throws Exception {
Path pluginDir = createTempDir(); Path pluginDir = createTempDir();
PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir);
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(Collections.singleton(bundle)); List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(Collections.singleton(bundle));
assertThat(sortedBundles, Matchers.contains(bundle)); assertThat(sortedBundles, Matchers.contains(bundle));
@ -350,15 +350,15 @@ public class PluginsServiceTests extends ESTestCase {
Path pluginDir = createTempDir(); Path pluginDir = createTempDir();
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
PluginInfo info1 = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir);
bundles.add(bundle1); bundles.add(bundle1);
PluginInfo info2 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info2 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir); PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir);
bundles.add(bundle2); bundles.add(bundle2);
PluginInfo info3 = new PluginInfo("baz", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info3 = new PluginInfo("baz", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle3 = new PluginsService.Bundle(info3, pluginDir); PluginsService.Bundle bundle3 = new PluginsService.Bundle(info3, pluginDir);
bundles.add(bundle3); bundles.add(bundle3);
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles); List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
@ -368,7 +368,7 @@ public class PluginsServiceTests extends ESTestCase {
public void testSortBundlesMissingDep() throws Exception { public void testSortBundlesMissingDep() throws Exception {
Path pluginDir = createTempDir(); Path pluginDir = createTempDir();
PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("dne"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("dne"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () ->
PluginsService.sortBundles(Collections.singleton(bundle)) PluginsService.sortBundles(Collections.singleton(bundle))
@ -380,19 +380,19 @@ public class PluginsServiceTests extends ESTestCase {
Path pluginDir = createTempDir(); Path pluginDir = createTempDir();
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
PluginInfo info1 = new PluginInfo("grandparent", "desc", "1.0",Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("grandparent", "desc", "1.0",Version.CURRENT, "1.8",
"MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir);
bundles.add(bundle1); bundles.add(bundle1);
PluginInfo info2 = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info2 = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("common"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("common"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir); PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir);
bundles.add(bundle2); bundles.add(bundle2);
PluginInfo info3 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info3 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("common"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("common"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle3 = new PluginsService.Bundle(info3, pluginDir); PluginsService.Bundle bundle3 = new PluginsService.Bundle(info3, pluginDir);
bundles.add(bundle3); bundles.add(bundle3);
PluginInfo info4 = new PluginInfo("common", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info4 = new PluginInfo("common", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("grandparent"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("grandparent"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle4 = new PluginsService.Bundle(info4, pluginDir); PluginsService.Bundle bundle4 = new PluginsService.Bundle(info4, pluginDir);
bundles.add(bundle4); bundles.add(bundle4);
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles); List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
@ -403,11 +403,11 @@ public class PluginsServiceTests extends ESTestCase {
Path pluginDir = createTempDir(); Path pluginDir = createTempDir();
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
PluginInfo info1 = new PluginInfo("dep", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("dep", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir);
bundles.add(bundle1); bundles.add(bundle1);
PluginInfo info2 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info2 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("dep"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("dep"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir); PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir);
bundles.add(bundle2); bundles.add(bundle2);
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles); List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
@ -466,7 +466,7 @@ public class PluginsServiceTests extends ESTestCase {
Map<String, Set<URL>> transitiveDeps = new HashMap<>(); Map<String, Set<URL>> transitiveDeps = new HashMap<>();
transitiveDeps.put("dep", Collections.singleton(dupJar.toUri().toURL())); transitiveDeps.put("dep", Collections.singleton(dupJar.toUri().toURL()));
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("dep"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("dep"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
IllegalStateException e = expectThrows(IllegalStateException.class, () -> IllegalStateException e = expectThrows(IllegalStateException.class, () ->
PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps)); PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps));
@ -485,7 +485,7 @@ public class PluginsServiceTests extends ESTestCase {
transitiveDeps.put("dep1", Collections.singleton(dupJar.toUri().toURL())); transitiveDeps.put("dep1", Collections.singleton(dupJar.toUri().toURL()));
transitiveDeps.put("dep2", Collections.singleton(dupJar.toUri().toURL())); transitiveDeps.put("dep2", Collections.singleton(dupJar.toUri().toURL()));
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Arrays.asList("dep1", "dep2"), false, PluginType.ISOLATED, ""); "MyPlugin", Arrays.asList("dep1", "dep2"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
IllegalStateException e = expectThrows(IllegalStateException.class, () -> IllegalStateException e = expectThrows(IllegalStateException.class, () ->
PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps)); PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps));
@ -502,7 +502,7 @@ public class PluginsServiceTests extends ESTestCase {
Path pluginJar = pluginDir.resolve("plugin.jar"); Path pluginJar = pluginDir.resolve("plugin.jar");
makeJar(pluginJar, Level.class); makeJar(pluginJar, Level.class);
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
IllegalStateException e = expectThrows(IllegalStateException.class, () -> IllegalStateException e = expectThrows(IllegalStateException.class, () ->
PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, new HashMap<>())); PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, new HashMap<>()));
@ -521,7 +521,7 @@ public class PluginsServiceTests extends ESTestCase {
Map<String, Set<URL>> transitiveDeps = new HashMap<>(); Map<String, Set<URL>> transitiveDeps = new HashMap<>();
transitiveDeps.put("dep", Collections.singleton(depJar.toUri().toURL())); transitiveDeps.put("dep", Collections.singleton(depJar.toUri().toURL()));
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Collections.singletonList("dep"), false, PluginType.ISOLATED, ""); "MyPlugin", Collections.singletonList("dep"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
IllegalStateException e = expectThrows(IllegalStateException.class, () -> IllegalStateException e = expectThrows(IllegalStateException.class, () ->
PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps)); PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps));
@ -544,7 +544,7 @@ public class PluginsServiceTests extends ESTestCase {
transitiveDeps.put("dep1", Collections.singleton(dep1Jar.toUri().toURL())); transitiveDeps.put("dep1", Collections.singleton(dep1Jar.toUri().toURL()));
transitiveDeps.put("dep2", Collections.singleton(dep2Jar.toUri().toURL())); transitiveDeps.put("dep2", Collections.singleton(dep2Jar.toUri().toURL()));
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Arrays.asList("dep1", "dep2"), false, PluginType.ISOLATED, ""); "MyPlugin", Arrays.asList("dep1", "dep2"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
IllegalStateException e = expectThrows(IllegalStateException.class, () -> IllegalStateException e = expectThrows(IllegalStateException.class, () ->
PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps)); PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps));
@ -567,7 +567,7 @@ public class PluginsServiceTests extends ESTestCase {
transitiveDeps.put("dep1", Collections.singleton(dep1Jar.toUri().toURL())); transitiveDeps.put("dep1", Collections.singleton(dep1Jar.toUri().toURL()));
transitiveDeps.put("dep2", Collections.singleton(dep2Jar.toUri().toURL())); transitiveDeps.put("dep2", Collections.singleton(dep2Jar.toUri().toURL()));
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8", PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
"MyPlugin", Arrays.asList("dep1", "dep2"), false, PluginType.ISOLATED, ""); "MyPlugin", Arrays.asList("dep1", "dep2"), false, PluginType.ISOLATED, "", false);
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir); PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps); PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps);
Set<URL> deps = transitiveDeps.get("myplugin"); Set<URL> deps = transitiveDeps.get("myplugin");
@ -616,14 +616,14 @@ public class PluginsServiceTests extends ESTestCase {
public void testIncompatibleElasticsearchVersion() throws Exception { public void testIncompatibleElasticsearchVersion() throws Exception {
PluginInfo info = new PluginInfo("my_plugin", "desc", "1.0", Version.V_6_0_0, PluginInfo info = new PluginInfo("my_plugin", "desc", "1.0", Version.V_6_0_0,
"1.8", "FakePlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "1.8", "FakePlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> PluginsService.verifyCompatibility(info)); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> PluginsService.verifyCompatibility(info));
assertThat(e.getMessage(), containsString("was built for Elasticsearch version 6.0.0")); assertThat(e.getMessage(), containsString("was built for Elasticsearch version 6.0.0"));
} }
public void testIncompatibleJavaVersion() throws Exception { public void testIncompatibleJavaVersion() throws Exception {
PluginInfo info = new PluginInfo("my_plugin", "desc", "1.0", Version.CURRENT, PluginInfo info = new PluginInfo("my_plugin", "desc", "1.0", Version.CURRENT,
"1000000.0", "FakePlugin", Collections.emptyList(), false, PluginType.ISOLATED, ""); "1000000.0", "FakePlugin", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
IllegalStateException e = expectThrows(IllegalStateException.class, () -> PluginsService.verifyCompatibility(info)); IllegalStateException e = expectThrows(IllegalStateException.class, () -> PluginsService.verifyCompatibility(info));
assertThat(e.getMessage(), containsString("my_plugin requires Java")); assertThat(e.getMessage(), containsString("my_plugin requires Java"));
} }
@ -724,7 +724,7 @@ public class PluginsServiceTests extends ESTestCase {
TestExtensiblePlugin extensiblePlugin = new TestExtensiblePlugin(); TestExtensiblePlugin extensiblePlugin = new TestExtensiblePlugin();
PluginsService.loadExtensions(Collections.singletonList( PluginsService.loadExtensions(Collections.singletonList(
Tuple.tuple( Tuple.tuple(
new PluginInfo("extensible", null, null, null, null, null, Collections.emptyList(), false, PluginType.ISOLATED, ""), new PluginInfo("extensible", null, null, null, null, null, Collections.emptyList(), false, PluginType.ISOLATED, "", false),
extensiblePlugin extensiblePlugin
) )
)); ));
@ -736,9 +736,9 @@ public class PluginsServiceTests extends ESTestCase {
TestPlugin testPlugin = new TestPlugin(); TestPlugin testPlugin = new TestPlugin();
PluginsService.loadExtensions(Arrays.asList( PluginsService.loadExtensions(Arrays.asList(
Tuple.tuple(new PluginInfo("extensible", null, null, null, null, null, Collections.emptyList(), false, Tuple.tuple(new PluginInfo("extensible", null, null, null, null, null, Collections.emptyList(), false,
PluginType.ISOLATED, ""), extensiblePlugin), PluginType.ISOLATED, "", false), extensiblePlugin),
Tuple.tuple(new PluginInfo("test", null, null, null, null, null, Collections.singletonList("extensible"), false, Tuple.tuple(new PluginInfo("test", null, null, null, null, null, Collections.singletonList("extensible"), false,
PluginType.ISOLATED, ""), testPlugin) PluginType.ISOLATED, "", false), testPlugin)
)); ));
assertThat(extensiblePlugin.extensions, notNullValue()); assertThat(extensiblePlugin.extensions, notNullValue());

View file

@ -257,7 +257,7 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
final PluginsAndModules mockPluginsAndModules = mock(PluginsAndModules.class); final PluginsAndModules mockPluginsAndModules = mock(PluginsAndModules.class);
when(mockNodeInfo.getInfo(PluginsAndModules.class)).thenReturn(mockPluginsAndModules); when(mockNodeInfo.getInfo(PluginsAndModules.class)).thenReturn(mockPluginsAndModules);
final PluginInfo pluginInfo = new PluginInfo("_plugin", "_plugin_desc", "_plugin_version", Version.CURRENT, final PluginInfo pluginInfo = new PluginInfo("_plugin", "_plugin_desc", "_plugin_version", Version.CURRENT,
"1.8", "_plugin_class", Collections.emptyList(), false, PluginType.ISOLATED, ""); "1.8", "_plugin_class", Collections.emptyList(), false, PluginType.ISOLATED, "", false);
when(mockPluginsAndModules.getPluginInfos()).thenReturn(singletonList(pluginInfo)); when(mockPluginsAndModules.getPluginInfos()).thenReturn(singletonList(pluginInfo));
final OsInfo mockOsInfo = mock(OsInfo.class); final OsInfo mockOsInfo = mock(OsInfo.class);

View file

@ -67,10 +67,6 @@ testClusters.integTest {
user username: "monitoring_agent", password: "x-pack-test-password", role: "remote_monitoring_agent" user username: "monitoring_agent", password: "x-pack-test-password", role: "remote_monitoring_agent"
project(':plugins').getChildProjects().each { pluginName, pluginProject -> project(':plugins').getChildProjects().each { pluginName, pluginProject ->
if (pluginName == 'quota-aware-fs') {
// This plugin has to be configured to work via system properties
return
}
plugin pluginProject.path plugin pluginProject.path
pluginsCount += 1 pluginsCount += 1
} }

View file

@ -1,5 +1,8 @@
apply plugin: 'elasticsearch.esplugin'
esplugin { esplugin {
description 'A bootstrap plugin that adds support for interfacing with filesystem that enforce user quotas.' description 'A bootstrap plugin that adds support for interfacing with filesystem that enforce user quotas.'
type = 'bootstrap' type = 'bootstrap'
javaOpts = '-Djava.nio.file.spi.DefaultFileSystemProvider=org.elasticsearch.fs.quotaaware.QuotaAwareFileSystemProvider' javaOpts = '-Djava.nio.file.spi.DefaultFileSystemProvider=org.elasticsearch.fs.quotaaware.QuotaAwareFileSystemProvider'
licensed true
} }

View file

@ -1,21 +1,9 @@
/* /*
* Licensed to Elasticsearch under one or more contributor * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* license agreements. See the NOTICE file distributed with * or more contributor license agreements. Licensed under the Elastic License;
* this work for additional information regarding copyright * you may not use this file except in compliance with the Elastic License.
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package org.elasticsearch.fs.quotaaware; package org.elasticsearch.fs.quotaaware;
import java.io.IOException; import java.io.IOException;

View file

@ -1,20 +1,7 @@
/* /*
* Licensed to Elasticsearch under one or more contributor * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* license agreements. See the NOTICE file distributed with * or more contributor license agreements. Licensed under the Elastic License;
* this work for additional information regarding copyright * you may not use this file except in compliance with the Elastic License.
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package org.elasticsearch.fs.quotaaware; package org.elasticsearch.fs.quotaaware;

View file

@ -1,20 +1,7 @@
/* /*
* Licensed to Elasticsearch under one or more contributor * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* license agreements. See the NOTICE file distributed with * or more contributor license agreements. Licensed under the Elastic License;
* this work for additional information regarding copyright * you may not use this file except in compliance with the Elastic License.
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package org.elasticsearch.fs.quotaaware; package org.elasticsearch.fs.quotaaware;

View file

@ -1,20 +1,7 @@
/* /*
* Licensed to Elasticsearch under one or more contributor * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* license agreements. See the NOTICE file distributed with * or more contributor license agreements. Licensed under the Elastic License;
* this work for additional information regarding copyright * you may not use this file except in compliance with the Elastic License.
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package org.elasticsearch.fs.quotaaware; package org.elasticsearch.fs.quotaaware;

View file

@ -1,20 +1,7 @@
/* /*
* Licensed to Elasticsearch under one or more contributor * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* license agreements. See the NOTICE file distributed with * or more contributor license agreements. Licensed under the Elastic License;
* this work for additional information regarding copyright * you may not use this file except in compliance with the Elastic License.
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package org.elasticsearch.fs.quotaaware; package org.elasticsearch.fs.quotaaware;

View file

@ -1,20 +1,7 @@
/* /*
* Licensed to Elasticsearch under one or more contributor * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* license agreements. See the NOTICE file distributed with * or more contributor license agreements. Licensed under the Elastic License;
* this work for additional information regarding copyright * you may not use this file except in compliance with the Elastic License.
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package org.elasticsearch.fs.quotaaware; package org.elasticsearch.fs.quotaaware;

View file

@ -1,20 +1,7 @@
/* /*
* Licensed to Elasticsearch under one or more contributor * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* license agreements. See the NOTICE file distributed with * or more contributor license agreements. Licensed under the Elastic License;
* this work for additional information regarding copyright * you may not use this file except in compliance with the Elastic License.
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package org.elasticsearch.fs.quotaaware; package org.elasticsearch.fs.quotaaware;

View file

@ -1,20 +1,7 @@
/* /*
* Licensed to Elasticsearch under one or more contributor * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* license agreements. See the NOTICE file distributed with * or more contributor license agreements. Licensed under the Elastic License;
* this work for additional information regarding copyright * you may not use this file except in compliance with the Elastic License.
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package org.elasticsearch.fs.quotaaware; package org.elasticsearch.fs.quotaaware;