From 9c2decdaaccf17bf56bea7c001472cb57626863d Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 13 Sep 2017 16:19:39 +0200 Subject: [PATCH 1/4] Expose recovered state to bootstrap checks This exposes the persistent part of the cluster state to the bootstrap checks to allow plugins to enforce certain preconditions based on the recovered state. --- .../org/elasticsearch/gateway/GatewayMetaState.java | 3 ++- .../org/elasticsearch/gateway/MetaStateService.java | 2 +- core/src/main/java/org/elasticsearch/node/Node.java | 13 ++++++++++++- .../main/java/org/elasticsearch/plugins/Plugin.java | 3 ++- .../test/java/org/elasticsearch/node/NodeTests.java | 4 +++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java b/core/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java index 99a51adf96183..9d57392030ce6 100644 --- a/core/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java +++ b/core/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java @@ -41,6 +41,7 @@ import org.elasticsearch.index.Index; import org.elasticsearch.plugins.MetaDataUpgrader; +import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; @@ -114,7 +115,7 @@ public GatewayMetaState(Settings settings, NodeEnvironment nodeEnv, MetaStateSer } } - public MetaData loadMetaState() throws Exception { + public MetaData loadMetaState() throws IOException { return metaStateService.loadFullState(); } diff --git a/core/src/main/java/org/elasticsearch/gateway/MetaStateService.java b/core/src/main/java/org/elasticsearch/gateway/MetaStateService.java index b900305ab55e1..5c820343cc807 100644 --- a/core/src/main/java/org/elasticsearch/gateway/MetaStateService.java +++ b/core/src/main/java/org/elasticsearch/gateway/MetaStateService.java @@ -53,7 +53,7 @@ public MetaStateService(Settings settings, NodeEnvironment nodeEnv, NamedXConten * Loads the full state, which includes both the global state and all the indices * meta state. */ - MetaData loadFullState() throws Exception { + MetaData loadFullState() throws IOException { MetaData globalMetaData = loadGlobalState(); MetaData.Builder metaDataBuilder; if (globalMetaData != null) { diff --git a/core/src/main/java/org/elasticsearch/node/Node.java b/core/src/main/java/org/elasticsearch/node/Node.java index 10d8ddcf2105d..e2747e6583d0c 100644 --- a/core/src/main/java/org/elasticsearch/node/Node.java +++ b/core/src/main/java/org/elasticsearch/node/Node.java @@ -86,6 +86,7 @@ import org.elasticsearch.env.Environment; import org.elasticsearch.env.NodeEnvironment; import org.elasticsearch.gateway.GatewayAllocator; +import org.elasticsearch.gateway.GatewayMetaState; import org.elasticsearch.gateway.GatewayModule; import org.elasticsearch.gateway.GatewayService; import org.elasticsearch.gateway.MetaStateService; @@ -139,6 +140,7 @@ import java.io.BufferedWriter; import java.io.Closeable; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -604,8 +606,17 @@ public Node start() throws NodeValidationException { assert localNodeFactory.getNode() != null; assert transportService.getLocalNode().equals(localNodeFactory.getNode()) : "transportService has a different local node than the factory provided"; + final MetaData onDiskMetadata; + try { + // we load the global state here (the persistent part of the cluster state stored on disk) to + // pass it to the bootstrap checks to allow plugins to enforce certain preconditions based on the recovered state. + onDiskMetadata = injector.getInstance(GatewayMetaState.class).loadMetaState(); + assert onDiskMetadata != null : "metadata is null but shouldn't"; // this is never null + } catch (IOException e) { + throw new UncheckedIOException(e); + } validateNodeBeforeAcceptingRequests(settings, transportService.boundAddress(), pluginsService.filterPlugins(Plugin.class).stream() - .flatMap(p -> p.getBootstrapChecks().stream()).collect(Collectors.toList())); + .flatMap(p -> p.getBootstrapChecks(onDiskMetadata).stream()).collect(Collectors.toList())); clusterService.addStateApplier(transportService.getTaskManager()); // start after transport service so the local disco is known diff --git a/core/src/main/java/org/elasticsearch/plugins/Plugin.java b/core/src/main/java/org/elasticsearch/plugins/Plugin.java index 82c8bf1bbcb18..62e1162e9ff8d 100644 --- a/core/src/main/java/org/elasticsearch/plugins/Plugin.java +++ b/core/src/main/java/org/elasticsearch/plugins/Plugin.java @@ -221,8 +221,9 @@ public List> getExecutorBuilders(Settings settings) { * interface. In this case we assume the node is running in production and all bootstrap checks must pass. This allows plugins * to provide a better out of the box experience by pre-configuring otherwise (in production) mandatory settings or to enforce certain * configurations like OS settings or 3rd party resources. + * @param metaData the on-disk metadata for this nodes. This allows bootstrap-checks based on the locally recovered cluster metadata */ - public List getBootstrapChecks() { return Collections.emptyList(); } + public List getBootstrapChecks(MetaData metaData) { return Collections.emptyList(); } /** * Close the resources opened by this plugin. diff --git a/core/src/test/java/org/elasticsearch/node/NodeTests.java b/core/src/test/java/org/elasticsearch/node/NodeTests.java index ec806799e71f6..d864729949421 100644 --- a/core/src/test/java/org/elasticsearch/node/NodeTests.java +++ b/core/src/test/java/org/elasticsearch/node/NodeTests.java @@ -23,6 +23,7 @@ import org.elasticsearch.Version; import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.cluster.ClusterName; +import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; @@ -76,7 +77,8 @@ public String errorMessage() { } }; @Override - public List getBootstrapChecks() { + public List getBootstrapChecks(MetaData metaData) { + assertNotNull(metaData); return Collections.singletonList(CHECK); } } From 5afc702ef09678089d922fddf362993545bbeda7 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 13 Sep 2017 18:02:32 +0200 Subject: [PATCH 2/4] cut over to bootstrap context --- .../elasticsearch/bootstrap/Bootstrap.java | 4 +- .../bootstrap/BootstrapCheck.java | 4 +- .../bootstrap/BootstrapChecks.java | 71 +++++------ .../bootstrap/BootstrapContext.java | 41 +++++++ .../java/org/elasticsearch/node/Node.java | 12 +- .../node/NodeValidationException.java | 4 +- .../org/elasticsearch/plugins/Plugin.java | 3 +- .../bootstrap/BootstrapChecksTests.java | 110 ++++++++++-------- .../org/elasticsearch/node/NodeTests.java | 9 +- .../bootstrap/EvilBootstrapChecksTests.java | 9 +- 10 files changed, 156 insertions(+), 111 deletions(-) create mode 100644 core/src/main/java/org/elasticsearch/bootstrap/BootstrapContext.java diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java index 840a62e5e916f..30b9fb7e28dd0 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java @@ -212,9 +212,9 @@ public void run() { node = new Node(environment) { @Override protected void validateNodeBeforeAcceptingRequests( - final Settings settings, + final BootstrapContext context, final BoundTransportAddress boundTransportAddress, List checks) throws NodeValidationException { - BootstrapChecks.check(settings, boundTransportAddress, checks); + BootstrapChecks.check(context, boundTransportAddress, checks); } }; } diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java index ffe52dfe5b957..a2620b2560c0d 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java @@ -27,9 +27,10 @@ public interface BootstrapCheck { /** * Test if the node fails the check. * + * @param context the bootstrap context for more sophisticated checks * @return {@code true} if the node failed the check */ - boolean check(); + boolean check(BootstrapContext context); /** * The error message for a failed check. @@ -41,5 +42,4 @@ public interface BootstrapCheck { default boolean alwaysEnforce() { return false; } - } diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java index 4adec75ae67a0..4414a912fe344 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java @@ -26,7 +26,6 @@ import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.logging.Loggers; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.discovery.DiscoveryModule; @@ -65,18 +64,18 @@ private BootstrapChecks() { * {@code es.enforce.bootstrap.checks} is set to {@code true} then the bootstrap checks will be enforced regardless of whether or not * the transport protocol is bound to a non-loopback interface. * - * @param settings the current node settings + * @param context the current node boostrap context * @param boundTransportAddress the node network bindings */ - static void check(final Settings settings, final BoundTransportAddress boundTransportAddress, List additionalChecks) - throws NodeValidationException { - final List builtInChecks = checks(settings); + static void check(final BootstrapContext context, final BoundTransportAddress boundTransportAddress, + List additionalChecks) throws NodeValidationException { + final List builtInChecks = checks(); final List combinedChecks = new ArrayList<>(builtInChecks); combinedChecks.addAll(additionalChecks); - check( - enforceLimits(boundTransportAddress, DiscoveryModule.DISCOVERY_TYPE_SETTING.get(settings)), + check( context, + enforceLimits(boundTransportAddress, DiscoveryModule.DISCOVERY_TYPE_SETTING.get(context.settings)), Collections.unmodifiableList(combinedChecks), - Node.NODE_NAME_SETTING.get(settings)); + Node.NODE_NAME_SETTING.get(context.settings)); } /** @@ -84,15 +83,17 @@ static void check(final Settings settings, final BoundTransportAddress boundTran * property {@code es.enforce.bootstrap.checks} is set to {@code true} then the bootstrap checks will be enforced regardless of whether * or not the transport protocol is bound to a non-loopback interface. * + * @param context the current node boostrap context * @param enforceLimits {@code true} if the checks should be enforced or otherwise warned * @param checks the checks to execute * @param nodeName the node name to be used as a logging prefix */ static void check( + final BootstrapContext context, final boolean enforceLimits, final List checks, final String nodeName) throws NodeValidationException { - check(enforceLimits, checks, Loggers.getLogger(BootstrapChecks.class, nodeName)); + check(context, enforceLimits, checks, Loggers.getLogger(BootstrapChecks.class, nodeName)); } /** @@ -100,11 +101,13 @@ static void check( * property {@code es.enforce.bootstrap.checks }is set to {@code true} then the bootstrap checks will be enforced regardless of whether * or not the transport protocol is bound to a non-loopback interface. * + * @param context the current node boostrap context * @param enforceLimits {@code true} if the checks should be enforced or otherwise warned * @param checks the checks to execute * @param logger the logger to */ static void check( + final BootstrapContext context, final boolean enforceLimits, final List checks, final Logger logger) throws NodeValidationException { @@ -134,7 +137,7 @@ static void check( } for (final BootstrapCheck check : checks) { - if (check.check()) { + if (check.check(context)) { if (!(enforceLimits || enforceBootstrapChecks) && !check.alwaysEnforce()) { ignoredErrors.add(check.errorMessage()); } else { @@ -180,13 +183,13 @@ static boolean enforceLimits(final BoundTransportAddress boundTransportAddress, } // the list of checks to execute - static List checks(final Settings settings) { + static List checks() { final List checks = new ArrayList<>(); checks.add(new HeapSizeCheck()); final FileDescriptorCheck fileDescriptorCheck = Constants.MAC_OS_X ? new OsXFileDescriptorCheck() : new FileDescriptorCheck(); checks.add(fileDescriptorCheck); - checks.add(new MlockallCheck(BootstrapSettings.MEMORY_LOCK_SETTING.get(settings))); + checks.add(new MlockallCheck()); if (Constants.LINUX) { checks.add(new MaxNumberOfThreadsCheck()); } @@ -201,7 +204,7 @@ static List checks(final Settings settings) { } checks.add(new ClientJvmCheck()); checks.add(new UseSerialGCCheck()); - checks.add(new SystemCallFilterCheck(BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(settings))); + checks.add(new SystemCallFilterCheck()); checks.add(new OnErrorCheck()); checks.add(new OnOutOfMemoryErrorCheck()); checks.add(new EarlyAccessCheck()); @@ -212,7 +215,7 @@ static List checks(final Settings settings) { static class HeapSizeCheck implements BootstrapCheck { @Override - public boolean check() { + public boolean check(BootstrapContext context) { final long initialHeapSize = getInitialHeapSize(); final long maxHeapSize = getMaxHeapSize(); return initialHeapSize != 0 && maxHeapSize != 0 && initialHeapSize != maxHeapSize; @@ -268,7 +271,7 @@ protected FileDescriptorCheck(final int limit) { this.limit = limit; } - public final boolean check() { + public final boolean check(BootstrapContext context) { final long maxFileDescriptorCount = getMaxFileDescriptorCount(); return maxFileDescriptorCount != -1 && maxFileDescriptorCount < limit; } @@ -292,15 +295,9 @@ long getMaxFileDescriptorCount() { static class MlockallCheck implements BootstrapCheck { - private final boolean mlockallSet; - - MlockallCheck(final boolean mlockAllSet) { - this.mlockallSet = mlockAllSet; - } - @Override - public boolean check() { - return mlockallSet && !isMemoryLocked(); + public boolean check(BootstrapContext context) { + return BootstrapSettings.MEMORY_LOCK_SETTING.get(context.settings) && !isMemoryLocked(); } @Override @@ -321,7 +318,7 @@ static class MaxNumberOfThreadsCheck implements BootstrapCheck { private static final long MAX_NUMBER_OF_THREADS_THRESHOLD = 1 << 12; @Override - public boolean check() { + public boolean check(BootstrapContext context) { return getMaxNumberOfThreads() != -1 && getMaxNumberOfThreads() < MAX_NUMBER_OF_THREADS_THRESHOLD; } @@ -345,7 +342,7 @@ long getMaxNumberOfThreads() { static class MaxSizeVirtualMemoryCheck implements BootstrapCheck { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return getMaxSizeVirtualMemory() != Long.MIN_VALUE && getMaxSizeVirtualMemory() != getRlimInfinity(); } @@ -376,7 +373,7 @@ long getMaxSizeVirtualMemory() { static class MaxFileSizeCheck implements BootstrapCheck { @Override - public boolean check() { + public boolean check(BootstrapContext context) { final long maxFileSize = getMaxFileSize(); return maxFileSize != Long.MIN_VALUE && maxFileSize != getRlimInfinity(); } @@ -405,7 +402,7 @@ static class MaxMapCountCheck implements BootstrapCheck { private static final long LIMIT = 1 << 18; @Override - public boolean check() { + public boolean check(BootstrapContext context) { return getMaxMapCount() != -1 && getMaxMapCount() < LIMIT; } @@ -470,7 +467,7 @@ long parseProcSysVmMaxMapCount(final String procSysVmMaxMapCount) throws NumberF static class ClientJvmCheck implements BootstrapCheck { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return getVmName().toLowerCase(Locale.ROOT).contains("client"); } @@ -496,7 +493,7 @@ public String errorMessage() { static class UseSerialGCCheck implements BootstrapCheck { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return getUseSerialGC().equals("true"); } @@ -521,15 +518,9 @@ public String errorMessage() { */ static class SystemCallFilterCheck implements BootstrapCheck { - private final boolean areSystemCallFiltersEnabled; - - SystemCallFilterCheck(final boolean areSystemCallFiltersEnabled) { - this.areSystemCallFiltersEnabled = areSystemCallFiltersEnabled; - } - @Override - public boolean check() { - return areSystemCallFiltersEnabled && !isSystemCallFilterInstalled(); + public boolean check(BootstrapContext context) { + return BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(context.settings) && !isSystemCallFilterInstalled(); } // visible for testing @@ -548,7 +539,7 @@ public String errorMessage() { abstract static class MightForkCheck implements BootstrapCheck { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return isSystemCallFilterInstalled() && mightFork(); } @@ -623,7 +614,7 @@ public String errorMessage() { static class EarlyAccessCheck implements BootstrapCheck { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return "Oracle Corporation".equals(jvmVendor()) && javaVersion().endsWith("-ea"); } @@ -651,7 +642,7 @@ public String errorMessage() { static class G1GCCheck implements BootstrapCheck { @Override - public boolean check() { + public boolean check(BootstrapContext context) { if ("Oracle Corporation".equals(jvmVendor()) && isJava8() && isG1GCEnabled()) { final String jvmVersion = jvmVersion(); // HotSpot versions on Java 8 match this regular expression; note that this changes with Java 9 after JEP-223 diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapContext.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapContext.java new file mode 100644 index 0000000000000..f23d0db6d80bf --- /dev/null +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapContext.java @@ -0,0 +1,41 @@ +/* + * 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.cluster.metadata.MetaData; +import org.elasticsearch.common.settings.Settings; + +/** + * Context that is passed to every bootstrap check to make decisions on. + */ +public class BootstrapContext { + /** + * The nodes settings + */ + public final Settings settings; + /** + * The nodes local state metadata loaded on startup + */ + public final MetaData metaData; + + public BootstrapContext(Settings settings, MetaData metaData) { + this.settings = settings; + this.metaData = metaData; + } +} diff --git a/core/src/main/java/org/elasticsearch/node/Node.java b/core/src/main/java/org/elasticsearch/node/Node.java index e2747e6583d0c..dbc6ef5b516c0 100644 --- a/core/src/main/java/org/elasticsearch/node/Node.java +++ b/core/src/main/java/org/elasticsearch/node/Node.java @@ -35,6 +35,7 @@ import org.elasticsearch.action.support.TransportAction; import org.elasticsearch.action.update.UpdateHelper; import org.elasticsearch.bootstrap.BootstrapCheck; +import org.elasticsearch.bootstrap.BootstrapContext; import org.elasticsearch.client.Client; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.cluster.ClusterInfo; @@ -615,8 +616,11 @@ public Node start() throws NodeValidationException { } catch (IOException e) { throw new UncheckedIOException(e); } - validateNodeBeforeAcceptingRequests(settings, transportService.boundAddress(), pluginsService.filterPlugins(Plugin.class).stream() - .flatMap(p -> p.getBootstrapChecks(onDiskMetadata).stream()).collect(Collectors.toList())); + validateNodeBeforeAcceptingRequests(new BootstrapContext(settings, onDiskMetadata), transportService.boundAddress(), pluginsService + .filterPlugins(Plugin + .class) + .stream() + .flatMap(p -> p.getBootstrapChecks().stream()).collect(Collectors.toList())); clusterService.addStateApplier(transportService.getTaskManager()); // start after transport service so the local disco is known @@ -822,13 +826,13 @@ public Injector injector() { * and before the network service starts accepting incoming network * requests. * - * @param settings the fully-resolved settings + * @param context the bootstrap context for this node * @param boundTransportAddress the network addresses the node is * bound and publishing to */ @SuppressWarnings("unused") protected void validateNodeBeforeAcceptingRequests( - final Settings settings, + final BootstrapContext context, final BoundTransportAddress boundTransportAddress, List bootstrapChecks) throws NodeValidationException { } diff --git a/core/src/main/java/org/elasticsearch/node/NodeValidationException.java b/core/src/main/java/org/elasticsearch/node/NodeValidationException.java index 01840b2556bcf..58e2c4ef951f6 100644 --- a/core/src/main/java/org/elasticsearch/node/NodeValidationException.java +++ b/core/src/main/java/org/elasticsearch/node/NodeValidationException.java @@ -27,8 +27,8 @@ /** * An exception thrown during node validation. Node validation runs immediately before a node * begins accepting network requests in - * {@link Node#validateNodeBeforeAcceptingRequests(Settings, BoundTransportAddress, List)}. This exception is a checked exception that - * is declared as thrown from this method for the purpose of bubbling up to the user. + * {@link Node#validateNodeBeforeAcceptingRequests(org.elasticsearch.bootstrap.BootstrapContext, BoundTransportAddress, List)}. + * This exception is a checked exception that is declared as thrown from this method for the purpose of bubbling up to the user. */ public class NodeValidationException extends Exception { diff --git a/core/src/main/java/org/elasticsearch/plugins/Plugin.java b/core/src/main/java/org/elasticsearch/plugins/Plugin.java index 62e1162e9ff8d..82c8bf1bbcb18 100644 --- a/core/src/main/java/org/elasticsearch/plugins/Plugin.java +++ b/core/src/main/java/org/elasticsearch/plugins/Plugin.java @@ -221,9 +221,8 @@ public List> getExecutorBuilders(Settings settings) { * interface. In this case we assume the node is running in production and all bootstrap checks must pass. This allows plugins * to provide a better out of the box experience by pre-configuring otherwise (in production) mandatory settings or to enforce certain * configurations like OS settings or 3rd party resources. - * @param metaData the on-disk metadata for this nodes. This allows bootstrap-checks based on the locally recovered cluster metadata */ - public List getBootstrapChecks(MetaData metaData) { return Collections.emptyList(); } + public List getBootstrapChecks() { return Collections.emptyList(); } /** * Close the resources opened by this plugin. diff --git a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java index 77276b8787fc2..a02590c30e0c5 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java +++ b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java @@ -21,6 +21,7 @@ import org.apache.logging.log4j.Logger; import org.apache.lucene.util.Constants; +import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; @@ -51,6 +52,7 @@ import static org.mockito.Mockito.when; public class BootstrapChecksTests extends ESTestCase { + private static final BootstrapContext defaultContext = new BootstrapContext(Settings.EMPTY, MetaData.EMPTY_META_DATA); public void testNonProductionMode() throws NodeValidationException { // nothing should happen since we are in non-production mode @@ -64,18 +66,18 @@ public void testNonProductionMode() throws NodeValidationException { BoundTransportAddress boundTransportAddress = mock(BoundTransportAddress.class); when(boundTransportAddress.boundAddresses()).thenReturn(transportAddresses.toArray(new TransportAddress[0])); when(boundTransportAddress.publishAddress()).thenReturn(publishAddress); - BootstrapChecks.check(Settings.EMPTY, boundTransportAddress, Collections.emptyList()); + BootstrapChecks.check(defaultContext, boundTransportAddress, Collections.emptyList()); } public void testNoLogMessageInNonProductionMode() throws NodeValidationException { final Logger logger = mock(Logger.class); - BootstrapChecks.check(false, Collections.emptyList(), logger); + BootstrapChecks.check(defaultContext, false, Collections.emptyList(), logger); verifyNoMoreInteractions(logger); } public void testLogMessageInProductionMode() throws NodeValidationException { final Logger logger = mock(Logger.class); - BootstrapChecks.check(true, Collections.emptyList(), logger); + BootstrapChecks.check(defaultContext, true, Collections.emptyList(), logger); verify(logger).info("bound or publishing to a non-loopback or non-link-local address, enforcing bootstrap checks"); verifyNoMoreInteractions(logger); } @@ -126,7 +128,7 @@ public void testExceptionAggregation() { final List checks = Arrays.asList( new BootstrapCheck() { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return true; } @@ -137,7 +139,7 @@ public String errorMessage() { }, new BootstrapCheck() { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return true; } @@ -149,7 +151,8 @@ public String errorMessage() { ); final NodeValidationException e = - expectThrows(NodeValidationException.class, () -> BootstrapChecks.check(true, checks, "testExceptionAggregation")); + expectThrows(NodeValidationException.class, + () -> BootstrapChecks.check(defaultContext, true, checks, "testExceptionAggregation")); assertThat(e, hasToString(allOf(containsString("bootstrap checks failed"), containsString("first"), containsString("second")))); final Throwable[] suppressed = e.getSuppressed(); assertThat(suppressed.length, equalTo(2)); @@ -180,7 +183,7 @@ long getMaxHeapSize() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(check), "testHeapSizeCheck")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testHeapSizeCheck")); assertThat( e.getMessage(), containsString("initial heap size [" + initialHeapSize.get() + "] " + @@ -188,7 +191,7 @@ long getMaxHeapSize() { initialHeapSize.set(maxHeapSize.get()); - BootstrapChecks.check(true, Collections.singletonList(check), "testHeapSizeCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testHeapSizeCheck"); // nothing should happen if the initial heap size or the max // heap size is not available @@ -197,7 +200,7 @@ long getMaxHeapSize() { } else { maxHeapSize.set(0); } - BootstrapChecks.check(true, Collections.singletonList(check), "testHeapSizeCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testHeapSizeCheck"); } public void testFileDescriptorLimits() throws NodeValidationException { @@ -223,17 +226,17 @@ long getMaxFileDescriptorCount() { final NodeValidationException e = expectThrows(NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(check), "testFileDescriptorLimits")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testFileDescriptorLimits")); assertThat(e.getMessage(), containsString("max file descriptors")); maxFileDescriptorCount.set(randomIntBetween(limit + 1, Integer.MAX_VALUE)); - BootstrapChecks.check(true, Collections.singletonList(check), "testFileDescriptorLimits"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testFileDescriptorLimits"); // nothing should happen if current file descriptor count is // not available maxFileDescriptorCount.set(-1); - BootstrapChecks.check(true, Collections.singletonList(check), "testFileDescriptorLimits"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testFileDescriptorLimits"); } public void testFileDescriptorLimitsThrowsOnInvalidLimit() { @@ -266,17 +269,19 @@ class MlockallCheckTestCase { testCases.add(new MlockallCheckTestCase(false, false, false)); for (final MlockallCheckTestCase testCase : testCases) { - final BootstrapChecks.MlockallCheck check = new BootstrapChecks.MlockallCheck(testCase.mlockallSet) { + final BootstrapChecks.MlockallCheck check = new BootstrapChecks.MlockallCheck() { @Override boolean isMemoryLocked() { return testCase.isMemoryLocked; } }; - + BootstrapContext bootstrapContext = new BootstrapContext( + Settings.builder().put("bootstrap.memory_lock", testCase.mlockallSet).build(), null); if (testCase.shouldFail) { final NodeValidationException e = expectThrows( NodeValidationException.class, () -> BootstrapChecks.check( + bootstrapContext, true, Collections.singletonList(check), "testFileDescriptorLimitsThrowsOnInvalidLimit")); @@ -285,7 +290,8 @@ boolean isMemoryLocked() { containsString("memory locking requested for elasticsearch process but memory is not locked")); } else { // nothing should happen - BootstrapChecks.check(true, Collections.singletonList(check), "testFileDescriptorLimitsThrowsOnInvalidLimit"); + BootstrapChecks.check(bootstrapContext, true, Collections.singletonList(check), + "testFileDescriptorLimitsThrowsOnInvalidLimit"); } } } @@ -302,17 +308,17 @@ long getMaxNumberOfThreads() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(check), "testMaxNumberOfThreadsCheck")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxNumberOfThreadsCheck")); assertThat(e.getMessage(), containsString("max number of threads")); maxNumberOfThreads.set(randomIntBetween(limit + 1, Integer.MAX_VALUE)); - BootstrapChecks.check(true, Collections.singletonList(check), "testMaxNumberOfThreadsCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxNumberOfThreadsCheck"); // nothing should happen if current max number of threads is // not available maxNumberOfThreads.set(-1); - BootstrapChecks.check(true, Collections.singletonList(check), "testMaxNumberOfThreadsCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxNumberOfThreadsCheck"); } public void testMaxSizeVirtualMemory() throws NodeValidationException { @@ -332,16 +338,16 @@ long getRlimInfinity() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(check), "testMaxSizeVirtualMemory")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxSizeVirtualMemory")); assertThat(e.getMessage(), containsString("max size virtual memory")); maxSizeVirtualMemory.set(rlimInfinity); - BootstrapChecks.check(true, Collections.singletonList(check), "testMaxSizeVirtualMemory"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxSizeVirtualMemory"); // nothing should happen if max size virtual memory is not available maxSizeVirtualMemory.set(Long.MIN_VALUE); - BootstrapChecks.check(true, Collections.singletonList(check), "testMaxSizeVirtualMemory"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxSizeVirtualMemory"); } public void testMaxFileSizeCheck() throws NodeValidationException { @@ -361,16 +367,16 @@ long getRlimInfinity() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(check), "testMaxFileSize")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxFileSize")); assertThat(e.getMessage(), containsString("max file size")); maxFileSize.set(rlimInfinity); - BootstrapChecks.check(true, Collections.singletonList(check), "testMaxFileSize"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxFileSize"); // nothing should happen if max file size is not available maxFileSize.set(Long.MIN_VALUE); - BootstrapChecks.check(true, Collections.singletonList(check), "testMaxFileSize"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxFileSize"); } public void testMaxMapCountCheck() throws NodeValidationException { @@ -385,17 +391,17 @@ long getMaxMapCount() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(check), "testMaxMapCountCheck")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxMapCountCheck")); assertThat(e.getMessage(), containsString("max virtual memory areas vm.max_map_count")); maxMapCount.set(randomIntBetween(limit + 1, Integer.MAX_VALUE)); - BootstrapChecks.check(true, Collections.singletonList(check), "testMaxMapCountCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxMapCountCheck"); // nothing should happen if current vm.max_map_count is not // available maxMapCount.set(-1); - BootstrapChecks.check(true, Collections.singletonList(check), "testMaxMapCountCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testMaxMapCountCheck"); } public void testClientJvmCheck() throws NodeValidationException { @@ -409,14 +415,14 @@ String getVmName() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(check), "testClientJvmCheck")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testClientJvmCheck")); assertThat( e.getMessage(), containsString("JVM is using the client VM [Java HotSpot(TM) 32-Bit Client VM] " + "but should be using a server VM for the best performance")); vmName.set("Java HotSpot(TM) 32-Bit Server VM"); - BootstrapChecks.check(true, Collections.singletonList(check), "testClientJvmCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testClientJvmCheck"); } public void testUseSerialGCCheck() throws NodeValidationException { @@ -430,19 +436,22 @@ String getUseSerialGC() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(check), "testUseSerialGCCheck")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testUseSerialGCCheck")); assertThat( e.getMessage(), containsString("JVM is using the serial collector but should not be for the best performance; " + "" + "either it's the default for the VM [" + JvmInfo.jvmInfo().getVmName() +"] or -XX:+UseSerialGC was explicitly specified")); useSerialGC.set("false"); - BootstrapChecks.check(true, Collections.singletonList(check), "testUseSerialGCCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), "testUseSerialGCCheck"); } public void testSystemCallFilterCheck() throws NodeValidationException { final AtomicBoolean isSystemCallFilterInstalled = new AtomicBoolean(); - final BootstrapChecks.SystemCallFilterCheck systemCallFilterEnabledCheck = new BootstrapChecks.SystemCallFilterCheck(true) { + BootstrapContext context = randomBoolean() ? new BootstrapContext(Settings.builder().put("bootstrap.system_call_filter", true) + .build(), null) : defaultContext; + + final BootstrapChecks.SystemCallFilterCheck systemCallFilterEnabledCheck = new BootstrapChecks.SystemCallFilterCheck() { @Override boolean isSystemCallFilterInstalled() { return isSystemCallFilterInstalled.get(); @@ -451,25 +460,26 @@ boolean isSystemCallFilterInstalled() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(systemCallFilterEnabledCheck), "testSystemCallFilterCheck")); + () -> BootstrapChecks.check(context, true, Collections.singletonList(systemCallFilterEnabledCheck), + "testSystemCallFilterCheck")); assertThat( e.getMessage(), containsString("system call filters failed to install; " + "check the logs and fix your configuration or disable system call filters at your own risk")); isSystemCallFilterInstalled.set(true); - BootstrapChecks.check(true, Collections.singletonList(systemCallFilterEnabledCheck), "testSystemCallFilterCheck"); - - final BootstrapChecks.SystemCallFilterCheck systemCallFilterNotEnabledCheck = new BootstrapChecks.SystemCallFilterCheck(false) { + BootstrapChecks.check(context, true, Collections.singletonList(systemCallFilterEnabledCheck), "testSystemCallFilterCheck"); + BootstrapContext context_1 = new BootstrapContext(Settings.builder().put("bootstrap.system_call_filter", false).build(), null); + final BootstrapChecks.SystemCallFilterCheck systemCallFilterNotEnabledCheck = new BootstrapChecks.SystemCallFilterCheck() { @Override boolean isSystemCallFilterInstalled() { return isSystemCallFilterInstalled.get(); } }; isSystemCallFilterInstalled.set(false); - BootstrapChecks.check(true, Collections.singletonList(systemCallFilterNotEnabledCheck), "testSystemCallFilterCheck"); + BootstrapChecks.check(context_1, true, Collections.singletonList(systemCallFilterNotEnabledCheck), "testSystemCallFilterCheck"); isSystemCallFilterInstalled.set(true); - BootstrapChecks.check(true, Collections.singletonList(systemCallFilterNotEnabledCheck), "testSystemCallFilterCheck"); + BootstrapChecks.check(context_1, true, Collections.singletonList(systemCallFilterNotEnabledCheck), "testSystemCallFilterCheck"); } public void testMightForkCheck() throws NodeValidationException { @@ -573,13 +583,13 @@ private void runMightForkTest( } else { enableMightFork.run(); } - BootstrapChecks.check(true, Collections.singletonList(check), methodName); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), methodName); // if system call filter is enabled, but we will not fork, nothing should // happen isSystemCallFilterInstalled.set(true); disableMightFork.run(); - BootstrapChecks.check(true, Collections.singletonList(check), methodName); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(check), methodName); // if system call filter is enabled, and we might fork, the check should be enforced, regardless of bootstrap checks being enabled // or not @@ -588,7 +598,7 @@ private void runMightForkTest( final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(randomBoolean(), Collections.singletonList(check), methodName)); + () -> BootstrapChecks.check(defaultContext, randomBoolean(), Collections.singletonList(check), methodName)); consumer.accept(e); } @@ -613,7 +623,7 @@ String javaVersion() { final NodeValidationException e = expectThrows( NodeValidationException.class, () -> { - BootstrapChecks.check(true, checks, "testEarlyAccessCheck"); + BootstrapChecks.check(defaultContext, true, checks, "testEarlyAccessCheck"); }); assertThat( e.getMessage(), @@ -624,7 +634,7 @@ String javaVersion() { // if not on an early-access build, nothing should happen javaVersion.set(randomFrom("1.8.0_152", "9")); - BootstrapChecks.check(true, checks, "testEarlyAccessCheck"); + BootstrapChecks.check(defaultContext, true, checks, "testEarlyAccessCheck"); } @@ -660,7 +670,7 @@ boolean isJava8() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(true, Collections.singletonList(g1GCCheck), "testG1GCCheck")); + () -> BootstrapChecks.check(defaultContext, true, Collections.singletonList(g1GCCheck), "testG1GCCheck")); assertThat( e.getMessage(), containsString( @@ -668,12 +678,12 @@ boolean isJava8() { // if G1GC is disabled, nothing should happen isG1GCEnabled.set(false); - BootstrapChecks.check(true, Collections.singletonList(g1GCCheck), "testG1GCCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(g1GCCheck), "testG1GCCheck"); // if on or after update 40, nothing should happen independent of whether or not G1GC is enabled isG1GCEnabled.set(randomBoolean()); jvmVersion.set(String.format(Locale.ROOT, "25.%d-b%d", randomIntBetween(40, 112), randomIntBetween(1, 128))); - BootstrapChecks.check(true, Collections.singletonList(g1GCCheck), "testG1GCCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(g1GCCheck), "testG1GCCheck"); final BootstrapChecks.G1GCCheck nonOracleCheck = new BootstrapChecks.G1GCCheck() { @@ -685,7 +695,7 @@ String jvmVendor() { }; // if not on an Oracle JVM, nothing should happen - BootstrapChecks.check(true, Collections.singletonList(nonOracleCheck), "testG1GCCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(nonOracleCheck), "testG1GCCheck"); final BootstrapChecks.G1GCCheck nonJava8Check = new BootstrapChecks.G1GCCheck() { @@ -697,13 +707,13 @@ boolean isJava8() { }; // if not Java 8, nothing should happen - BootstrapChecks.check(true, Collections.singletonList(nonJava8Check), "testG1GCCheck"); + BootstrapChecks.check(defaultContext, true, Collections.singletonList(nonJava8Check), "testG1GCCheck"); } public void testAlwaysEnforcedChecks() { final BootstrapCheck check = new BootstrapCheck() { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return true; } @@ -720,7 +730,7 @@ public boolean alwaysEnforce() { final NodeValidationException alwaysEnforced = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(randomBoolean(), Collections.singletonList(check), "testAlwaysEnforcedChecks")); + () -> BootstrapChecks.check(defaultContext, randomBoolean(), Collections.singletonList(check), "testAlwaysEnforcedChecks")); assertThat(alwaysEnforced, hasToString(containsString("error"))); } diff --git a/core/src/test/java/org/elasticsearch/node/NodeTests.java b/core/src/test/java/org/elasticsearch/node/NodeTests.java index d864729949421..edf5dfac76daa 100644 --- a/core/src/test/java/org/elasticsearch/node/NodeTests.java +++ b/core/src/test/java/org/elasticsearch/node/NodeTests.java @@ -22,8 +22,8 @@ import org.apache.lucene.util.LuceneTestCase; import org.elasticsearch.Version; import org.elasticsearch.bootstrap.BootstrapCheck; +import org.elasticsearch.bootstrap.BootstrapContext; import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; @@ -67,7 +67,7 @@ public void testNodeName() throws IOException { public static class CheckPlugin extends Plugin { public static final BootstrapCheck CHECK = new BootstrapCheck() { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return false; } @@ -77,8 +77,7 @@ public String errorMessage() { } }; @Override - public List getBootstrapChecks(MetaData metaData) { - assertNotNull(metaData); + public List getBootstrapChecks() { return Collections.singletonList(CHECK); } } @@ -92,7 +91,7 @@ public void testLoadPluginBootstrapChecks() throws IOException { AtomicBoolean executed = new AtomicBoolean(false); try (Node node = new MockNode(settings.build(), Arrays.asList(getTestTransportPlugin(), CheckPlugin.class)) { @Override - protected void validateNodeBeforeAcceptingRequests(Settings settings, BoundTransportAddress boundTransportAddress, + protected void validateNodeBeforeAcceptingRequests(BootstrapContext context, BoundTransportAddress boundTransportAddress, List bootstrapChecks) throws NodeValidationException { assertEquals(1, bootstrapChecks.size()); assertSame(CheckPlugin.CHECK, bootstrapChecks.get(0)); diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilBootstrapChecksTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilBootstrapChecksTests.java index 8e346bf7d9cb9..8b0fbd6862fc1 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilBootstrapChecksTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilBootstrapChecksTests.java @@ -21,6 +21,7 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.common.SuppressForbidden; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.node.NodeValidationException; import org.elasticsearch.test.ESTestCase; import org.hamcrest.Matcher; @@ -61,7 +62,7 @@ public void testEnforceBootstrapChecks() throws NodeValidationException { final List checks = Collections.singletonList( new BootstrapCheck() { @Override - public boolean check() { + public boolean check(BootstrapContext context) { return true; } @@ -75,7 +76,7 @@ public String errorMessage() { final NodeValidationException e = expectThrows( NodeValidationException.class, - () -> BootstrapChecks.check(false, checks, logger)); + () -> BootstrapChecks.check(new BootstrapContext(Settings.EMPTY, null), false, checks, logger)); final Matcher allOf = allOf(containsString("bootstrap checks failed"), containsString("error")); assertThat(e, hasToString(allOf)); @@ -87,7 +88,7 @@ public void testNonEnforcedBootstrapChecks() throws NodeValidationException { setEsEnforceBootstrapChecks(null); final Logger logger = mock(Logger.class); // nothing should happen - BootstrapChecks.check(false, emptyList(), logger); + BootstrapChecks.check(new BootstrapContext(Settings.EMPTY, null), false, emptyList(), logger); verifyNoMoreInteractions(logger); } @@ -97,7 +98,7 @@ public void testInvalidValue() { final boolean enforceLimits = randomBoolean(); final IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> BootstrapChecks.check(enforceLimits, emptyList(), "testInvalidValue")); + () -> BootstrapChecks.check(new BootstrapContext(Settings.EMPTY, null), enforceLimits, emptyList(), "testInvalidValue")); final Matcher matcher = containsString( "[es.enforce.bootstrap.checks] must be [true] but was [" + value + "]"); assertThat(e, hasToString(matcher)); From a1bb2dd991399d8e11c7b0524581e0af009a2f27 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 13 Sep 2017 20:07:13 +0200 Subject: [PATCH 3/4] only load state on data / master nodes --- core/src/main/java/org/elasticsearch/node/Node.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/elasticsearch/node/Node.java b/core/src/main/java/org/elasticsearch/node/Node.java index dbc6ef5b516c0..cee85c9619912 100644 --- a/core/src/main/java/org/elasticsearch/node/Node.java +++ b/core/src/main/java/org/elasticsearch/node/Node.java @@ -611,7 +611,11 @@ public Node start() throws NodeValidationException { try { // we load the global state here (the persistent part of the cluster state stored on disk) to // pass it to the bootstrap checks to allow plugins to enforce certain preconditions based on the recovered state. - onDiskMetadata = injector.getInstance(GatewayMetaState.class).loadMetaState(); + if (DiscoveryNode.isMasterNode(settings) || DiscoveryNode.isDataNode(settings)) { + onDiskMetadata = injector.getInstance(GatewayMetaState.class).loadMetaState(); + } else { + onDiskMetadata = MetaData.EMPTY_META_DATA; + } assert onDiskMetadata != null : "metadata is null but shouldn't"; // this is never null } catch (IOException e) { throw new UncheckedIOException(e); From 6ffd479463e3181c1d861bb9c57c18efa0efef77 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 13 Sep 2017 22:11:17 +0200 Subject: [PATCH 4/4] fix typo --- .../main/java/org/elasticsearch/bootstrap/BootstrapChecks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java index 4414a912fe344..b13f36229f9a8 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java @@ -64,7 +64,7 @@ private BootstrapChecks() { * {@code es.enforce.bootstrap.checks} is set to {@code true} then the bootstrap checks will be enforced regardless of whether or not * the transport protocol is bound to a non-loopback interface. * - * @param context the current node boostrap context + * @param context the current node bootstrap context * @param boundTransportAddress the node network bindings */ static void check(final BootstrapContext context, final BoundTransportAddress boundTransportAddress,