summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarmen Stoppels <me@harmenstoppels.nl>2024-10-21 18:46:13 +0200
committerGitHub <noreply@github.com>2024-10-21 10:46:13 -0600
commit19ad29a6902ec54e9e4ed2ec0dbbed2558048de2 (patch)
tree9b1c9b4c0b52935c395856a8be13137de35d4002
parent4187c57250fbfd50aaa5bb8d08b11daf42cbb83b (diff)
downloadspack-19ad29a6902ec54e9e4ed2ec0dbbed2558048de2.tar.gz
spack-19ad29a6902ec54e9e4ed2ec0dbbed2558048de2.tar.bz2
spack-19ad29a6902ec54e9e4ed2ec0dbbed2558048de2.tar.xz
spack-19ad29a6902ec54e9e4ed2ec0dbbed2558048de2.zip
bootstrap: handle a new edge case of binary python packages with missing python-venv (#47094)
relevant for clingo installed without gcc-runtime and python-venv, which is done for good reasons.
-rw-r--r--lib/spack/spack/binary_distribution.py19
-rw-r--r--lib/spack/spack/bootstrap/_common.py18
-rw-r--r--lib/spack/spack/bootstrap/core.py10
-rw-r--r--lib/spack/spack/database.py4
4 files changed, 37 insertions, 14 deletions
diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py
index 1f0d33f00e..bf1d352124 100644
--- a/lib/spack/spack/binary_distribution.py
+++ b/lib/spack/spack/binary_distribution.py
@@ -2562,7 +2562,13 @@ def _ensure_common_prefix(tar: tarfile.TarFile) -> str:
return pkg_prefix
-def install_root_node(spec, unsigned=False, force=False, sha256=None):
+def install_root_node(
+ spec: spack.spec.Spec,
+ unsigned=False,
+ force: bool = False,
+ sha256: Optional[str] = None,
+ allow_missing: bool = False,
+) -> None:
"""Install the root node of a concrete spec from a buildcache.
Checking the sha256 sum of a node before installation is usually needed only
@@ -2571,11 +2577,10 @@ def install_root_node(spec, unsigned=False, force=False, sha256=None):
Args:
spec: spec to be installed (note that only the root node will be installed)
- unsigned (bool): if True allows installing unsigned binaries
- force (bool): force installation if the spec is already present in the
- local store
- sha256 (str): optional sha256 of the binary package, to be checked
- before installation
+ unsigned: if True allows installing unsigned binaries
+ force: force installation if the spec is already present in the local store
+ sha256: optional sha256 of the binary package, to be checked before installation
+ allow_missing: when true, allows installing a node with missing dependencies
"""
# Early termination
if spec.external or spec.virtual:
@@ -2613,7 +2618,7 @@ def install_root_node(spec, unsigned=False, force=False, sha256=None):
spec, spack.store.STORE.layout.spec_file_path(spec)
)
spack.hooks.post_install(spec, False)
- spack.store.STORE.db.add(spec)
+ spack.store.STORE.db.add(spec, allow_missing=allow_missing)
def install_single_spec(spec, unsigned=False, force=False):
diff --git a/lib/spack/spack/bootstrap/_common.py b/lib/spack/spack/bootstrap/_common.py
index e56890f22b..2a33fa9aba 100644
--- a/lib/spack/spack/bootstrap/_common.py
+++ b/lib/spack/spack/bootstrap/_common.py
@@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Common basic functions used through the spack.bootstrap package"""
import fnmatch
+import glob
import importlib
import os.path
import re
@@ -60,10 +61,19 @@ def _try_import_from_store(
python, *_ = candidate_spec.dependencies("python-venv")
else:
python, *_ = candidate_spec.dependencies("python")
- module_paths = [
- os.path.join(candidate_spec.prefix, python.package.purelib),
- os.path.join(candidate_spec.prefix, python.package.platlib),
- ]
+
+ # if python is installed, ask it for the layout
+ if python.installed:
+ module_paths = [
+ os.path.join(candidate_spec.prefix, python.package.purelib),
+ os.path.join(candidate_spec.prefix, python.package.platlib),
+ ]
+ # otherwise search for the site-packages directory
+ # (clingo from binaries with truncated python-venv runtime)
+ else:
+ module_paths = glob.glob(
+ os.path.join(candidate_spec.prefix, "lib", "python*", "site-packages")
+ )
path_before = list(sys.path)
# NOTE: try module_paths first and last, last allows an existing version in path
diff --git a/lib/spack/spack/bootstrap/core.py b/lib/spack/spack/bootstrap/core.py
index 6f1d9fdb9d..e9c2975196 100644
--- a/lib/spack/spack/bootstrap/core.py
+++ b/lib/spack/spack/bootstrap/core.py
@@ -175,7 +175,15 @@ class BuildcacheBootstrapper(Bootstrapper):
query = spack.binary_distribution.BinaryCacheQuery(all_architectures=True)
for match in spack.store.find([f"/{pkg_hash}"], multiple=False, query_fn=query):
spack.binary_distribution.install_root_node(
- match, unsigned=True, force=True, sha256=pkg_sha256
+ # allow_missing is true since when bootstrapping clingo we truncate runtime
+ # deps such as gcc-runtime, since we link libstdc++ statically, and the other
+ # further runtime deps are loaded by the Python interpreter. This just silences
+ # warnings about missing dependencies.
+ match,
+ unsigned=True,
+ force=True,
+ sha256=pkg_sha256,
+ allow_missing=True,
)
def _install_and_test(
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index c1ed06d241..9813c7c18d 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -1245,7 +1245,7 @@ class Database:
self._data[key].explicit = explicit
@_autospec
- def add(self, spec: "spack.spec.Spec", *, explicit: bool = False) -> None:
+ def add(self, spec: "spack.spec.Spec", *, explicit: bool = False, allow_missing=False) -> None:
"""Add spec at path to database, locking and reading DB to sync.
``add()`` will lock and read from the DB on disk.
@@ -1254,7 +1254,7 @@ class Database:
# TODO: ensure that spec is concrete?
# Entire add is transactional.
with self.write_transaction():
- self._add(spec, explicit=explicit)
+ self._add(spec, explicit=explicit, allow_missing=allow_missing)
def _get_matching_spec_key(self, spec: "spack.spec.Spec", **kwargs) -> str:
"""Get the exact spec OR get a single spec that matches."""