diff --git a/plugin/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java b/plugin/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java index a1074dfb988..49b9c137291 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java @@ -272,7 +272,7 @@ public class MachineLearning implements ActionPlugin { JobManager jobManager = new JobManager(settings, jobProvider, clusterService, auditor, internalClient, notifier); AutodetectProcessFactory autodetectProcessFactory; NormalizerProcessFactory normalizerProcessFactory; - if (AUTODETECT_PROCESS.get(settings)) { + if (AUTODETECT_PROCESS.get(settings) && MachineLearningFeatureSet.isRunningOnMlPlatform(true)) { try { NativeController nativeController = NativeControllerHolder.getNativeController(settings); if (nativeController == null) { diff --git a/plugin/src/main/java/org/elasticsearch/xpack/ml/MachineLearningFeatureSet.java b/plugin/src/main/java/org/elasticsearch/xpack/ml/MachineLearningFeatureSet.java index 725e8f8f55a..515e498fd5e 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/ml/MachineLearningFeatureSet.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/ml/MachineLearningFeatureSet.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.ml; +import org.apache.lucene.util.Constants; import org.apache.lucene.util.Counter; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; @@ -19,6 +20,7 @@ import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.plugins.Platforms; import org.elasticsearch.xpack.XPackFeatureSet; import org.elasticsearch.xpack.XPackPlugin; import org.elasticsearch.xpack.XPackSettings; @@ -33,6 +35,7 @@ import org.elasticsearch.xpack.ml.job.process.autodetect.state.ModelSizeStats; import org.elasticsearch.xpack.ml.utils.StatsAccumulator; import java.io.IOException; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -47,6 +50,12 @@ import static org.elasticsearch.xpack.ml.action.GetJobsStatsAction.Response.JobS public class MachineLearningFeatureSet implements XPackFeatureSet { + /** + * List of platforms for which the native processes are available + */ + private static final List mlPlatforms = + Arrays.asList("darwin-x86_64", "linux-x86_64", "windows-x86_64"); + private final boolean enabled; private final XPackLicenseState licenseState; private final ClusterService clusterService; @@ -64,21 +73,38 @@ public class MachineLearningFeatureSet implements XPackFeatureSet { // Don't try to get the native code version in the transport client - the controller process won't be running if (XPackPlugin.transportClientMode(settings) == false && XPackPlugin.isTribeClientNode(settings) == false) { try { - NativeController nativeController = NativeControllerHolder.getNativeController(settings); - if (nativeController != null) { - nativeCodeInfo = nativeController.getNativeCodeInfo(); + if (isRunningOnMlPlatform(enabled)) { + NativeController nativeController = NativeControllerHolder.getNativeController(settings); + if (nativeController != null) { + nativeCodeInfo = nativeController.getNativeCodeInfo(); + } } } catch (IOException | TimeoutException e) { Loggers.getLogger(MachineLearningFeatureSet.class).error("Cannot get native code info for Machine Learning", e); if (enabled) { - throw new ElasticsearchException("Cannot communicate with Machine Learning native code " - + "- please check that you are running on a supported platform"); + throw new ElasticsearchException("Cannot communicate with Machine Learning native code"); } } } this.nativeCodeInfo = nativeCodeInfo; } + static boolean isRunningOnMlPlatform(boolean fatalIfNot) { + return isRunningOnMlPlatform(Constants.OS_NAME, Constants.OS_ARCH, fatalIfNot); + } + + static boolean isRunningOnMlPlatform(String osName, String osArch, boolean fatalIfNot) { + String platformName = Platforms.platformName(osName, osArch); + if (mlPlatforms.contains(platformName)) { + return true; + } + if (fatalIfNot) { + throw new ElasticsearchException("X-Pack is not supported and Machine Learning is not available for [" + platformName + + "]; you can use the other X-Pack features (unsupported) by setting xpack.ml.enabled: false in elasticsearch.yml"); + } + return false; + } + @Override public String name() { return XPackPlugin.MACHINE_LEARNING; diff --git a/plugin/src/test/java/org/elasticsearch/xpack/ml/MachineLearningFeatureSetTests.java b/plugin/src/test/java/org/elasticsearch/xpack/ml/MachineLearningFeatureSetTests.java index 028cee5c18c..03141721a61 100644 --- a/plugin/src/test/java/org/elasticsearch/xpack/ml/MachineLearningFeatureSetTests.java +++ b/plugin/src/test/java/org/elasticsearch/xpack/ml/MachineLearningFeatureSetTests.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.ml; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.Client; @@ -64,6 +65,21 @@ public class MachineLearningFeatureSetTests extends ESTestCase { givenDatafeeds(Collections.emptyList()); } + public void testIsRunningOnMlPlatform() { + assertTrue(MachineLearningFeatureSet.isRunningOnMlPlatform("Linux", "amd64", true)); + assertTrue(MachineLearningFeatureSet.isRunningOnMlPlatform("Windows 10", "amd64", true)); + assertTrue(MachineLearningFeatureSet.isRunningOnMlPlatform("Mac OS X", "x86_64", true)); + assertFalse(MachineLearningFeatureSet.isRunningOnMlPlatform("Linux", "i386", false)); + assertFalse(MachineLearningFeatureSet.isRunningOnMlPlatform("Windows 10", "i386", false)); + assertFalse(MachineLearningFeatureSet.isRunningOnMlPlatform("SunOS", "amd64", false)); + expectThrows(ElasticsearchException.class, + () -> MachineLearningFeatureSet.isRunningOnMlPlatform("Linux", "i386", true)); + expectThrows(ElasticsearchException.class, + () -> MachineLearningFeatureSet.isRunningOnMlPlatform("Windows 10", "i386", true)); + expectThrows(ElasticsearchException.class, + () -> MachineLearningFeatureSet.isRunningOnMlPlatform("SunOS", "amd64", true)); + } + public void testAvailable() throws Exception { MachineLearningFeatureSet featureSet = new MachineLearningFeatureSet(Settings.EMPTY, clusterService, client, licenseState); boolean available = randomBoolean();