New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bootstrap GnuPG #24003
Bootstrap GnuPG #24003
Conversation
5de002b
to
cc52c74
Compare
cc52c74
to
4ece090
Compare
14d38f2
to
45a8843
Compare
lib/spack/spack/test/cmd/gpg.py
Outdated
monkeypatch.setattr( | ||
spack.bootstrap, 'ensure_gpg_in_path_or_raise', lambda: None | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be better to check this by "untrusting" all the bootstrapping methods? That way we're actually checking the proper behavior if gpg isn't available, rather than testing what happens if bootstrapping fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See 019ca56
def ensure_gpg_in_path_or_raise(): | ||
"""Ensure gpg or gpg2 are in the PATH or raise.""" | ||
ensure_executables_in_path_or_raise( | ||
executables=['gpg2', 'gpg'], abstract_spec=gnupg_root_spec(), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should think about whether this is sustainable to have a method here for each calling site, or whether these methods should be pushed into the callers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My take on it is the following:
- The wrapper function may be pushed on the caller (it's indeed just a convenience to fix parameters in one place)
- I think
gnupg_root_spec
and similar should stay here so that we can collect in thespack.bootstrap
module all the specs we may need on bootstrapping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gnupg_root_spec
and clingo_root_spec
are identical methods, besides the spec string. I think we should have a method get_bootstrap_spec
that takes an abstract spec or abstract spec string as an argument. Then the calling site can keep the information that belongs to it ("I need gpg@1.1:" or whatever it is) and call into bootstrap only to turn that abstract information into a bootstrappable spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See d2a41f7 I factored together adding a compiler and a target, but I still think it's good to keep in bootstrap.py
the wrapping functions, like:
def clingo_root_spec():
"""Return the root spec used to bootstrap clingo"""
return _root_spec('clingo-bootstrap@spack+python')
The rationale is that the root spec for e.g. clingo
should stay consistent across Spack if /when needed in multiple places in the code. So having a function here that returns it seems good to keep the information in a single place.
@@ -325,6 +447,44 @@ def ensure_module_importable_or_raise(module, abstract_spec=None): | |||
raise ImportError(msg) | |||
|
|||
|
|||
def ensure_executables_in_path_or_raise(executables, abstract_spec): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a default argument as it is for modules?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API is slightly different, since executables
accepts a list. As it stands I don't think it needs a default value, but maybe we can revisit this post v0.17.0? If after the release we'll add more dependencies to the bootstrap procedure we may have more data to make the API more consistent.
lib/spack/spack/bootstrap.py
Outdated
def _executables_in_path(executables): | ||
"""Return True if at least one of the executables is in PATH, | ||
False otherwise. | ||
""" | ||
msg = "[BOOTSTRAP EXECUTABLES {0}] Look if the executables are in the path" | ||
executables_str = ', '.join(executables) | ||
tty.debug(msg.format(executables_str)) | ||
found = spack.util.executable.which_string(*executables) | ||
if found: | ||
msg = "[BOOTSTRAP EXECUTABLES {0}] {1} executable found in PATH" | ||
tty.debug(msg.format(executables_str, found)) | ||
return True | ||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't this method just be replaced with bool(spack.util.executable.which_string(*executables)
? I think we're getting a little overly verbose, even for debug mode with some of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See dee4605
lib/spack/spack/bootstrap.py
Outdated
current_path = os.environ['PATH'] | ||
|
||
os.environ['PATH'] = ':'.join([bin_dir, current_path]) | ||
if _executables_in_path(executables): | ||
return True | ||
os.environ['PATH'] = current_path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current_path = os.environ['PATH'] | |
os.environ['PATH'] = ':'.join([bin_dir, current_path]) | |
if _executables_in_path(executables): | |
return True | |
os.environ['PATH'] = current_path | |
if spack.util.executable.which_string(*executables, path=bin_dir): | |
spack.util.environment.path_put_first('PATH', [bin_dir]) | |
return True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See dee4605
lib/spack/spack/bootstrap.py
Outdated
with spack.config.override(self.mirror_scope): | ||
# This index is currently needed to get the compiler used to build some | ||
# specs that wwe know by dag hash. | ||
spack.binary_distribution.binary_index.regenerate_spec_cache() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably need something more robust for this -- do we need to regenerate the spec cache when we're done and switching back to the normal mirro configurations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to regenerate it, but might be wrong. In any case this method didn't change in this PR. It's what we currently use to bootstrap clingo. Can we postpone making it more robust to a later PR, if there are no major concerns about that?
344a800
to
2780c74
Compare
2780c74
to
244a307
Compare
244a307
to
9f202b1
Compare
@becker33 Can you review again? I think most points have been addressed (and hopefully the PR will pass unit tests, which are currently still pending). |
@alalazo coverage is still pretty low -- is that avoidable? |
Adding unit tests for this was difficult, so I resorted to e2e tests which are not run with coverage. The one added in this PR is: spack/.github/workflows/bootstrap.yml Lines 162 to 188 in 019ca56
I didn't add a macOS tests for binaries since |
019ca56
to
64fcba2
Compare
e7c0921
to
9274573
Compare
73db1b4
to
20279d7
Compare
depends on #22720
depends on #23889
Modifications: