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.
This commit is contained in:
Harmen Stoppels 2024-10-21 18:46:13 +02:00 committed by GitHub
parent 4187c57250
commit 19ad29a690
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 14 deletions

View File

@ -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):

View File

@ -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

View File

@ -175,7 +175,15 @@ def _install_by_hash(
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(

View File

@ -1245,7 +1245,7 @@ def _add(
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 @@ def add(self, spec: "spack.spec.Spec", *, explicit: bool = False) -> None:
# 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."""