Bootstrap does not set system properties
Today, certain bootstrap properties are set and read via system properties. This action-at-distance way of managing these properties is rather confusing, and completely unnecessary. But another problem exists with setting these as system properties. Namely, these system properties are interpreted as Elasticsearch settings, not all of which are registered. This leads to Elasticsearch failing to startup if any of these special properties are set. Instead, these properties should be kept as local as possible, and passed around as method parameters where needed. This eliminates the action-at-distance way of handling these properties, and eliminates the need to register these non-setting properties. This commit does exactly that. Additionally, today we use the "-D" command line flag to set the properties, but this is confusing because "-D" is a special flag to the JVM for setting system properties. This creates confusion because some "-D" properties should be passed via arguments to the JVM (so via ES_JAVA_OPTS), and some should be passed as arguments to Elasticsearch. This commit changes the "-D" flag for Elasticsearch settings to "-E".
This commit is contained in:
parent
8ac5a98b87
commit
8a05c2a2be
|
@ -407,6 +407,7 @@ class BuildPlugin implements Plugin<Project> {
|
|||
systemProperty 'jna.nosys', 'true'
|
||||
// default test sysprop values
|
||||
systemProperty 'tests.ifNoTests', 'fail'
|
||||
// TODO: remove setting logging level via system property
|
||||
systemProperty 'es.logger.level', 'WARN'
|
||||
for (Map.Entry<String, String> property : System.properties.entrySet()) {
|
||||
if (property.getKey().startsWith('tests.') ||
|
||||
|
|
|
@ -73,6 +73,8 @@ class ClusterConfiguration {
|
|||
return tmpFile.exists()
|
||||
}
|
||||
|
||||
Map<String, String> esSettings = new HashMap<>();
|
||||
|
||||
Map<String, String> systemProperties = new HashMap<>()
|
||||
|
||||
Map<String, String> settings = new HashMap<>()
|
||||
|
@ -86,6 +88,11 @@ class ClusterConfiguration {
|
|||
|
||||
LinkedHashMap<String, Object[]> setupCommands = new LinkedHashMap<>()
|
||||
|
||||
@Input
|
||||
void esSetting(String setting, String value) {
|
||||
esSettings.put(setting, value);
|
||||
}
|
||||
|
||||
@Input
|
||||
void systemProperty(String property, String value) {
|
||||
systemProperties.put(property, value)
|
||||
|
|
|
@ -129,14 +129,16 @@ class NodeInfo {
|
|||
'JAVA_HOME' : project.javaHome,
|
||||
'ES_GC_OPTS': config.jvmArgs // we pass these with the undocumented gc opts so the argline can set gc, etc
|
||||
]
|
||||
args.add("-Des.node.portsfile=true")
|
||||
args.addAll(config.systemProperties.collect { key, value -> "-D${key}=${value}" })
|
||||
args.addAll("-E", "es.node.portsfile=true")
|
||||
args.addAll(config.esSettings.collectMany { key, value -> ["-E", "${key}=${value}" ] })
|
||||
env.put('ES_JAVA_OPTS', config.systemProperties.collect { key, value -> "-D${key}=${value}" }.join(" "))
|
||||
for (Map.Entry<String, String> property : System.properties.entrySet()) {
|
||||
if (property.getKey().startsWith('es.')) {
|
||||
args.add("-D${property.getKey()}=${property.getValue()}")
|
||||
args.add("-E")
|
||||
args.add("${property.getKey()}=${property.getValue()}")
|
||||
}
|
||||
}
|
||||
args.add("-Des.path.conf=${confDir}")
|
||||
args.addAll("-E", "es.path.conf=${confDir}")
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
args.add('"') // end the entire command, quoted
|
||||
}
|
||||
|
|
|
@ -259,7 +259,6 @@
|
|||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]update[/\\]UpdateRequest.java" checks="LineLength" />
|
||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]update[/\\]UpdateRequestBuilder.java" checks="LineLength" />
|
||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]bootstrap[/\\]Bootstrap.java" checks="LineLength" />
|
||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]bootstrap[/\\]BootstrapCLIParser.java" checks="LineLength" />
|
||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]bootstrap[/\\]JNAKernel32Library.java" checks="LineLength" />
|
||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]bootstrap[/\\]JNANatives.java" checks="LineLength" />
|
||||
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]bootstrap[/\\]JVMCheck.java" checks="LineLength" />
|
||||
|
@ -1597,7 +1596,6 @@
|
|||
<suppress files="plugins[/\\]repository-s3[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]cloud[/\\]aws[/\\]blobstore[/\\]MockDefaultS3OutputStream.java" checks="LineLength" />
|
||||
<suppress files="plugins[/\\]repository-s3[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]repositories[/\\]s3[/\\]AbstractS3SnapshotRestoreTest.java" checks="LineLength" />
|
||||
<suppress files="plugins[/\\]store-smb[/\\]src[/\\]main[/\\]java[/\\]org[/\\]apache[/\\]lucene[/\\]store[/\\]SmbDirectoryWrapper.java" checks="LineLength" />
|
||||
<suppress files="qa[/\\]evil-tests[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]bootstrap[/\\]BootstrapCliParserTests.java" checks="LineLength" />
|
||||
<suppress files="qa[/\\]evil-tests[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]bootstrap[/\\]ESPolicyUnitTests.java" checks="LineLength" />
|
||||
<suppress files="qa[/\\]evil-tests[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]bootstrap[/\\]EvilSecurityTests.java" checks="LineLength" />
|
||||
<suppress files="qa[/\\]evil-tests[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]cli[/\\]CheckFileCommandTests.java" checks="LineLength" />
|
||||
|
|
|
@ -19,21 +19,14 @@
|
|||
|
||||
package org.elasticsearch.bootstrap;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import org.apache.lucene.util.Constants;
|
||||
import org.apache.lucene.util.IOUtils;
|
||||
import org.apache.lucene.util.StringHelper;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cli.ExitCodes;
|
||||
import org.elasticsearch.cli.Terminal;
|
||||
import org.elasticsearch.common.PidFile;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.inject.CreationException;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
|
@ -47,7 +40,13 @@ import org.elasticsearch.monitor.process.ProcessProbe;
|
|||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
||||
|
||||
import static org.elasticsearch.common.settings.Settings.Builder.EMPTY_SETTINGS;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* Internal startup code.
|
||||
|
@ -189,9 +188,14 @@ final class Bootstrap {
|
|||
node = new Node(nodeSettings);
|
||||
}
|
||||
|
||||
private static Environment initialSettings(boolean foreground) {
|
||||
Terminal terminal = foreground ? Terminal.DEFAULT : null;
|
||||
return InternalSettingsPreparer.prepareEnvironment(EMPTY_SETTINGS, terminal);
|
||||
private static Environment initialSettings(boolean daemonize, String pathHome, String pidFile) {
|
||||
Terminal terminal = daemonize ? null : Terminal.DEFAULT;
|
||||
Settings.Builder builder = Settings.builder();
|
||||
builder.put(Environment.PATH_HOME_SETTING.getKey(), pathHome);
|
||||
if (Strings.hasLength(pidFile)) {
|
||||
builder.put(Environment.PIDFILE_SETTING.getKey(), pidFile);
|
||||
}
|
||||
return InternalSettingsPreparer.prepareEnvironment(builder.build(), terminal);
|
||||
}
|
||||
|
||||
private void start() {
|
||||
|
@ -218,22 +222,19 @@ final class Bootstrap {
|
|||
* This method is invoked by {@link Elasticsearch#main(String[])}
|
||||
* to startup elasticsearch.
|
||||
*/
|
||||
static void init(String[] args) throws Throwable {
|
||||
static void init(
|
||||
final boolean daemonize,
|
||||
final String pathHome,
|
||||
final String pidFile,
|
||||
final Map<String, String> esSettings) throws Throwable {
|
||||
// Set the system property before anything has a chance to trigger its use
|
||||
initLoggerPrefix();
|
||||
|
||||
BootstrapCliParser parser = new BootstrapCliParser();
|
||||
int status = parser.main(args, Terminal.DEFAULT);
|
||||
|
||||
if (parser.shouldRun() == false || status != ExitCodes.OK) {
|
||||
exit(status);
|
||||
}
|
||||
elasticsearchSettings(esSettings);
|
||||
|
||||
INSTANCE = new Bootstrap();
|
||||
|
||||
boolean foreground = !"false".equals(System.getProperty("es.foreground", System.getProperty("es-foreground")));
|
||||
|
||||
Environment environment = initialSettings(foreground);
|
||||
Environment environment = initialSettings(daemonize, pathHome, pidFile);
|
||||
Settings settings = environment.settings();
|
||||
LogConfigurator.configure(settings, true);
|
||||
checkForCustomConfFile();
|
||||
|
@ -249,7 +250,7 @@ final class Bootstrap {
|
|||
}
|
||||
|
||||
try {
|
||||
if (!foreground) {
|
||||
if (daemonize) {
|
||||
Loggers.disableConsoleLogging();
|
||||
closeSystOut();
|
||||
}
|
||||
|
@ -264,12 +265,12 @@ final class Bootstrap {
|
|||
|
||||
INSTANCE.start();
|
||||
|
||||
if (!foreground) {
|
||||
if (daemonize) {
|
||||
closeSysError();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
// disable console logging, so user does not see the exception twice (jvm will show it already)
|
||||
if (foreground) {
|
||||
if (!daemonize) {
|
||||
Loggers.disableConsoleLogging();
|
||||
}
|
||||
ESLogger logger = Loggers.getLogger(Bootstrap.class);
|
||||
|
@ -289,7 +290,7 @@ final class Bootstrap {
|
|||
logger.error("Exception", e);
|
||||
}
|
||||
// re-enable it if appropriate, so they can see any logging during the shutdown process
|
||||
if (foreground) {
|
||||
if (!daemonize) {
|
||||
Loggers.enableConsoleLogging();
|
||||
}
|
||||
|
||||
|
@ -297,6 +298,13 @@ final class Bootstrap {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "Sets system properties passed as CLI parameters")
|
||||
private static void elasticsearchSettings(Map<String, String> esSettings) {
|
||||
for (Map.Entry<String, String> esSetting : esSettings.entrySet()) {
|
||||
System.setProperty(esSetting.getKey(), esSetting.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "System#out")
|
||||
private static void closeSystOut() {
|
||||
System.out.close();
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
import org.elasticsearch.Build;
|
||||
import org.elasticsearch.cli.Command;
|
||||
import org.elasticsearch.cli.ExitCodes;
|
||||
import org.elasticsearch.cli.UserError;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.cli.Terminal;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.monitor.jvm.JvmInfo;
|
||||
|
||||
final class BootstrapCliParser extends Command {
|
||||
|
||||
private final OptionSpec<Void> versionOption;
|
||||
private final OptionSpec<Void> daemonizeOption;
|
||||
private final OptionSpec<String> pidfileOption;
|
||||
private final OptionSpec<String> propertyOption;
|
||||
private boolean shouldRun = false;
|
||||
|
||||
BootstrapCliParser() {
|
||||
super("Starts elasticsearch");
|
||||
// TODO: in jopt-simple 5.0, make this mutually exclusive with all other options
|
||||
versionOption = parser.acceptsAll(Arrays.asList("V", "version"),
|
||||
"Prints elasticsearch version information and exits");
|
||||
daemonizeOption = parser.acceptsAll(Arrays.asList("d", "daemonize"),
|
||||
"Starts Elasticsearch in the background");
|
||||
// TODO: in jopt-simple 5.0 this option type can be a Path
|
||||
pidfileOption = parser.acceptsAll(Arrays.asList("p", "pidfile"),
|
||||
"Creates a pid file in the specified path on start")
|
||||
.withRequiredArg();
|
||||
propertyOption = parser.accepts("D", "Configures an Elasticsearch setting")
|
||||
.withRequiredArg();
|
||||
}
|
||||
|
||||
// TODO: don't use system properties as a way to do this, its horrible...
|
||||
@SuppressForbidden(reason = "Sets system properties passed as CLI parameters")
|
||||
@Override
|
||||
protected void execute(Terminal terminal, OptionSet options) throws Exception {
|
||||
if (options.has(versionOption)) {
|
||||
terminal.println("Version: " + org.elasticsearch.Version.CURRENT
|
||||
+ ", Build: " + Build.CURRENT.shortHash() + "/" + Build.CURRENT.date()
|
||||
+ ", JVM: " + JvmInfo.jvmInfo().version());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: don't use sysprops for any of these! pass the args through to bootstrap...
|
||||
if (options.has(daemonizeOption)) {
|
||||
System.setProperty("es.foreground", "false");
|
||||
}
|
||||
String pidFile = pidfileOption.value(options);
|
||||
if (Strings.isNullOrEmpty(pidFile) == false) {
|
||||
System.setProperty("es.pidfile", pidFile);
|
||||
}
|
||||
|
||||
for (String property : propertyOption.values(options)) {
|
||||
String[] keyValue = property.split("=", 2);
|
||||
if (keyValue.length != 2) {
|
||||
throw new UserError(ExitCodes.USAGE, "Malformed elasticsearch setting, must be of the form key=value");
|
||||
}
|
||||
String key = keyValue[0];
|
||||
if (key.startsWith("es.") == false) {
|
||||
key = "es." + key;
|
||||
}
|
||||
System.setProperty(key, keyValue[1]);
|
||||
}
|
||||
shouldRun = true;
|
||||
}
|
||||
|
||||
boolean shouldRun() {
|
||||
return shouldRun;
|
||||
}
|
||||
}
|
|
@ -19,23 +19,98 @@
|
|||
|
||||
package org.elasticsearch.bootstrap;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
import joptsimple.util.KeyValuePair;
|
||||
import org.elasticsearch.Build;
|
||||
import org.elasticsearch.cli.Command;
|
||||
import org.elasticsearch.cli.ExitCodes;
|
||||
import org.elasticsearch.cli.Terminal;
|
||||
import org.elasticsearch.cli.UserError;
|
||||
import org.elasticsearch.monitor.jvm.JvmInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class starts elasticsearch.
|
||||
*/
|
||||
public final class Elasticsearch {
|
||||
class Elasticsearch extends Command {
|
||||
|
||||
private final OptionSpec<Void> versionOption;
|
||||
private final OptionSpec<Void> daemonizeOption;
|
||||
private final OptionSpec<String> pathHomeOption;
|
||||
private final OptionSpec<String> pidfileOption;
|
||||
private final OptionSpec<KeyValuePair> propertyOption;
|
||||
|
||||
/** no instantiation */
|
||||
private Elasticsearch() {}
|
||||
Elasticsearch() {
|
||||
super("starts elasticsearch");
|
||||
// TODO: in jopt-simple 5.0, make this mutually exclusive with all other options
|
||||
versionOption = parser.acceptsAll(Arrays.asList("V", "version"),
|
||||
"Prints elasticsearch version information and exits");
|
||||
daemonizeOption = parser.acceptsAll(Arrays.asList("d", "daemonize"),
|
||||
"Starts Elasticsearch in the background");
|
||||
// TODO: in jopt-simple 5.0 this option type can be a Path
|
||||
pathHomeOption = parser.acceptsAll(Arrays.asList("H", "path.home"), "").withRequiredArg();
|
||||
// TODO: in jopt-simple 5.0 this option type can be a Path
|
||||
pidfileOption = parser.acceptsAll(Arrays.asList("p", "pidfile"),
|
||||
"Creates a pid file in the specified path on start")
|
||||
.withRequiredArg();
|
||||
propertyOption = parser.accepts("E", "Configure an Elasticsearch setting").withRequiredArg().ofType(KeyValuePair.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point for starting elasticsearch
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
public static void main(final String[] args) throws Exception {
|
||||
final Elasticsearch elasticsearch = new Elasticsearch();
|
||||
int status = main(args, elasticsearch, Terminal.DEFAULT);
|
||||
if (status != ExitCodes.OK) {
|
||||
exit(status);
|
||||
}
|
||||
}
|
||||
|
||||
static int main(final String[] args, final Elasticsearch elasticsearch, final Terminal terminal) throws Exception {
|
||||
return elasticsearch.main(args, terminal);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(Terminal terminal, OptionSet options) throws Exception {
|
||||
if (options.has(versionOption)) {
|
||||
if (options.has(daemonizeOption) || options.has(pathHomeOption) || options.has(pidfileOption)) {
|
||||
throw new UserError(ExitCodes.USAGE, "Elasticsearch version option is mutually exclusive with any other option");
|
||||
}
|
||||
terminal.println("Version: " + org.elasticsearch.Version.CURRENT
|
||||
+ ", Build: " + Build.CURRENT.shortHash() + "/" + Build.CURRENT.date()
|
||||
+ ", JVM: " + JvmInfo.jvmInfo().version());
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean daemonize = options.has(daemonizeOption);
|
||||
final String pathHome = pathHomeOption.value(options);
|
||||
final String pidFile = pidfileOption.value(options);
|
||||
|
||||
final Map<String, String> esSettings = new HashMap<>();
|
||||
for (final KeyValuePair kvp : propertyOption.values(options)) {
|
||||
if (!kvp.key.startsWith("es.")) {
|
||||
throw new UserError(ExitCodes.USAGE, "Elasticsearch settings must be prefixed with [es.] but was [" + kvp.key + "]");
|
||||
}
|
||||
if (kvp.value.isEmpty()) {
|
||||
throw new UserError(ExitCodes.USAGE, "Elasticsearch setting [" + kvp.key + "] must not be empty");
|
||||
}
|
||||
esSettings.put(kvp.key, kvp.value);
|
||||
}
|
||||
|
||||
init(daemonize, pathHome, pidFile, esSettings);
|
||||
}
|
||||
|
||||
void init(final boolean daemonize, final String pathHome, final String pidFile, final Map<String, String> esSettings) {
|
||||
try {
|
||||
Bootstrap.init(args);
|
||||
} catch (Throwable t) {
|
||||
Bootstrap.init(daemonize, pathHome, pidFile, esSettings);
|
||||
} catch (final Throwable t) {
|
||||
// format exceptions to the console in a special way
|
||||
// to avoid 2MB stacktraces from guice, etc.
|
||||
throw new StartupError(t);
|
||||
|
|
|
@ -110,9 +110,7 @@ public class LogConfigurator {
|
|||
if (resolveConfig) {
|
||||
resolveConfig(environment, settingsBuilder);
|
||||
}
|
||||
settingsBuilder
|
||||
.putProperties("elasticsearch.", BootstrapInfo.getSystemProperties())
|
||||
.putProperties("es.", BootstrapInfo.getSystemProperties());
|
||||
settingsBuilder.putProperties("es.", BootstrapInfo.getSystemProperties());
|
||||
// add custom settings after config was added so that they are not overwritten by config
|
||||
settingsBuilder.put(settings);
|
||||
settingsBuilder.replacePropertyPlaceholders();
|
||||
|
|
|
@ -1136,10 +1136,10 @@ public final class Settings implements ToXContent {
|
|||
* @param properties The properties to put
|
||||
* @return The builder
|
||||
*/
|
||||
public Builder putProperties(String prefix, Dictionary<Object,Object> properties) {
|
||||
for (Object key1 : Collections.list(properties.keys())) {
|
||||
String key = Objects.toString(key1);
|
||||
String value = Objects.toString(properties.get(key));
|
||||
public Builder putProperties(String prefix, Dictionary<Object, Object> properties) {
|
||||
for (Object property : Collections.list(properties.keys())) {
|
||||
String key = Objects.toString(property);
|
||||
String value = Objects.toString(properties.get(property));
|
||||
if (key.startsWith(prefix)) {
|
||||
map.put(key.substring(prefix.length()), value);
|
||||
}
|
||||
|
@ -1154,19 +1154,12 @@ public final class Settings implements ToXContent {
|
|||
* @param properties The properties to put
|
||||
* @return The builder
|
||||
*/
|
||||
public Builder putProperties(String prefix, Dictionary<Object,Object> properties, String[] ignorePrefixes) {
|
||||
for (Object key1 : Collections.list(properties.keys())) {
|
||||
String key = Objects.toString(key1);
|
||||
String value = Objects.toString(properties.get(key));
|
||||
public Builder putProperties(String prefix, Dictionary<Object, Object> properties, String ignorePrefix) {
|
||||
for (Object property : Collections.list(properties.keys())) {
|
||||
String key = Objects.toString(property);
|
||||
String value = Objects.toString(properties.get(property));
|
||||
if (key.startsWith(prefix)) {
|
||||
boolean ignore = false;
|
||||
for (String ignorePrefix : ignorePrefixes) {
|
||||
if (key.startsWith(ignorePrefix)) {
|
||||
ignore = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ignore) {
|
||||
if (!key.startsWith(ignorePrefix)) {
|
||||
map.put(key.substring(prefix.length()), value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ import static org.elasticsearch.common.settings.Settings.settingsBuilder;
|
|||
public class InternalSettingsPreparer {
|
||||
|
||||
private static final String[] ALLOWED_SUFFIXES = {".yml", ".yaml", ".json", ".properties"};
|
||||
static final String[] PROPERTY_PREFIXES = {"es.", "elasticsearch."};
|
||||
static final String[] PROPERTY_DEFAULTS_PREFIXES = {"es.default.", "elasticsearch.default."};
|
||||
static final String PROPERTY_PREFIX = "es.";
|
||||
static final String PROPERTY_DEFAULTS_PREFIX = "es.default.";
|
||||
|
||||
public static final String SECRET_PROMPT_VALUE = "${prompt.secret}";
|
||||
public static final String TEXT_PROMPT_VALUE = "${prompt.text}";
|
||||
|
@ -126,13 +126,9 @@ public class InternalSettingsPreparer {
|
|||
output.put(input);
|
||||
if (useSystemProperties(input)) {
|
||||
if (loadDefaults) {
|
||||
for (String prefix : PROPERTY_DEFAULTS_PREFIXES) {
|
||||
output.putProperties(prefix, BootstrapInfo.getSystemProperties());
|
||||
}
|
||||
}
|
||||
for (String prefix : PROPERTY_PREFIXES) {
|
||||
output.putProperties(prefix, BootstrapInfo.getSystemProperties(), PROPERTY_DEFAULTS_PREFIXES);
|
||||
output.putProperties(PROPERTY_DEFAULTS_PREFIX, BootstrapInfo.getSystemProperties());
|
||||
}
|
||||
output.putProperties(PROPERTY_PREFIX, BootstrapInfo.getSystemProperties(), PROPERTY_DEFAULTS_PREFIX);
|
||||
}
|
||||
output.replacePropertyPlaceholders();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import org.elasticsearch.Build;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cli.ExitCodes;
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.monitor.jvm.JvmInfo;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasEntry;
|
||||
|
||||
public class ElasticsearchCommandLineParsingTests extends ESTestCase {
|
||||
|
||||
public void testVersion() throws Exception {
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "-d");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "--daemonize");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "-H", "/tmp/home");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "--path.home", "/tmp/home");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "-p", "/tmp/pid");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "--pidfile", "/tmp/pid");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "-d");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "--daemonize");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "-H", "/tmp/home");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "--path.home", "/tmp/home");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "-p", "/tmp/pid");
|
||||
runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "--pidfile", "/tmp/pid");
|
||||
runTestThatVersionIsReturned("-V");
|
||||
runTestThatVersionIsReturned("--version");
|
||||
}
|
||||
|
||||
private void runTestThatVersionIsMutuallyExclusiveToOtherOptions(String... args) throws Exception {
|
||||
runTestVersion(
|
||||
ExitCodes.USAGE,
|
||||
output -> assertThat(
|
||||
output,
|
||||
containsString("ERROR: Elasticsearch version option is mutually exclusive with any other option")),
|
||||
args);
|
||||
}
|
||||
|
||||
private void runTestThatVersionIsReturned(String... args) throws Exception {
|
||||
runTestVersion(ExitCodes.OK, output -> {
|
||||
assertThat(output, containsString("Version: " + Version.CURRENT.toString()));
|
||||
assertThat(output, containsString("Build: " + Build.CURRENT.shortHash() + "/" + Build.CURRENT.date()));
|
||||
assertThat(output, containsString("JVM: " + JvmInfo.jvmInfo().version()));
|
||||
}, args);
|
||||
}
|
||||
|
||||
private void runTestVersion(int expectedStatus, Consumer<String> outputConsumer, String... args) throws Exception {
|
||||
runTest(expectedStatus, false, outputConsumer, (daemonize, pathHome, pidFile, esSettings) -> {}, args);
|
||||
}
|
||||
|
||||
public void testThatPidFileCanBeConfigured() throws Exception {
|
||||
runPidFileTest(ExitCodes.USAGE, false, output -> assertThat(output, containsString("Option p/pidfile requires an argument")), "-p");
|
||||
runPidFileTest(ExitCodes.OK, true, output -> {}, "-p", "/tmp/pid");
|
||||
runPidFileTest(ExitCodes.OK, true, output -> {}, "--pidfile", "/tmp/pid");
|
||||
}
|
||||
|
||||
private void runPidFileTest(final int expectedStatus, final boolean expectedInit, Consumer<String> outputConsumer, final String... args)
|
||||
throws Exception {
|
||||
runTest(
|
||||
expectedStatus,
|
||||
expectedInit,
|
||||
outputConsumer,
|
||||
(daemonize, pathHome, pidFile, esSettings) -> assertThat(pidFile, equalTo("/tmp/pid")),
|
||||
args);
|
||||
}
|
||||
|
||||
public void testThatParsingDaemonizeWorks() throws Exception {
|
||||
runDaemonizeTest(true, "-d");
|
||||
runDaemonizeTest(true, "--daemonize");
|
||||
runDaemonizeTest(false);
|
||||
}
|
||||
|
||||
private void runDaemonizeTest(final boolean expectedDaemonize, final String... args) throws Exception {
|
||||
runTest(
|
||||
ExitCodes.OK,
|
||||
true,
|
||||
output -> {},
|
||||
(daemonize, pathHome, pidFile, esSettings) -> assertThat(daemonize, equalTo(expectedDaemonize)),
|
||||
args);
|
||||
}
|
||||
|
||||
public void testElasticsearchSettings() throws Exception {
|
||||
runTest(
|
||||
ExitCodes.OK,
|
||||
true,
|
||||
output -> {},
|
||||
(daemonize, pathHome, pidFile, esSettings) -> {
|
||||
assertThat(esSettings.size(), equalTo(2));
|
||||
assertThat(esSettings, hasEntry("es.foo", "bar"));
|
||||
assertThat(esSettings, hasEntry("es.baz", "qux"));
|
||||
},
|
||||
"-Ees.foo=bar", "-E", "es.baz=qux"
|
||||
);
|
||||
}
|
||||
|
||||
public void testElasticsearchSettingPrefix() throws Exception {
|
||||
runElasticsearchSettingPrefixTest("-E", "foo");
|
||||
runElasticsearchSettingPrefixTest("-E", "foo=bar");
|
||||
runElasticsearchSettingPrefixTest("-E", "=bar");
|
||||
}
|
||||
|
||||
private void runElasticsearchSettingPrefixTest(String... args) throws Exception {
|
||||
runTest(
|
||||
ExitCodes.USAGE,
|
||||
false,
|
||||
output -> assertThat(output, containsString("Elasticsearch settings must be prefixed with [es.] but was [")),
|
||||
(daemonize, pathHome, pidFile, esSettings) -> {},
|
||||
args
|
||||
);
|
||||
}
|
||||
|
||||
public void testElasticsearchSettingCanNotBeEmpty() throws Exception {
|
||||
runTest(
|
||||
ExitCodes.USAGE,
|
||||
false,
|
||||
output -> assertThat(output, containsString("Elasticsearch setting [es.foo] must not be empty")),
|
||||
(daemonize, pathHome, pidFile, esSettings) -> {},
|
||||
"-E", "es.foo="
|
||||
);
|
||||
}
|
||||
|
||||
public void testUnknownOption() throws Exception {
|
||||
runTest(
|
||||
ExitCodes.USAGE,
|
||||
false,
|
||||
output -> assertThat(output, containsString("network.host is not a recognized option")),
|
||||
(daemonize, pathHome, pidFile, esSettings) -> {},
|
||||
"--network.host");
|
||||
}
|
||||
|
||||
private interface InitConsumer {
|
||||
void accept(final boolean daemonize, final String pathHome, final String pidFile, final Map<String, String> esSettings);
|
||||
}
|
||||
|
||||
private void runTest(
|
||||
final int expectedStatus,
|
||||
final boolean expectedInit,
|
||||
final Consumer<String> outputConsumer,
|
||||
final InitConsumer initConsumer,
|
||||
String... args) throws Exception {
|
||||
final MockTerminal terminal = new MockTerminal();
|
||||
try {
|
||||
final AtomicBoolean init = new AtomicBoolean();
|
||||
final int status = Elasticsearch.main(args, new Elasticsearch() {
|
||||
@Override
|
||||
void init(final boolean daemonize, final String pathHome, final String pidFile, final Map<String, String> esSettings) {
|
||||
init.set(true);
|
||||
initConsumer.accept(daemonize, pathHome, pidFile, esSettings);
|
||||
}
|
||||
}, terminal);
|
||||
assertThat(status, equalTo(expectedStatus));
|
||||
assertThat(init.get(), equalTo(expectedInit));
|
||||
outputConsumer.accept(terminal.getOutput());
|
||||
} catch (Throwable t) {
|
||||
// if an unexpected exception is thrown, we log
|
||||
// terminal output to aid debugging
|
||||
logger.info(terminal.getOutput());
|
||||
// rethrow so the test fails
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
# you can override this using by setting a system property, for example -Des.logger.level=DEBUG
|
||||
# you can override this using by setting a system property, for example -Ees.logger.level=DEBUG
|
||||
es.logger.level: INFO
|
||||
rootLogger: ${es.logger.level}, console
|
||||
logger:
|
||||
|
|
|
@ -99,7 +99,7 @@ fi
|
|||
# Define other required variables
|
||||
PID_FILE="$PID_DIR/$NAME.pid"
|
||||
DAEMON=$ES_HOME/bin/elasticsearch
|
||||
DAEMON_OPTS="-d -p $PID_FILE -D es.default.path.home=$ES_HOME -D es.default.path.logs=$LOG_DIR -D es.default.path.data=$DATA_DIR -D es.default.path.conf=$CONF_DIR"
|
||||
DAEMON_OPTS="-d -p $PID_FILE -Ees.default.path.home=$ES_HOME -Ees.default.path.logs=$LOG_DIR -Ees.default.path.data=$DATA_DIR -Ees.default.path.conf=$CONF_DIR"
|
||||
|
||||
export ES_HEAP_SIZE
|
||||
export ES_HEAP_NEWSIZE
|
||||
|
|
|
@ -117,7 +117,7 @@ start() {
|
|||
cd $ES_HOME
|
||||
echo -n $"Starting $prog: "
|
||||
# if not running, start it up here, usually something like "daemon $exec"
|
||||
daemon --user $ES_USER --pidfile $pidfile $exec -p $pidfile -d -D es.default.path.home=$ES_HOME -D es.default.path.logs=$LOG_DIR -D es.default.path.data=$DATA_DIR -D es.default.path.conf=$CONF_DIR
|
||||
daemon --user $ES_USER --pidfile $pidfile $exec -p $pidfile -d -Ees.default.path.home=$ES_HOME -Ees.default.path.logs=$LOG_DIR -Ees.default.path.data=$DATA_DIR -Ees.default.path.conf=$CONF_DIR
|
||||
retval=$?
|
||||
echo
|
||||
[ $retval -eq 0 ] && touch $lockfile
|
||||
|
|
|
@ -20,11 +20,11 @@ Group=elasticsearch
|
|||
ExecStartPre=/usr/share/elasticsearch/bin/elasticsearch-systemd-pre-exec
|
||||
|
||||
ExecStart=/usr/share/elasticsearch/bin/elasticsearch \
|
||||
-Des.pidfile=${PID_DIR}/elasticsearch.pid \
|
||||
-Des.default.path.home=${ES_HOME} \
|
||||
-Des.default.path.logs=${LOG_DIR} \
|
||||
-Des.default.path.data=${DATA_DIR} \
|
||||
-Des.default.path.conf=${CONF_DIR}
|
||||
-Ees.pidfile=${PID_DIR}/elasticsearch.pid \
|
||||
-Ees.default.path.home=${ES_HOME} \
|
||||
-Ees.default.path.logs=${LOG_DIR} \
|
||||
-Ees.default.path.data=${DATA_DIR} \
|
||||
-Ees.default.path.conf=${CONF_DIR}
|
||||
|
||||
StandardOutput=journal
|
||||
StandardError=inherit
|
||||
|
|
|
@ -126,11 +126,11 @@ export HOSTNAME
|
|||
# manual parsing to find out, if process should be detached
|
||||
daemonized=`echo $* | egrep -- '(^-d |-d$| -d |--daemonize$|--daemonize )'`
|
||||
if [ -z "$daemonized" ] ; then
|
||||
exec "$JAVA" $JAVA_OPTS $ES_JAVA_OPTS -Des.path.home="$ES_HOME" -cp "$ES_CLASSPATH" \
|
||||
org.elasticsearch.bootstrap.Elasticsearch start "$@"
|
||||
exec "$JAVA" $JAVA_OPTS $ES_JAVA_OPTS -cp "$ES_CLASSPATH" \
|
||||
org.elasticsearch.bootstrap.Elasticsearch --path.home "$ES_HOME" "$@"
|
||||
else
|
||||
exec "$JAVA" $JAVA_OPTS $ES_JAVA_OPTS -Des.path.home="$ES_HOME" -cp "$ES_CLASSPATH" \
|
||||
org.elasticsearch.bootstrap.Elasticsearch start "$@" <&- &
|
||||
exec "$JAVA" $JAVA_OPTS $ES_JAVA_OPTS -cp "$ES_CLASSPATH" \
|
||||
org.elasticsearch.bootstrap.Elasticsearch --path.home "$ES_HOME" "$@" <&- &
|
||||
retval=$?
|
||||
pid=$!
|
||||
[ $retval -eq 0 ] || exit $retval
|
||||
|
|
|
@ -48,7 +48,7 @@ GOTO loop
|
|||
|
||||
SET HOSTNAME=%COMPUTERNAME%
|
||||
|
||||
"%JAVA_HOME%\bin\java" -client -Des.path.home="%ES_HOME%" !properties! -cp "%ES_HOME%/lib/*;" "org.elasticsearch.plugins.PluginCli" !args!
|
||||
"%JAVA_HOME%\bin\java" -client -Ees.path.home="%ES_HOME%" !properties! -cp "%ES_HOME%/lib/*;" "org.elasticsearch.plugins.PluginCli" !args!
|
||||
goto finally
|
||||
|
||||
|
||||
|
|
|
@ -104,4 +104,4 @@ ECHO additional elements via the plugin mechanism, or if code must really be 1>&
|
|||
ECHO added to the main classpath, add jars to lib\, unsupported 1>&2
|
||||
EXIT /B 1
|
||||
)
|
||||
set ES_PARAMS=-Delasticsearch -Des-foreground=yes -Des.path.home="%ES_HOME%"
|
||||
set ES_PARAMS=-Delasticsearch -Ees.path.home="%ES_HOME%"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# you can override this using by setting a system property, for example -Des.logger.level=DEBUG
|
||||
# you can override this using by setting a system property, for example -Ees.logger.level=DEBUG
|
||||
es.logger.level: INFO
|
||||
rootLogger: ${es.logger.level}, console, file
|
||||
logger:
|
||||
|
|
|
@ -167,7 +167,7 @@ can do this as follows:
|
|||
|
||||
[source,sh]
|
||||
---------------------
|
||||
sudo bin/elasticsearch-plugin -Des.path.conf=/path/to/custom/config/dir install <plugin name>
|
||||
sudo bin/elasticsearch-plugin -Ees.path.conf=/path/to/custom/config/dir install <plugin name>
|
||||
---------------------
|
||||
|
||||
You can also set the `CONF_DIR` environment variable to the custom config
|
||||
|
|
|
@ -163,7 +163,7 @@ As mentioned previously, we can override either the cluster or node name. This c
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
./elasticsearch --cluster.name my_cluster_name --node.name my_node_name
|
||||
./elasticsearch -Ees.cluster.name=my_cluster_name -Ees.node.name=my_node_name
|
||||
--------------------------------------------------
|
||||
|
||||
Also note the line marked http with information about the HTTP address (`192.168.8.112`) and port (`9200`) that our node is reachable from. By default, Elasticsearch uses port `9200` to provide access to its REST API. This port is configurable if necessary.
|
||||
|
|
|
@ -14,7 +14,7 @@ attribute as follows:
|
|||
|
||||
[source,sh]
|
||||
------------------------
|
||||
bin/elasticsearch --node.rack rack1 --node.size big <1>
|
||||
bin/elasticsearch -Ees.node.rack=rack1 -Ees.node.size=big <1>
|
||||
------------------------
|
||||
<1> These attribute settings can also be specified in the `elasticsearch.yml` config file.
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ on startup if it is set too low.
|
|||
|
||||
==== Removed es.netty.gathering
|
||||
|
||||
Disabling Netty from using NIO gathering could be done via the escape
|
||||
Disabling Netty from using NIO gathring could be done via the escape
|
||||
hatch of setting the system property "es.netty.gathering" to "false".
|
||||
Time has proven enabling gathering by default is a non-issue and this
|
||||
non-documented setting has been removed.
|
||||
|
@ -172,3 +172,18 @@ Two cache concurrency level settings
|
|||
`indices.fielddata.cache.concurrency_level` because they no longer apply to
|
||||
the cache implementation used for the request cache and the field data cache.
|
||||
|
||||
==== Using system properties to configure Elasticsearch
|
||||
|
||||
Elasticsearch can be configured by setting system properties on the
|
||||
command line via `-Des.name.of.property=value.of.property`. This will be
|
||||
removed in a future version of Elasticsearch. Instead, use
|
||||
`-E es.name.of.setting=value.of.setting`. Note that in all cases the
|
||||
name of the setting must be prefixed with `es.`.
|
||||
|
||||
==== Removed using double-dashes to configure Elasticsearch
|
||||
|
||||
Elasticsearch could previously be configured on the command line by
|
||||
setting settings via `--name.of.setting value.of.setting`. This feature
|
||||
has been removed. Instead, use
|
||||
`-Ees.name.of.setting=value.of.setting`. Note that in all cases the
|
||||
name of the setting must be prefixed with `es.`.
|
||||
|
|
|
@ -21,7 +21,7 @@ attribute called `rack_id` -- we could use any attribute name. For example:
|
|||
|
||||
[source,sh]
|
||||
----------------------
|
||||
./bin/elasticsearch --node.rack_id rack_one <1>
|
||||
./bin/elasticsearch -Ees.node.rack_id=rack_one <1>
|
||||
----------------------
|
||||
<1> This setting could also be specified in the `elasticsearch.yml` config file.
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ Like all node settings, it can also be specified on the command line as:
|
|||
|
||||
[source,sh]
|
||||
-----------------------
|
||||
./bin/elasticsearch --path.data /var/elasticsearch/data
|
||||
./bin/elasticsearch -Ees.path.data=/var/elasticsearch/data
|
||||
-----------------------
|
||||
|
||||
TIP: When using the `.zip` or `.tar.gz` distributions, the `path.data` setting
|
||||
|
|
|
@ -67,13 +67,12 @@ There are added features when using the `elasticsearch` shell script.
|
|||
The first, which was explained earlier, is the ability to easily run the
|
||||
process either in the foreground or the background.
|
||||
|
||||
Another feature is the ability to pass `-D` or getopt long style
|
||||
configuration parameters directly to the script. When set, all override
|
||||
anything set using either `JAVA_OPTS` or `ES_JAVA_OPTS`. For example:
|
||||
Another feature is the ability to pass `-E` configuration parameters
|
||||
directly to the script. For example:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ bin/elasticsearch -Des.index.refresh_interval=5s --node.name=my-node
|
||||
$ bin/elasticsearch -Ees.index.refresh_interval=5s -Ees.node.name=my-node
|
||||
--------------------------------------------------
|
||||
*************************************************************************
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ command, for example:
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ elasticsearch -Des.network.host=10.0.0.4
|
||||
$ elasticsearch -Ees.network.host=10.0.0.4
|
||||
--------------------------------------------------
|
||||
|
||||
Another option is to set `es.default.` prefix instead of `es.` prefix,
|
||||
|
@ -336,7 +336,7 @@ course, the above can also be set as a "collapsed" setting, for example:
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ elasticsearch -Des.index.refresh_interval=5s
|
||||
$ elasticsearch -Ees.index.refresh_interval=5s
|
||||
--------------------------------------------------
|
||||
|
||||
All of the index level configuration can be found within each
|
||||
|
|
|
@ -80,7 +80,7 @@ To upgrade using a zip or compressed tarball:
|
|||
overwrite the `config` or `data` directories.
|
||||
|
||||
* Either copy the files in the `config` directory from your old installation
|
||||
to your new installation, or use the `--path.conf` option on the command
|
||||
to your new installation, or use the `-E path.conf=` option on the command
|
||||
line to point to an external config directory.
|
||||
|
||||
* Either copy the files in the `data` directory from your old installation
|
||||
|
|
|
@ -28,8 +28,8 @@ dependencies {
|
|||
|
||||
integTest {
|
||||
cluster {
|
||||
systemProperty 'es.script.inline', 'true'
|
||||
systemProperty 'es.script.indexed', 'true'
|
||||
esSetting 'es.script.inline', 'true'
|
||||
esSetting 'es.script.indexed', 'true'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ dependencies {
|
|||
|
||||
integTest {
|
||||
cluster {
|
||||
systemProperty 'es.script.inline', 'true'
|
||||
systemProperty 'es.script.indexed', 'true'
|
||||
esSetting 'es.script.inline', 'true'
|
||||
esSetting 'es.script.indexed', 'true'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ dependencies {
|
|||
|
||||
integTest {
|
||||
cluster {
|
||||
systemProperty 'es.script.inline', 'true'
|
||||
systemProperty 'es.script.indexed', 'true'
|
||||
esSetting 'es.script.inline', 'true'
|
||||
esSetting 'es.script.indexed', 'true'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ dependencies {
|
|||
|
||||
integTest {
|
||||
cluster {
|
||||
systemProperty 'es.script.inline', 'true'
|
||||
systemProperty 'es.script.indexed', 'true'
|
||||
esSetting 'es.script.inline', 'true'
|
||||
esSetting 'es.script.indexed', 'true'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import joptsimple.OptionException;
|
||||
import org.elasticsearch.Build;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cli.Command;
|
||||
import org.elasticsearch.cli.CommandTestCase;
|
||||
import org.elasticsearch.cli.UserError;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.monitor.jvm.JvmInfo;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
@SuppressForbidden(reason = "modifies system properties intentionally")
|
||||
public class BootstrapCliParserTests extends CommandTestCase {
|
||||
|
||||
@Override
|
||||
protected Command newCommand() {
|
||||
return new BootstrapCliParser();
|
||||
}
|
||||
|
||||
private List<String> propertiesToClear = new ArrayList<>();
|
||||
private Map<Object, Object> properties;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
this.properties = new HashMap<>(System.getProperties());
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearProperties() {
|
||||
for (String property : propertiesToClear) {
|
||||
System.clearProperty(property);
|
||||
}
|
||||
propertiesToClear.clear();
|
||||
assertEquals("properties leaked", properties, new HashMap<>(System.getProperties()));
|
||||
}
|
||||
|
||||
void assertShouldRun(boolean shouldRun) {
|
||||
BootstrapCliParser parser = (BootstrapCliParser)command;
|
||||
assertEquals(shouldRun, parser.shouldRun());
|
||||
}
|
||||
|
||||
public void testVersion() throws Exception {
|
||||
String output = execute("-V");
|
||||
assertTrue(output, output.contains(Version.CURRENT.toString()));
|
||||
assertTrue(output, output.contains(Build.CURRENT.shortHash()));
|
||||
assertTrue(output, output.contains(Build.CURRENT.date()));
|
||||
assertTrue(output, output.contains(JvmInfo.jvmInfo().version()));
|
||||
assertShouldRun(false);
|
||||
|
||||
terminal.reset();
|
||||
output = execute("--version");
|
||||
assertTrue(output, output.contains(Version.CURRENT.toString()));
|
||||
assertTrue(output, output.contains(Build.CURRENT.shortHash()));
|
||||
assertTrue(output, output.contains(Build.CURRENT.date()));
|
||||
assertTrue(output, output.contains(JvmInfo.jvmInfo().version()));
|
||||
assertShouldRun(false);
|
||||
}
|
||||
|
||||
public void testPidfile() throws Exception {
|
||||
registerProperties("es.pidfile");
|
||||
|
||||
// missing argument
|
||||
OptionException e = expectThrows(OptionException.class, () -> {
|
||||
execute("-p");
|
||||
});
|
||||
assertEquals("Option p/pidfile requires an argument", e.getMessage());
|
||||
assertShouldRun(false);
|
||||
|
||||
// good cases
|
||||
terminal.reset();
|
||||
execute("--pidfile", "/tmp/pid");
|
||||
assertSystemProperty("es.pidfile", "/tmp/pid");
|
||||
assertShouldRun(true);
|
||||
|
||||
System.clearProperty("es.pidfile");
|
||||
terminal.reset();
|
||||
execute("-p", "/tmp/pid");
|
||||
assertSystemProperty("es.pidfile", "/tmp/pid");
|
||||
assertShouldRun(true);
|
||||
}
|
||||
|
||||
public void testNoDaemonize() throws Exception {
|
||||
registerProperties("es.foreground");
|
||||
|
||||
execute();
|
||||
assertSystemProperty("es.foreground", null);
|
||||
assertShouldRun(true);
|
||||
}
|
||||
|
||||
public void testDaemonize() throws Exception {
|
||||
registerProperties("es.foreground");
|
||||
|
||||
execute("-d");
|
||||
assertSystemProperty("es.foreground", "false");
|
||||
assertShouldRun(true);
|
||||
|
||||
System.clearProperty("es.foreground");
|
||||
execute("--daemonize");
|
||||
assertSystemProperty("es.foreground", "false");
|
||||
assertShouldRun(true);
|
||||
}
|
||||
|
||||
public void testConfig() throws Exception {
|
||||
registerProperties("es.foo", "es.spam");
|
||||
|
||||
execute("-Dfoo=bar", "-Dspam=eggs");
|
||||
assertSystemProperty("es.foo", "bar");
|
||||
assertSystemProperty("es.spam", "eggs");
|
||||
assertShouldRun(true);
|
||||
}
|
||||
|
||||
public void testConfigMalformed() throws Exception {
|
||||
UserError e = expectThrows(UserError.class, () -> {
|
||||
execute("-Dfoo");
|
||||
});
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("Malformed elasticsearch setting"));
|
||||
}
|
||||
|
||||
public void testUnknownOption() throws Exception {
|
||||
OptionException e = expectThrows(OptionException.class, () -> {
|
||||
execute("--network.host");
|
||||
});
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("network.host is not a recognized option"));
|
||||
}
|
||||
|
||||
private void registerProperties(String ... systemProperties) {
|
||||
propertiesToClear.addAll(Arrays.asList(systemProperties));
|
||||
}
|
||||
|
||||
private void assertSystemProperty(String name, String expectedValue) throws Exception {
|
||||
String msg = String.format(Locale.ROOT, "Expected property %s to be %s, terminal output was %s", name, expectedValue, terminal.getOutput());
|
||||
assertThat(msg, System.getProperty(name), is(expectedValue));
|
||||
}
|
||||
}
|
|
@ -21,6 +21,6 @@ apply plugin: 'elasticsearch.rest-test'
|
|||
|
||||
integTest {
|
||||
cluster {
|
||||
systemProperty 'es.node.ingest', 'false'
|
||||
esSetting 'es.node.ingest', 'false'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,6 @@ apply plugin: 'elasticsearch.rest-test'
|
|||
|
||||
integTest {
|
||||
cluster {
|
||||
systemProperty 'es.script.inline', 'true'
|
||||
esSetting 'es.script.inline', 'true'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -303,7 +303,7 @@ run_elasticsearch_service() {
|
|||
# This line is attempting to emulate the on login behavior of /usr/share/upstart/sessions/jayatana.conf
|
||||
[ -f /usr/share/java/jayatanaag.jar ] && export JAVA_TOOL_OPTIONS="-javaagent:/usr/share/java/jayatanaag.jar"
|
||||
# And now we can start Elasticsearch normally, in the background (-d) and with a pidfile (-p).
|
||||
$timeoutCommand/tmp/elasticsearch/bin/elasticsearch $background -p /tmp/elasticsearch/elasticsearch.pid -Des.path.conf=$CONF_DIR $commandLineArgs
|
||||
$timeoutCommand/tmp/elasticsearch/bin/elasticsearch $background -p /tmp/elasticsearch/elasticsearch.pid -Ees.path.conf=$CONF_DIR $commandLineArgs
|
||||
BASH
|
||||
[ "$status" -eq "$expectedStatus" ]
|
||||
elif is_systemd; then
|
||||
|
|
|
@ -102,7 +102,7 @@ fi
|
|||
echo "CONF_FILE=$CONF_FILE" >> /etc/sysconfig/elasticsearch;
|
||||
fi
|
||||
|
||||
run_elasticsearch_service 1 -Des.default.config="$CONF_FILE"
|
||||
run_elasticsearch_service 1 -Ees.default.config="$CONF_FILE"
|
||||
|
||||
# remove settings again otherwise cleaning up before next testrun will fail
|
||||
if is_dpkg ; then
|
||||
|
@ -408,7 +408,7 @@ fi
|
|||
remove_jvm_example
|
||||
|
||||
local relativePath=${1:-$(readlink -m jvm-example-*.zip)}
|
||||
sudo -E -u $ESPLUGIN_COMMAND_USER "$ESHOME/bin/elasticsearch-plugin" install "file://$relativePath" -Des.logger.level=DEBUG > /tmp/plugin-cli-output
|
||||
sudo -E -u $ESPLUGIN_COMMAND_USER "$ESHOME/bin/elasticsearch-plugin" install "file://$relativePath" -Ees.logger.level=DEBUG > /tmp/plugin-cli-output
|
||||
local loglines=$(cat /tmp/plugin-cli-output | wc -l)
|
||||
if [ "$GROUP" == "TAR PLUGINS" ]; then
|
||||
[ "$loglines" -gt "7" ] || {
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* 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.common.cli;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.StreamsUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.isEmptyString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
public abstract class CliToolTestCase extends ESTestCase {
|
||||
|
||||
@Before
|
||||
@SuppressForbidden(reason = "sets es.default.path.home during tests")
|
||||
public void setPathHome() {
|
||||
System.setProperty("es.default.path.home", createTempDir().toString());
|
||||
}
|
||||
|
||||
@After
|
||||
@SuppressForbidden(reason = "clears es.default.path.home during tests")
|
||||
public void clearPathHome() {
|
||||
System.clearProperty("es.default.path.home");
|
||||
}
|
||||
|
||||
public static String[] args(String command) {
|
||||
if (!Strings.hasLength(command)) {
|
||||
return Strings.EMPTY_ARRAY;
|
||||
}
|
||||
return command.split("\\s+");
|
||||
}
|
||||
|
||||
public static void assertTerminalOutputContainsHelpFile(MockTerminal terminal, String classPath) throws IOException {
|
||||
String output = terminal.getOutput();
|
||||
assertThat(output, not(isEmptyString()));
|
||||
String expectedDocs = StreamsUtils.copyToStringFromClasspath(classPath);
|
||||
// convert to *nix newlines as MockTerminal used for tests also uses *nix newlines
|
||||
expectedDocs = expectedDocs.replace("\r\n", "\n");
|
||||
assertThat(output, containsString(expectedDocs));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue