diff --git a/localstack-core/localstack/services/opensearch/cluster.py b/localstack-core/localstack/services/opensearch/cluster.py index 65ef2dd9c4ed5..cae1916c90b09 100644 --- a/localstack-core/localstack/services/opensearch/cluster.py +++ b/localstack-core/localstack/services/opensearch/cluster.py @@ -675,14 +675,25 @@ def _base_settings(self, dirs) -> CommandSettings: settings = { "http.port": self.port, "http.publish_port": self.port, - "transport.port": "0", "network.host": self.host, "http.compression": "false", "path.data": f'"{dirs.data}"', "path.repo": f'"{dirs.backup}"', - "discovery.type": "single-node", } + # This config option was renamed between 6.7 and 6.8, yet not documented as a breaking change + # See https://github.com/elastic/elasticsearch/blob/f220abaf/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java#L1349-L1353 + if self.version.startswith("Elasticsearch_5.") or ( + self.version.startswith("Elasticsearch_6.") and self.version != "Elasticsearch_6.8" + ): + settings["transport.tcp.port"] = "0" + else: + settings["transport.port"] = "0" + + # `discovery.type` had a different meaning in 5.x + if not self.version.startswith("Elasticsearch_5."): + settings["discovery.type"] = "single-node" + if os.path.exists(os.path.join(dirs.mods, "x-pack-ml")): settings["xpack.ml.enabled"] = "false" @@ -690,7 +701,7 @@ def _base_settings(self, dirs) -> CommandSettings: def _create_env_vars(self, directories: Directories) -> Dict: return { - "JAVA_HOME": os.path.join(directories.install, "jdk"), + **elasticsearch_package.get_installer(self.version).get_java_env_vars(), "ES_JAVA_OPTS": os.environ.get("ES_JAVA_OPTS", "-Xms200m -Xmx600m"), "ES_TMPDIR": directories.tmp, } diff --git a/localstack-core/localstack/services/opensearch/packages.py b/localstack-core/localstack/services/opensearch/packages.py index 4610420f330ee..35a7fd933ea91 100644 --- a/localstack-core/localstack/services/opensearch/packages.py +++ b/localstack-core/localstack/services/opensearch/packages.py @@ -18,6 +18,7 @@ OPENSEARCH_PLUGIN_LIST, ) from localstack.packages import InstallTarget, Package, PackageInstaller +from localstack.packages.java import java_package from localstack.services.opensearch import versions from localstack.utils.archives import download_and_extract_with_retry from localstack.utils.files import chmod_r, load_file, mkdir, rm_rf, save_file @@ -42,6 +43,8 @@ def __init__(self, default_version: str = OPENSEARCH_DEFAULT_VERSION): def _get_installer(self, version: str) -> PackageInstaller: if version in versions._prefixed_elasticsearch_install_versions: + if version.startswith("Elasticsearch_5.") or version.startswith("Elasticsearch_6."): + return ElasticsearchLegacyPackageInstaller(version) return ElasticsearchPackageInstaller(version) else: return OpensearchPackageInstaller(version) @@ -233,6 +236,12 @@ class ElasticsearchPackageInstaller(PackageInstaller): def __init__(self, version: str): super().__init__("elasticsearch", version) + def get_java_env_vars(self) -> dict[str, str]: + install_dir = self.get_installed_dir() + return { + "JAVA_HOME": os.path.join(install_dir, "jdk"), + } + def _install(self, target: InstallTarget): # locally import to avoid having a dependency on ASF when starting the CLI from localstack.aws.api.opensearch import EngineType @@ -263,7 +272,7 @@ def _install(self, target: InstallTarget): **java_system_properties_proxy(), **java_system_properties_ssl( os.path.join(install_dir, "jdk", "bin", "keytool"), - {"JAVA_HOME": os.path.join(install_dir, "jdk")}, + self.get_java_env_vars(), ), } java_opts = system_properties_to_cli_args(sys_props) @@ -336,5 +345,27 @@ def get_elasticsearch_install_version(self) -> str: return versions.get_install_version(self.version) +class ElasticsearchLegacyPackageInstaller(ElasticsearchPackageInstaller): + """ + Specialised package installer for ElasticSearch 5.x and 6.x + + It installs Java during setup because these releases of ES do not have a bundled JDK. + This should be removed after these versions are dropped in line with AWS EOL, scheduled for Nov 2026. + https://docs.aws.amazon.com/opensearch-service/latest/developerguide/what-is.html#choosing-version + """ + + # ES 5.x and 6.x require Java 8 + # See: https://www.elastic.co/guide/en/elasticsearch/reference/6.0/zip-targz.html + JAVA_VERSION = "8" + + def _prepare_installation(self, target: InstallTarget) -> None: + java_package.get_installer(self.JAVA_VERSION).install(target) + + def get_java_env_vars(self) -> dict[str, str]: + return { + "JAVA_HOME": java_package.get_installer(self.JAVA_VERSION).get_java_home(), + } + + opensearch_package = OpensearchPackage(default_version=OPENSEARCH_DEFAULT_VERSION) elasticsearch_package = OpensearchPackage(default_version=ELASTICSEARCH_DEFAULT_VERSION)