From 549c7852271171a316f66c74a039518b8e7a6eec Mon Sep 17 00:00:00 2001
From: Massimiliano Culpo <massimiliano.culpo@gmail.com>
Date: Wed, 9 Feb 2022 23:41:11 +0100
Subject: Detecting "Cray" as "linux" during bootstrap (#28726)

* bootstrap: avoid detecting "Cray" and treat the platform as "linux"

* bootstrap: create a proper context manager to disable cray
---
 lib/spack/spack/bootstrap.py            | 53 +++++++++++++--------------------
 lib/spack/spack/platforms/__init__.py   |  6 ++--
 lib/spack/spack/platforms/_functions.py | 22 ++++++++++++++
 3 files changed, 47 insertions(+), 34 deletions(-)

diff --git a/lib/spack/spack/bootstrap.py b/lib/spack/spack/bootstrap.py
index ef33ef641f..c44f217ccd 100644
--- a/lib/spack/spack/bootstrap.py
+++ b/lib/spack/spack/bootstrap.py
@@ -33,6 +33,7 @@ import spack.repo
 import spack.spec
 import spack.store
 import spack.user_environment
+import spack.util.environment
 import spack.util.executable
 import spack.util.path
 
@@ -65,12 +66,6 @@ def _try_import_from_store(module, query_spec, query_info=None):
     """
     # If it is a string assume it's one of the root specs by this module
     if isinstance(query_spec, six.string_types):
-        bincache_platform = spack.platforms.real_host()
-        if str(bincache_platform) == 'cray':
-            bincache_platform = spack.platforms.linux.Linux()
-            with spack.platforms.use_platform(bincache_platform):
-                query_spec = str(spack.spec.Spec(query_spec))
-
         # We have to run as part of this python interpreter
         query_spec += ' ^' + spec_for_current_python()
 
@@ -231,10 +226,6 @@ class _BuildcacheBootstrapper(object):
         abstract_spec = spack.spec.Spec(abstract_spec_str)
         # On Cray we want to use Linux binaries if available from mirrors
         bincache_platform = spack.platforms.real_host()
-        if str(bincache_platform) == 'cray':
-            bincache_platform = spack.platforms.Linux()
-            with spack.platforms.use_platform(bincache_platform):
-                abstract_spec = spack.spec.Spec(abstract_spec_str)
         return abstract_spec, bincache_platform
 
     def _read_metadata(self, package_name):
@@ -372,9 +363,6 @@ class _SourceBootstrapper(object):
         # Try to build and install from sources
         with spack_python_interpreter():
             # Add hint to use frontend operating system on Cray
-            if str(spack.platforms.host()) == 'cray':
-                abstract_spec_str += ' os=fe'
-
             concrete_spec = spack.spec.Spec(
                 abstract_spec_str + ' ^' + spec_for_current_python()
             )
@@ -406,10 +394,6 @@ class _SourceBootstrapper(object):
         # might reduce compilation time by a fair amount
         _add_externals_if_missing()
 
-        # Add hint to use frontend operating system on Cray
-        if str(spack.platforms.host()) == 'cray':
-            abstract_spec_str += ' os=fe'
-
         concrete_spec = spack.spec.Spec(abstract_spec_str)
         if concrete_spec.name == 'patchelf':
             concrete_spec._old_concretize(deprecation_warning=False)
@@ -666,21 +650,26 @@ def _ensure_bootstrap_configuration():
     bootstrap_store_path = store_path()
     user_configuration = _read_and_sanitize_configuration()
     with spack.environment.no_active_environment():
-        with spack.platforms.use_platform(spack.platforms.real_host()):
-            with spack.repo.use_repositories(spack.paths.packages_path):
-                with spack.store.use_store(bootstrap_store_path):
-                    # Default configuration scopes excluding command line
-                    # and builtin but accounting for platform specific scopes
-                    config_scopes = _bootstrap_config_scopes()
-                    with spack.config.use_configuration(*config_scopes):
-                        # We may need to compile code from sources, so ensure we have
-                        # compilers for the current platform before switching parts.
-                        _add_compilers_if_missing()
-                        spack.config.set('bootstrap', user_configuration['bootstrap'])
-                        spack.config.set('config', user_configuration['config'])
-                        with spack.modules.disable_modules():
-                            with spack_python_interpreter():
-                                yield
+        with spack.platforms.prevent_cray_detection():
+            with spack.platforms.use_platform(spack.platforms.real_host()):
+                with spack.repo.use_repositories(spack.paths.packages_path):
+                    with spack.store.use_store(bootstrap_store_path):
+                        # Default configuration scopes excluding command line
+                        # and builtin but accounting for platform specific scopes
+                        config_scopes = _bootstrap_config_scopes()
+                        with spack.config.use_configuration(*config_scopes):
+                            # We may need to compile code from sources, so ensure we
+                            # have compilers for the current platform
+                            _add_compilers_if_missing()
+                            spack.config.set(
+                                'bootstrap', user_configuration['bootstrap']
+                            )
+                            spack.config.set(
+                                'config', user_configuration['config']
+                            )
+                            with spack.modules.disable_modules():
+                                with spack_python_interpreter():
+                                    yield
 
 
 def _read_and_sanitize_configuration():
diff --git a/lib/spack/spack/platforms/__init__.py b/lib/spack/spack/platforms/__init__.py
index 44855b7f58..83de03de12 100644
--- a/lib/spack/spack/platforms/__init__.py
+++ b/lib/spack/spack/platforms/__init__.py
@@ -4,7 +4,7 @@
 # SPDX-License-Identifier: (Apache-2.0 OR MIT)
 import contextlib
 
-from ._functions import _host, by_name, platforms
+from ._functions import _host, by_name, platforms, prevent_cray_detection, reset
 from ._platform import Platform
 from .cray import Cray
 from .darwin import Darwin
@@ -19,7 +19,9 @@ __all__ = [
     'Test',
     'platforms',
     'host',
-    'by_name'
+    'by_name',
+    'reset',
+    'prevent_cray_detection'
 ]
 
 #: The "real" platform of the host running Spack. This should not be changed
diff --git a/lib/spack/spack/platforms/_functions.py b/lib/spack/spack/platforms/_functions.py
index 4aaa75e948..7d3a440a3a 100644
--- a/lib/spack/spack/platforms/_functions.py
+++ b/lib/spack/spack/platforms/_functions.py
@@ -2,8 +2,12 @@
 # Spack Project Developers. See the top-level COPYRIGHT file for details.
 #
 # SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import contextlib
+
 import llnl.util.lang
 
+import spack.util.environment
+
 from .cray import Cray
 from .darwin import Darwin
 from .linux import Linux
@@ -22,6 +26,13 @@ def _host():
     return None
 
 
+def reset():
+    """The result of the host search is memoized. In case it needs to be recomputed
+    we must clear the cache, which is what this function does.
+    """
+    _host.cache.clear()
+
+
 @llnl.util.lang.memoized
 def cls_by_name(name):
     """Return a platform class that corresponds to the given name or None
@@ -45,3 +56,14 @@ def by_name(name):
     """
     platform_cls = cls_by_name(name)
     return platform_cls() if platform_cls else None
+
+
+@contextlib.contextmanager
+def prevent_cray_detection():
+    """Context manager that prevents the detection of the Cray platform"""
+    reset()
+    try:
+        with spack.util.environment.set_env(MODULEPATH=''):
+            yield
+    finally:
+        reset()
-- 
cgit v1.2.3-70-g09d2