mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-04-24 15:17:30 -04:00
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:
parent
cb79960d6f
commit
a7ccbfa346
26 changed files with 235 additions and 185 deletions
|
@ -97,13 +97,14 @@ class PluginBuildPlugin implements Plugin<Project> {
|
|||
'requiresKeystore' : extension1.requiresKeystore,
|
||||
'type' : extension1.type.toString(),
|
||||
'javaOpts' : extension1.javaOpts,
|
||||
'licensed' : extension1.licensed,
|
||||
]
|
||||
project.tasks.named('pluginProperties').configure {
|
||||
expand(properties)
|
||||
inputs.properties(properties)
|
||||
}
|
||||
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
|
||||
if (isModule == false || isXPackModule) {
|
||||
addNoticeGeneration(project, extension1)
|
||||
|
|
|
@ -47,6 +47,9 @@ public class PluginPropertiesExtension {
|
|||
|
||||
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. */
|
||||
private boolean requiresKeystore;
|
||||
|
||||
|
@ -127,6 +130,14 @@ public class PluginPropertiesExtension {
|
|||
this.javaOpts = javaOpts;
|
||||
}
|
||||
|
||||
public boolean isLicensed() {
|
||||
return isLicensed;
|
||||
}
|
||||
|
||||
public void setLicensed(boolean licensed) {
|
||||
isLicensed = licensed;
|
||||
}
|
||||
|
||||
public boolean isRequiresKeystore() {
|
||||
return requiresKeystore;
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ public class DistroTestPlugin implements Plugin<Project> {
|
|||
private static Configuration configureQuotaAwareFsPlugin(Project project) {
|
||||
Configuration examplePlugin = project.getConfigurations().create(QUOTA_AWARE_FS_PLUGIN_CONFIGURATION);
|
||||
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));
|
||||
return examplePlugin;
|
||||
}
|
||||
|
|
|
@ -57,3 +57,7 @@ has.native.controller=${hasNativeController}
|
|||
# Elasticsearch starts. Only applies to "bootstrap" plugins.
|
||||
java.opts=${javaOpts}
|
||||
<% } %>
|
||||
<% if (licensed) { %>
|
||||
# This plugin requires that a license agreement be accepted before installation
|
||||
licensed=${licensed}
|
||||
<% } %>
|
||||
|
|
|
@ -866,6 +866,9 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||
private PluginInfo installPlugin(Terminal terminal, boolean isBatch, Path tmpRoot, Environment env, List<Path> deleteOnFailure)
|
||||
throws Exception {
|
||||
final PluginInfo info = loadPluginInfo(terminal, tmpRoot, env);
|
||||
|
||||
checkCanInstallationProceed(terminal, Build.CURRENT.flavor(), info);
|
||||
|
||||
PluginPolicyInfo pluginPolicy = PolicyUtil.getPluginPolicyInfo(tmpRoot, env.tmpFile());
|
||||
if (pluginPolicy != null) {
|
||||
Set<String> permissions = PluginSecurity.getPermissionDescriptions(pluginPolicy, env.tmpFile());
|
||||
|
@ -1019,4 +1022,24 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
Path pluginDir = createPluginDir(temp);
|
||||
// if batch is enabled, we also want to add a security policy
|
||||
if (isBatch) {
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -85,9 +85,8 @@ testClusters.integTest {
|
|||
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
|
||||
* 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-') || subproj.path.startsWith(':plugins:quota-aware-fs')) {
|
||||
*/
|
||||
if (subproj.path.startsWith(':plugins:repository-')) {
|
||||
return
|
||||
}
|
||||
// Do not install ingest-attachment in a FIPS 140 JVM as this is not supported
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.packaging.test;
|
|||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.http.client.fluent.Request;
|
||||
import org.elasticsearch.packaging.util.Distribution;
|
||||
import org.elasticsearch.packaging.util.ServerUtils;
|
||||
import org.elasticsearch.packaging.util.Shell;
|
||||
import org.junit.After;
|
||||
|
@ -53,6 +54,7 @@ public class QuotaAwareFsTests extends PackagingTestCase {
|
|||
@BeforeClass
|
||||
public static void filterDistros() {
|
||||
assumeTrue("only archives", distribution.isArchive());
|
||||
assumeTrue("only default distribution", distribution.flavor == Distribution.Flavor.DEFAULT);
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
@ -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
|
||||
return
|
||||
}
|
||||
if (pluginName == 'quota-aware-fs') {
|
||||
// This plugin has to be configured to work via system properties
|
||||
return
|
||||
}
|
||||
plugin pluginProject.path
|
||||
pluginsCount += 1
|
||||
}
|
||||
|
|
|
@ -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_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 description;
|
||||
|
@ -62,6 +62,7 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
|||
private final boolean hasNativeController;
|
||||
private final PluginType type;
|
||||
private final String javaOpts;
|
||||
private final boolean isLicensed;
|
||||
|
||||
/**
|
||||
* 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 type the type of the plugin. Expects "bootstrap" or "isolated".
|
||||
* @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,
|
||||
String classname, List<String> extendedPlugins, boolean hasNativeController,
|
||||
PluginType type, String javaOpts) {
|
||||
PluginType type, String javaOpts, boolean isLicensed) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.version = version;
|
||||
|
@ -90,6 +92,7 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
|||
this.hasNativeController = hasNativeController;
|
||||
this.type = type;
|
||||
this.javaOpts = javaOpts;
|
||||
this.isLicensed = isLicensed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,12 +128,14 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
|||
*/
|
||||
in.readBoolean();
|
||||
}
|
||||
if (in.getVersion().onOrAfter(BOOSTRAP_PLUGINS_SUPPORT)) {
|
||||
if (in.getVersion().onOrAfter(LICENSED_PLUGINS_SUPPORT)) {
|
||||
type = PluginType.valueOf(in.readString());
|
||||
javaOpts = in.readOptionalString();
|
||||
isLicensed = in.readBoolean();
|
||||
} else {
|
||||
type = PluginType.ISOLATED;
|
||||
javaOpts = null;
|
||||
isLicensed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,9 +160,10 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
|||
*/
|
||||
out.writeBoolean(false);
|
||||
}
|
||||
if (out.getVersion().onOrAfter(BOOSTRAP_PLUGINS_SUPPORT)) {
|
||||
if (out.getVersion().onOrAfter(LICENSED_PLUGINS_SUPPORT)) {
|
||||
out.writeString(type.name());
|
||||
out.writeOptionalString(javaOpts);
|
||||
out.writeBoolean(this.isLicensed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,12 +241,17 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
|||
propsMap.remove("requires.keystore");
|
||||
}
|
||||
|
||||
boolean isLicensed = false;
|
||||
if (esVersion.onOrAfter(LICENSED_PLUGINS_SUPPORT)) {
|
||||
isLicensed = parseBooleanValue(name, "licensed", propsMap.remove("licensed"));
|
||||
}
|
||||
|
||||
if (propsMap.isEmpty() == false) {
|
||||
throw new IllegalArgumentException("Unknown properties for plugin [" + name + "] in plugin descriptor: " + propsMap.keySet());
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -381,6 +392,15 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
|||
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
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
|
|
|
@ -124,7 +124,7 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
|
|||
for (Class<? extends Plugin> pluginClass : classpathPlugins) {
|
||||
Plugin plugin = loadPlugin(pluginClass, settings, configPath);
|
||||
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()) {
|
||||
logger.trace("plugin loaded from classpath [{}]", pluginInfo);
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ public class NodeInfoStreamingTests extends ESTestCase {
|
|||
plugins.add(new PluginInfo(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10),
|
||||
randomAlphaOfLengthBetween(3, 10), VersionUtils.randomVersion(random()), "1.8",
|
||||
randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean(), randomFrom(PluginType.values()),
|
||||
randomAlphaOfLengthBetween(3, 10)));
|
||||
randomAlphaOfLengthBetween(3, 10), randomBoolean()));
|
||||
}
|
||||
int numModules = randomIntBetween(0, 5);
|
||||
List<PluginInfo> modules = new ArrayList<>();
|
||||
|
@ -158,7 +158,7 @@ public class NodeInfoStreamingTests extends ESTestCase {
|
|||
modules.add(new PluginInfo(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10),
|
||||
randomAlphaOfLengthBetween(3, 10), VersionUtils.randomVersion(random()), "1.8",
|
||||
randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean(), randomFrom(PluginType.values()),
|
||||
randomAlphaOfLengthBetween(3, 10)));
|
||||
randomAlphaOfLengthBetween(3, 10), randomBoolean()));
|
||||
}
|
||||
pluginsAndModules = new PluginsAndModules(plugins, modules);
|
||||
}
|
||||
|
|
|
@ -185,7 +185,8 @@ public class PluginInfoTests extends ESTestCase {
|
|||
|
||||
public void testSerialize() throws Exception {
|
||||
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();
|
||||
info.writeTo(output);
|
||||
ByteBuffer buffer = ByteBuffer.wrap(output.bytes().toBytesRef().bytes);
|
||||
|
@ -198,15 +199,15 @@ public class PluginInfoTests extends ESTestCase {
|
|||
public void testPluginListSorted() {
|
||||
List<PluginInfo> plugins = new ArrayList<>();
|
||||
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",
|
||||
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",
|
||||
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",
|
||||
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",
|
||||
Collections.emptyList(), randomBoolean(), PluginType.ISOLATED, "-De"));
|
||||
Collections.emptyList(), randomBoolean(), PluginType.ISOLATED, "-De", randomBoolean()));
|
||||
PluginsAndModules pluginsInfo = new PluginsAndModules(plugins, Collections.emptyList());
|
||||
|
||||
final List<PluginInfo> infos = pluginsInfo.getPluginInfos();
|
||||
|
|
|
@ -309,7 +309,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
public void testSortBundlesCycleSelfReference() throws Exception {
|
||||
Path pluginDir = createTempDir();
|
||||
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);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.sortBundles(Collections.singleton(bundle))
|
||||
|
@ -321,16 +321,16 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
Path pluginDir = createTempDir();
|
||||
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",
|
||||
"MyPlugin", Arrays.asList("bar", "other"), false, PluginType.ISOLATED, "");
|
||||
"MyPlugin", Arrays.asList("bar", "other"), false, PluginType.ISOLATED, "", false);
|
||||
bundles.add(new PluginsService.Bundle(info, pluginDir));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () -> PluginsService.sortBundles(bundles));
|
||||
|
@ -340,7 +340,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
public void testSortBundlesSingle() throws Exception {
|
||||
Path pluginDir = createTempDir();
|
||||
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);
|
||||
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(Collections.singleton(bundle));
|
||||
assertThat(sortedBundles, Matchers.contains(bundle));
|
||||
|
@ -350,15 +350,15 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
Path pluginDir = createTempDir();
|
||||
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
|
||||
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);
|
||||
bundles.add(bundle1);
|
||||
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);
|
||||
bundles.add(bundle2);
|
||||
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);
|
||||
bundles.add(bundle3);
|
||||
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
|
||||
|
@ -368,7 +368,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
public void testSortBundlesMissingDep() throws Exception {
|
||||
Path pluginDir = createTempDir();
|
||||
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);
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () ->
|
||||
PluginsService.sortBundles(Collections.singleton(bundle))
|
||||
|
@ -380,19 +380,19 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
Path pluginDir = createTempDir();
|
||||
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
|
||||
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);
|
||||
bundles.add(bundle1);
|
||||
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);
|
||||
bundles.add(bundle2);
|
||||
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);
|
||||
bundles.add(bundle3);
|
||||
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);
|
||||
bundles.add(bundle4);
|
||||
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
|
||||
|
@ -403,11 +403,11 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
Path pluginDir = createTempDir();
|
||||
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
|
||||
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);
|
||||
bundles.add(bundle1);
|
||||
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);
|
||||
bundles.add(bundle2);
|
||||
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
|
||||
|
@ -466,7 +466,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
Map<String, Set<URL>> transitiveDeps = new HashMap<>();
|
||||
transitiveDeps.put("dep", Collections.singleton(dupJar.toUri().toURL()));
|
||||
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);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
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("dep2", Collections.singleton(dupJar.toUri().toURL()));
|
||||
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);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps));
|
||||
|
@ -502,7 +502,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
Path pluginJar = pluginDir.resolve("plugin.jar");
|
||||
makeJar(pluginJar, Level.class);
|
||||
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);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.checkBundleJarHell(JarHell.parseClassPath(), bundle, new HashMap<>()));
|
||||
|
@ -521,7 +521,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
Map<String, Set<URL>> transitiveDeps = new HashMap<>();
|
||||
transitiveDeps.put("dep", Collections.singleton(depJar.toUri().toURL()));
|
||||
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);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
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("dep2", Collections.singleton(dep2Jar.toUri().toURL()));
|
||||
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);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
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("dep2", Collections.singleton(dep2Jar.toUri().toURL()));
|
||||
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.checkBundleJarHell(JarHell.parseClassPath(), bundle, transitiveDeps);
|
||||
Set<URL> deps = transitiveDeps.get("myplugin");
|
||||
|
@ -616,14 +616,14 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
|
||||
public void testIncompatibleElasticsearchVersion() throws Exception {
|
||||
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));
|
||||
assertThat(e.getMessage(), containsString("was built for Elasticsearch version 6.0.0"));
|
||||
}
|
||||
|
||||
public void testIncompatibleJavaVersion() throws Exception {
|
||||
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));
|
||||
assertThat(e.getMessage(), containsString("my_plugin requires Java"));
|
||||
}
|
||||
|
@ -724,7 +724,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
TestExtensiblePlugin extensiblePlugin = new TestExtensiblePlugin();
|
||||
PluginsService.loadExtensions(Collections.singletonList(
|
||||
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
|
||||
)
|
||||
));
|
||||
|
@ -736,9 +736,9 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
TestPlugin testPlugin = new TestPlugin();
|
||||
PluginsService.loadExtensions(Arrays.asList(
|
||||
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,
|
||||
PluginType.ISOLATED, ""), testPlugin)
|
||||
PluginType.ISOLATED, "", false), testPlugin)
|
||||
));
|
||||
|
||||
assertThat(extensiblePlugin.extensions, notNullValue());
|
||||
|
|
|
@ -257,7 +257,7 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
|
|||
final PluginsAndModules mockPluginsAndModules = mock(PluginsAndModules.class);
|
||||
when(mockNodeInfo.getInfo(PluginsAndModules.class)).thenReturn(mockPluginsAndModules);
|
||||
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));
|
||||
|
||||
final OsInfo mockOsInfo = mock(OsInfo.class);
|
||||
|
|
|
@ -67,10 +67,6 @@ testClusters.integTest {
|
|||
user username: "monitoring_agent", password: "x-pack-test-password", role: "remote_monitoring_agent"
|
||||
|
||||
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
|
||||
pluginsCount += 1
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
apply plugin: 'elasticsearch.esplugin'
|
||||
|
||||
esplugin {
|
||||
description 'A bootstrap plugin that adds support for interfacing with filesystem that enforce user quotas.'
|
||||
type = 'bootstrap'
|
||||
javaOpts = '-Djava.nio.file.spi.DefaultFileSystemProvider=org.elasticsearch.fs.quotaaware.QuotaAwareFileSystemProvider'
|
||||
licensed true
|
||||
}
|
|
@ -1,21 +1,9 @@
|
|||
/*
|
||||
* 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.
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.fs.quotaaware;
|
||||
|
||||
import java.io.IOException;
|
|
@ -1,20 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.fs.quotaaware;
|
|
@ -1,20 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.fs.quotaaware;
|
|
@ -1,20 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.fs.quotaaware;
|
|
@ -1,20 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.fs.quotaaware;
|
|
@ -1,20 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.fs.quotaaware;
|
|
@ -1,20 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.fs.quotaaware;
|
|
@ -1,20 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.fs.quotaaware;
|
Loading…
Add table
Add a link
Reference in a new issue