Bootstrap GnuPG (#24003)

* GnuPG: allow bootstrapping from buildcache and sources

* Add a test to bootstrap GnuPG from binaries

* Disable bootstrapping in tests

* Add e2e test to bootstrap GnuPG from sources on Ubuntu

* Add e2e test to bootstrap GnuPG on macOS
This commit is contained in:
Massimiliano Culpo 2021-11-03 07:15:24 +01:00 committed by GitHub
parent 1a3747b2b3
commit 78c08fccd5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 549 additions and 79 deletions

View file

@ -19,7 +19,7 @@ on:
jobs: jobs:
fedora-sources: fedora-clingo-sources:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: "fedora:latest" container: "fedora:latest"
steps: steps:
@ -46,7 +46,7 @@ jobs:
spack -d solve zlib spack -d solve zlib
tree ~/.spack/bootstrap/store/ tree ~/.spack/bootstrap/store/
ubuntu-sources: ubuntu-clingo-sources:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: "ubuntu:latest" container: "ubuntu:latest"
steps: steps:
@ -76,7 +76,7 @@ jobs:
spack -d solve zlib spack -d solve zlib
tree ~/.spack/bootstrap/store/ tree ~/.spack/bootstrap/store/
opensuse-sources: opensuse-clingo-sources:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: "opensuse/leap:latest" container: "opensuse/leap:latest"
steps: steps:
@ -101,7 +101,7 @@ jobs:
spack -d solve zlib spack -d solve zlib
tree ~/.spack/bootstrap/store/ tree ~/.spack/bootstrap/store/
macos-sources: macos-clingo-sources:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: Install dependencies - name: Install dependencies
@ -137,7 +137,6 @@ jobs:
spack -d solve zlib spack -d solve zlib
tree ~/.spack/bootstrap/store/ tree ~/.spack/bootstrap/store/
ubuntu-clingo-binaries: ubuntu-clingo-binaries:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@ -159,3 +158,94 @@ jobs:
spack bootstrap untrust spack-install spack bootstrap untrust spack-install
spack -d solve zlib spack -d solve zlib
tree ~/.spack/bootstrap/store/ tree ~/.spack/bootstrap/store/
ubuntu-gnupg-binaries:
runs-on: ubuntu-latest
container: "ubuntu:latest"
steps:
- name: Install dependencies
env:
DEBIAN_FRONTEND: noninteractive
run: |
apt-get update -y && apt-get upgrade -y
apt-get install -y \
bzip2 curl file g++ gcc patchelf gfortran git gzip \
make patch unzip xz-utils python3 python3-dev tree
- uses: actions/checkout@v2
- name: Setup repo and non-root user
run: |
git --version
git fetch --unshallow
. .github/workflows/setup_git.sh
useradd -m spack-test
chown -R spack-test .
- name: Bootstrap GnuPG
shell: runuser -u spack-test -- bash {0}
run: |
source share/spack/setup-env.sh
spack bootstrap untrust spack-install
spack -d gpg list
tree ~/.spack/bootstrap/store/
ubuntu-gnupg-sources:
runs-on: ubuntu-latest
container: "ubuntu:latest"
steps:
- name: Install dependencies
env:
DEBIAN_FRONTEND: noninteractive
run: |
apt-get update -y && apt-get upgrade -y
apt-get install -y \
bzip2 curl file g++ gcc patchelf gfortran git gzip \
make patch unzip xz-utils python3 python3-dev tree \
gawk
- uses: actions/checkout@v2
- name: Setup repo and non-root user
run: |
git --version
git fetch --unshallow
. .github/workflows/setup_git.sh
useradd -m spack-test
chown -R spack-test .
- name: Bootstrap GnuPG
shell: runuser -u spack-test -- bash {0}
run: |
source share/spack/setup-env.sh
spack solve zlib
spack bootstrap untrust github-actions
spack -d gpg list
tree ~/.spack/bootstrap/store/
macos-gnupg-binaries:
runs-on: macos-latest
steps:
- name: Install dependencies
run: |
brew install tree
# Remove GnuPG since we want to bootstrap it
sudo rm -rf /usr/local/bin/gpg
- uses: actions/checkout@v2
- name: Bootstrap GnuPG
run: |
source share/spack/setup-env.sh
spack bootstrap untrust spack-install
spack -d gpg list
tree ~/.spack/bootstrap/store/
macos-gnupg-sources:
runs-on: macos-latest
steps:
- name: Install dependencies
run: |
brew install gawk tree
# Remove GnuPG since we want to bootstrap it
sudo rm -rf /usr/local/bin/gpg
- uses: actions/checkout@v2
- name: Bootstrap GnuPG
run: |
source share/spack/setup-env.sh
spack solve zlib
spack bootstrap untrust github-actions
spack -d gpg list
tree ~/.spack/bootstrap/store/

View file

@ -6,6 +6,7 @@
import contextlib import contextlib
import fnmatch import fnmatch
import functools
import json import json
import os import os
import os.path import os.path
@ -34,11 +35,14 @@
import spack.repo import spack.repo
import spack.spec import spack.spec
import spack.store import spack.store
import spack.user_environment as uenv import spack.user_environment
import spack.util.executable import spack.util.executable
import spack.util.path import spack.util.path
from spack.util.environment import EnvironmentModifications from spack.util.environment import EnvironmentModifications
#: "spack buildcache" command, initialized lazily
_buildcache_cmd = None
#: Map a bootstrapper type to the corresponding class #: Map a bootstrapper type to the corresponding class
_bootstrap_methods = {} _bootstrap_methods = {}
@ -171,6 +175,34 @@ def _fix_ext_suffix(candidate_spec):
os.symlink(abs_path, link_name) os.symlink(abs_path, link_name)
def _executables_in_store(executables, abstract_spec_str):
"""Return True if at least one of the executables can be retrieved from
a spec in store, False otherwise.
The different executables must provide the same functionality and are
"alternate" to each other, i.e. the function will exit True on the first
executable found.
Args:
executables: list of executables to be searched
abstract_spec_str: abstract spec that may provide the executable
"""
executables_str = ', '.join(executables)
msg = "[BOOTSTRAP EXECUTABLES {0}] Try installed specs with query '{1}'"
tty.debug(msg.format(executables_str, abstract_spec_str))
installed_specs = spack.store.db.query(abstract_spec_str, installed=True)
if installed_specs:
for concrete_spec in installed_specs:
bin_dir = concrete_spec.prefix.bin
# IF we have a "bin" directory and it contains
# the executables we are looking for
if (os.path.exists(bin_dir) and os.path.isdir(bin_dir) and
spack.util.executable.which_string(*executables, path=bin_dir)):
spack.util.environment.path_put_first('PATH', [bin_dir])
return True
return False
@_bootstrapper(type='buildcache') @_bootstrapper(type='buildcache')
class _BuildcacheBootstrapper(object): class _BuildcacheBootstrapper(object):
"""Install the software needed during bootstrapping from a buildcache.""" """Install the software needed during bootstrapping from a buildcache."""
@ -178,93 +210,140 @@ def __init__(self, conf):
self.name = conf['name'] self.name = conf['name']
self.url = conf['info']['url'] self.url = conf['info']['url']
def try_import(self, module, abstract_spec_str): @staticmethod
if _try_import_from_store(module, abstract_spec_str): def _spec_and_platform(abstract_spec_str):
return True """Return the spec object and platform we need to use when
querying the buildcache.
tty.info("Bootstrapping {0} from pre-built binaries".format(module)) Args:
abstract_spec_str: abstract spec string we are looking for
"""
# This import is local since it is needed only on Cray
import spack.platforms.linux
# Try to install from an unsigned binary cache # Try to install from an unsigned binary cache
abstract_spec = spack.spec.Spec( abstract_spec = spack.spec.Spec(abstract_spec_str)
abstract_spec_str + ' ^' + spec_for_current_python()
)
# On Cray we want to use Linux binaries if available from mirrors # On Cray we want to use Linux binaries if available from mirrors
bincache_platform = spack.platforms.real_host() bincache_platform = spack.platforms.real_host()
if str(bincache_platform) == 'cray': if str(bincache_platform) == 'cray':
bincache_platform = spack.platforms.Linux() bincache_platform = spack.platforms.Linux()
with spack.platforms.use_platform(bincache_platform): with spack.platforms.use_platform(bincache_platform):
abstract_spec = spack.spec.Spec( abstract_spec = spack.spec.Spec(abstract_spec_str)
abstract_spec_str + ' ^' + spec_for_current_python() return abstract_spec, bincache_platform
)
# Read information on verified clingo binaries def _read_metadata(self, package_name):
json_filename = '{0}.json'.format(module) """Return metadata about the given package."""
json_filename = '{0}.json'.format(package_name)
json_path = os.path.join( json_path = os.path.join(
spack.paths.share_path, 'bootstrap', self.name, json_filename spack.paths.share_path, 'bootstrap', self.name, json_filename
) )
with open(json_path) as f: with open(json_path) as f:
data = json.load(f) data = json.load(f)
return data
buildcache = spack.main.SpackCommand('buildcache') def _install_by_hash(self, pkg_hash, pkg_sha256, index, bincache_platform):
global _buildcache_cmd
if _buildcache_cmd is None:
_buildcache_cmd = spack.main.SpackCommand('buildcache')
index_spec = next(x for x in index if x.dag_hash() == pkg_hash)
# Reconstruct the compiler that we need to use for bootstrapping
compiler_entry = {
"modules": [],
"operating_system": str(index_spec.os),
"paths": {
"cc": "/dev/null",
"cxx": "/dev/null",
"f77": "/dev/null",
"fc": "/dev/null"
},
"spec": str(index_spec.compiler),
"target": str(index_spec.target.family)
}
with spack.platforms.use_platform(bincache_platform):
with spack.config.override(
'compilers', [{'compiler': compiler_entry}]
):
spec_str = '/' + pkg_hash
install_args = [
'install',
'--sha256', pkg_sha256,
'--only-root',
'-a', '-u', '-o', '-f', spec_str
]
_buildcache_cmd(*install_args, fail_on_error=False)
def _install_and_test(
self, abstract_spec, bincache_platform, bincache_data, test_fn
):
# Ensure we see only the buildcache being used to bootstrap # Ensure we see only the buildcache being used to bootstrap
mirror_scope = spack.config.InternalConfigScope( with spack.config.override(self.mirror_scope):
'bootstrap_buildcache', {'mirrors:': {self.name: self.url}}
)
with spack.config.override(mirror_scope):
# This index is currently needed to get the compiler used to build some # This index is currently needed to get the compiler used to build some
# specs that wwe know by dag hash. # specs that we know by dag hash.
spack.binary_distribution.binary_index.regenerate_spec_cache() spack.binary_distribution.binary_index.regenerate_spec_cache()
index = spack.binary_distribution.update_cache_and_get_specs() index = spack.binary_distribution.update_cache_and_get_specs()
if not index: if not index:
raise RuntimeError("The binary index is empty") raise RuntimeError("The binary index is empty")
for item in data['verified']: for item in bincache_data['verified']:
candidate_spec = item['spec'] candidate_spec = item['spec']
python_spec = item['python'] # This will be None for things that don't depend on python
python_spec = item.get('python', None)
# Skip specs which are not compatible # Skip specs which are not compatible
if not abstract_spec.satisfies(candidate_spec): if not abstract_spec.satisfies(candidate_spec):
continue continue
if python_spec not in abstract_spec: if python_spec is not None and python_spec not in abstract_spec:
continue continue
for pkg_name, pkg_hash, pkg_sha256 in item['binaries']: for pkg_name, pkg_hash, pkg_sha256 in item['binaries']:
msg = ('[BOOTSTRAP MODULE {0}] Try installing "{1}" from binary ' # TODO: undo installations that didn't complete?
'cache at "{2}"') self._install_by_hash(
tty.debug(msg.format(module, pkg_name, self.url)) pkg_hash, pkg_sha256, index, bincache_platform
index_spec = next(x for x in index if x.dag_hash() == pkg_hash) )
# Reconstruct the compiler that we need to use for bootstrapping
compiler_entry = {
"modules": [],
"operating_system": str(index_spec.os),
"paths": {
"cc": "/dev/null",
"cxx": "/dev/null",
"f77": "/dev/null",
"fc": "/dev/null"
},
"spec": str(index_spec.compiler),
"target": str(index_spec.target.family)
}
with spack.platforms.use_platform(bincache_platform):
with spack.config.override(
'compilers', [{'compiler': compiler_entry}]
):
spec_str = '/' + pkg_hash
install_args = [
'install',
'--sha256', pkg_sha256,
'-a', '-u', '-o', '-f', spec_str
]
buildcache(*install_args, fail_on_error=False)
# TODO: undo installations that didn't complete?
if _try_import_from_store(module, abstract_spec_str): if test_fn():
return True return True
return False return False
@property
def mirror_scope(self):
return spack.config.InternalConfigScope(
'bootstrap', {'mirrors:': {self.name: self.url}}
)
def try_import(self, module, abstract_spec_str):
test_fn = functools.partial(_try_import_from_store, module, abstract_spec_str)
if test_fn():
return True
tty.info("Bootstrapping {0} from pre-built binaries".format(module))
abstract_spec, bincache_platform = self._spec_and_platform(
abstract_spec_str + ' ^' + spec_for_current_python()
)
data = self._read_metadata(module)
return self._install_and_test(
abstract_spec, bincache_platform, data, test_fn
)
def try_search_path(self, executables, abstract_spec_str):
test_fn = functools.partial(
_executables_in_store, executables, abstract_spec_str
)
if test_fn():
return True
abstract_spec, bincache_platform = self._spec_and_platform(
abstract_spec_str
)
tty.info("Bootstrapping {0} from pre-built binaries".format(abstract_spec.name))
data = self._read_metadata(abstract_spec.name)
return self._install_and_test(
abstract_spec, bincache_platform, data, test_fn
)
@_bootstrapper(type='install') @_bootstrapper(type='install')
class _SourceBootstrapper(object): class _SourceBootstrapper(object):
@ -307,6 +386,26 @@ def try_import(module, abstract_spec_str):
return _try_import_from_store(module, abstract_spec_str=abstract_spec_str) return _try_import_from_store(module, abstract_spec_str=abstract_spec_str)
def try_search_path(self, executables, abstract_spec_str):
if _executables_in_store(executables, abstract_spec_str):
return True
# If we compile code from sources detecting a few build tools
# 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)
concrete_spec.concretize()
msg = "[BOOTSTRAP GnuPG] Try installing '{0}' from sources"
tty.debug(msg.format(abstract_spec_str))
concrete_spec.package.do_install()
return _executables_in_store(executables, abstract_spec_str)
def _make_bootstrapper(conf): def _make_bootstrapper(conf):
"""Return a bootstrap object built according to the """Return a bootstrap object built according to the
@ -418,6 +517,44 @@ def ensure_module_importable_or_raise(module, abstract_spec=None):
raise ImportError(msg) raise ImportError(msg)
def ensure_executables_in_path_or_raise(executables, abstract_spec):
"""Ensure that some executables are in path or raise.
Args:
executables (list): list of executables to be searched in the PATH,
in order. The function exits on the first one found.
abstract_spec (str): abstract spec that provides the executables
Raises:
RuntimeError: if the executables cannot be ensured to be in PATH
"""
if spack.util.executable.which_string(*executables):
return
executables_str = ', '.join(executables)
source_configs = spack.config.get('bootstrap:sources', [])
for current_config in source_configs:
if not _source_is_trusted(current_config):
msg = ('[BOOTSTRAP EXECUTABLES {0}] Skipping source "{1}" since it is '
'not trusted').format(executables_str, current_config['name'])
tty.debug(msg)
continue
b = _make_bootstrapper(current_config)
try:
if b.try_search_path(executables, abstract_spec):
return
except Exception as e:
msg = '[BOOTSTRAP EXECUTABLES {0}] Unexpected error "{1}"'
tty.debug(msg.format(executables_str, str(e)))
# We couldn't import in any way, so raise an import error
msg = 'cannot bootstrap any of the {0} executables'.format(executables_str)
if abstract_spec:
msg += ' from spec "{0}"'.format(abstract_spec)
raise RuntimeError(msg)
def _python_import(module): def _python_import(module):
try: try:
__import__(module) __import__(module)
@ -455,7 +592,9 @@ def get_executable(exe, spec=None, install=False):
ret = spack.util.executable.Executable(exe_path[0]) ret = spack.util.executable.Executable(exe_path[0])
envmod = EnvironmentModifications() envmod = EnvironmentModifications()
for dep in ispec.traverse(root=True, order='post'): for dep in ispec.traverse(root=True, order='post'):
envmod.extend(uenv.environment_modifications_for_spec(dep)) envmod.extend(
spack.user_environment.environment_modifications_for_spec(dep)
)
ret.add_default_envmod(envmod) ret.add_default_envmod(envmod)
return ret return ret
else: else:
@ -484,7 +623,9 @@ def _raise_error(executable, exe_spec):
ret = spack.util.executable.Executable(exe_path[0]) ret = spack.util.executable.Executable(exe_path[0])
envmod = EnvironmentModifications() envmod = EnvironmentModifications()
for dep in spec.traverse(root=True, order='post'): for dep in spec.traverse(root=True, order='post'):
envmod.extend(uenv.environment_modifications_for_spec(dep)) envmod.extend(
spack.user_environment.environment_modifications_for_spec(dep)
)
ret.add_default_envmod(envmod) ret.add_default_envmod(envmod)
return ret return ret
@ -523,8 +664,11 @@ def _add_compilers_if_missing():
def _add_externals_if_missing(): def _add_externals_if_missing():
search_list = [ search_list = [
# clingo
spack.repo.path.get('cmake'), spack.repo.path.get('cmake'),
spack.repo.path.get('bison') spack.repo.path.get('bison'),
# GnuPG
spack.repo.path.get('gawk')
] ]
detected_packages = spack.detection.by_executable(search_list) detected_packages = spack.detection.by_executable(search_list)
spack.detection.update_configuration(detected_packages, scope='bootstrap') spack.detection.update_configuration(detected_packages, scope='bootstrap')
@ -600,10 +744,12 @@ def _config_path():
) )
def clingo_root_spec(): def _root_spec(spec_str):
# Construct the root spec that will be used to bootstrap clingo """Add a proper compiler and target to a spec used during bootstrapping.
spec_str = 'clingo-bootstrap@spack+python'
Args:
spec_str (str): spec to be bootstrapped. Must be without compiler and target.
"""
# Add a proper compiler hint to the root spec. We use GCC for # Add a proper compiler hint to the root spec. We use GCC for
# everything but MacOS. # everything but MacOS.
if str(spack.platforms.host()) == 'darwin': if str(spack.platforms.host()) == 'darwin':
@ -611,17 +757,32 @@ def clingo_root_spec():
else: else:
spec_str += ' %gcc' spec_str += ' %gcc'
# Add the generic target target = archspec.cpu.host().family
generic_target = archspec.cpu.host().family spec_str += ' target={0}'.format(target)
spec_str += ' target={0}'.format(str(generic_target))
tty.debug('[BOOTSTRAP ROOT SPEC] clingo: {0}'.format(spec_str))
tty.debug('[BOOTSTRAP ROOT SPEC] {0}'.format(spec_str))
return spec_str return spec_str
def clingo_root_spec():
"""Return the root spec used to bootstrap clingo"""
return _root_spec('clingo-bootstrap@spack+python')
def ensure_clingo_importable_or_raise(): def ensure_clingo_importable_or_raise():
"""Ensure that the clingo module is available for import.""" """Ensure that the clingo module is available for import."""
ensure_module_importable_or_raise( ensure_module_importable_or_raise(
module='clingo', abstract_spec=clingo_root_spec() module='clingo', abstract_spec=clingo_root_spec()
) )
def gnupg_root_spec():
"""Return the root spec used to bootstrap GnuPG"""
return _root_spec('gnupg@2.3:')
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(),
)

View file

@ -104,6 +104,9 @@ def setup_parser(subparser):
" instead of default platform and OS") " instead of default platform and OS")
# This argument is needed by the bootstrapping logic to verify checksums # This argument is needed by the bootstrapping logic to verify checksums
install.add_argument('--sha256', help=argparse.SUPPRESS) install.add_argument('--sha256', help=argparse.SUPPRESS)
install.add_argument(
'--only-root', action='store_true', help=argparse.SUPPRESS
)
arguments.add_common_arguments(install, ['specs']) arguments.add_common_arguments(install, ['specs'])
install.set_defaults(func=installtarball) install.set_defaults(func=installtarball)
@ -534,9 +537,14 @@ def install_tarball(spec, args):
if s.external or s.virtual: if s.external or s.virtual:
tty.warn("Skipping external or virtual package %s" % spec.format()) tty.warn("Skipping external or virtual package %s" % spec.format())
return return
for d in s.dependencies(deptype=('link', 'run')):
tty.msg("Installing buildcache for dependency spec %s" % d) # This argument is used only for bootstrapping specs without signatures,
install_tarball(d, args) # since we need to check the sha256 of each tarball
if not args.only_root:
for d in s.dependencies(deptype=('link', 'run')):
tty.msg("Installing buildcache for dependency spec %s" % d)
install_tarball(d, args)
package = spack.repo.get(spec) package = spack.repo.get(spec)
if s.concrete and package.installed and not args.force: if s.concrete and package.installed and not args.force:
tty.warn("Package for spec %s already installed." % spec.format()) tty.warn("Package for spec %s already installed." % spec.format())

View file

@ -40,7 +40,7 @@
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.lang import dedupe from llnl.util.lang import dedupe
import spack.build_environment as build_environment import spack.build_environment
import spack.config import spack.config
import spack.environment import spack.environment
import spack.error import spack.error
@ -732,12 +732,12 @@ def environment_modifications(self):
# Let the extendee/dependency modify their extensions/dependencies # Let the extendee/dependency modify their extensions/dependencies
# before asking for package-specific modifications # before asking for package-specific modifications
env.extend( env.extend(
build_environment.modifications_from_dependencies( spack.build_environment.modifications_from_dependencies(
spec, context='run' spec, context='run'
) )
) )
# Package specific modifications # Package specific modifications
build_environment.set_module_variables_for_package(spec.package) spack.build_environment.set_module_variables_for_package(spec.package)
spec.package.setup_run_environment(env) spec.package.setup_run_environment(env)
# Modifications required from modules.yaml # Modifications required from modules.yaml

View file

@ -9,6 +9,7 @@
import llnl.util.filesystem as fs import llnl.util.filesystem as fs
import spack.bootstrap
import spack.util.executable import spack.util.executable
import spack.util.gpg import spack.util.gpg
from spack.main import SpackCommand from spack.main import SpackCommand
@ -17,6 +18,7 @@
#: spack command used by tests below #: spack command used by tests below
gpg = SpackCommand('gpg') gpg = SpackCommand('gpg')
bootstrap = SpackCommand('bootstrap')
# test gpg command detection # test gpg command detection
@ -46,9 +48,10 @@ def test_find_gpg(cmd_name, version, tmpdir, mock_gnupghome, monkeypatch):
assert spack.util.gpg.GPGCONF is not None assert spack.util.gpg.GPGCONF is not None
def test_no_gpg_in_path(tmpdir, mock_gnupghome, monkeypatch): def test_no_gpg_in_path(tmpdir, mock_gnupghome, monkeypatch, mutable_config):
monkeypatch.setitem(os.environ, "PATH", str(tmpdir)) monkeypatch.setitem(os.environ, "PATH", str(tmpdir))
with pytest.raises(spack.util.gpg.SpackGPGError): bootstrap('disable')
with pytest.raises(RuntimeError):
spack.util.gpg.init(force=True) spack.util.gpg.init(force=True)

View file

@ -8,6 +8,7 @@
import os import os
import re import re
import spack.bootstrap
import spack.error import spack.error
import spack.paths import spack.paths
import spack.util.executable import spack.util.executable
@ -59,7 +60,10 @@ def init(gnupghome=None, force=False):
spack.paths.gpg_path) spack.paths.gpg_path)
# Set the executable objects for "gpg" and "gpgconf" # Set the executable objects for "gpg" and "gpgconf"
GPG, GPGCONF = _gpg(), _gpgconf() with spack.bootstrap.ensure_bootstrap_configuration():
spack.bootstrap.ensure_gpg_in_path_or_raise()
GPG, GPGCONF = _gpg(), _gpgconf()
GPG.add_default_env('GNUPGHOME', GNUPGHOME) GPG.add_default_env('GNUPGHOME', GNUPGHOME)
if GPGCONF: if GPGCONF:
GPGCONF.add_default_env('GNUPGHOME', GNUPGHOME) GPGCONF.add_default_env('GNUPGHOME', GNUPGHOME)

View file

@ -0,0 +1,204 @@
{
"verified": [
{
"binaries": [
[
"libgpg-error",
"hph66gvb7vlinpzwoytxq27ojb7gtl2j",
"f040f513e212c428ee863d75924331f58b5f8f3946f98c757a9e0af0d0a34f63"
],
[
"libiconv",
"ckpif6rcf7mxdmceyv6sqvtnwfqi7fmc",
"1d745d04f7c8a1c4d17d9735eba0ee88c8acfbb213c22a15e45e58637867ed4c"
],
[
"npth",
"fjuoy73whriauk3bt6ma5fwet6iric7y",
"78d5d9e339ef901b0def0924a72ce87a93e0a8acb7394ec2c35be6c328154444"
],
[
"zlib",
"qo6otxqnn6mxpw4zhqc4wdwqmgcfjdfe",
"f00c38ecaf316cd665399ed14c233f839ae5868387ff04998e1ec949c1f4dcd6"
],
[
"libassuan",
"2upi74qccouj4k6d7wultp2u5fntayi3",
"f2118b102f9a94bb1e2804492689b44b260b7f6e46ac1208d5110ebffe24bf99"
],
[
"libgcrypt",
"xzhvvm44cfxwvgqgkpbeucpnl4dbj4p2",
"ae717e068f2f7f4eaeee4bdec4a6b20ff299c59c3d724c1661b6045fda628a9b"
],
[
"libksba",
"aodyg5mzfule3vimuetmzulv5mzdx37g",
"c665eb20f27b2d28fcb634fe958829165e44a27b1ad69995d5040f13d5693d52"
],
[
"pinentry",
"ihqcvdm5okxuvnln463l7h4flbkhrp44",
"b0c7781354eb4a7c9e979802590c0e4fb7eb53f440191367f0142eac4868f8d6"
],
[
"gnupg",
"47vilwybwuxved7jov7esiad3qlkv5rp",
"83f3de13b2712a05f520d16b5141797493f8b117041dd32aa5414a25d9d53439"
]
],
"spec": "gnupg@2.3: %apple-clang platform=darwin target=x86_64"
},
{
"binaries": [
[
"libgpg-error",
"3dkguooajaaejhsebigs2e3lhk37mtem",
"09c5edd93fb479961d62d9938c1ea02b8f443babf0e79776f1539085c3422cd5"
],
[
"libiconv",
"i2eqtudh3zcxt5fvxuhe6n2ztuqbadtp",
"838786e029474d668b5f83a9669d227c812253c3c3f0328aa4f888542a7de830"
],
[
"npth",
"c3z6gg3ilutvvryxkjrboampqv5u5s2s",
"967522ae988ccce8c922f28aa2124170246f501f0a45179b919d827bf28c35d2"
],
[
"zlib",
"p2jozvok56voja7652dms4gvthpcjzta",
"41cbc69850640ed4466dbedc1bb4ccb0ade0c1a1e8fcd70d1e247b1387b937b5"
],
[
"libassuan",
"s2wx2xvt3iz3sigcdt5tvppj2m7e2bsf",
"5f766af4ff355769e3e456a9c95636a20a64f5ba32aecec633216a3d83a854f8"
],
[
"libgcrypt",
"gznmtryix6ck4x3chnuvbctz4xa3fmxl",
"0261b03f790c5320980d27bf0a471a1a4663929689ddfaeb5e568d33be8dc889"
],
[
"libksba",
"uxaryyfybbcw563jcwumufhfmbsawlbz",
"f45fff7a6a5c626a1474c7354fd00e18e629fcd086787336f7d62d1ead50c94f"
],
[
"pinentry",
"ias6sb4qi24u6i7axr5hkj4liq5dtr6l",
"a2a8e7652dceb7d080ff78726d28099f9050cb9f6e290d97f1f59f4b42521b9c"
],
[
"gnupg",
"qpm457bujhmfqy66euzhswokumuvufbz",
"d2371e26412e10fc702b9b2482aff776108194b84e1927644a3d64f5710fd163"
]
],
"spec": "gnupg@2.3: %gcc platform=linux target=aarch64"
},
{
"binaries": [
[
"libgpg-error",
"4bp6dcfdbzbd4uuzvbgjyqunhjedg3lf",
"9a9947240c6af7e915aa8336bfaed8706c9129967eb9ab1895598217df91f301"
],
[
"libiconv",
"dscneqtpyy32r6ds24izlkki3euthnbr",
"a9dc099f6c7ee9fd6c63757cb81a59fe4b81672543d5253a50bb73bc819440ef"
],
[
"npth",
"jukmafxhkxo2s4udlzi5r5b6bbb3udw5",
"d2a2b11c0f1794ab0de813753221bde073508fbec19f0b15dbfd23455bc6de87"
],
[
"zlib",
"amqfrcbn67rochzkeu2ashklo35ayqqq",
"686fc10058d208530889bc5c3779aa2cc324b77301878a5405cf65ca53d613ba"
],
[
"libassuan",
"lyeih2j3miy7yugmwh37h667fogqn3fl",
"f87c474d81c890232cd8e1e4d93b5b232aa0ad428dcaa7231d7a8d182cea9ecc"
],
[
"libgcrypt",
"zb33zulvwcansfzu5km4d34avujnazfa",
"e67ae6a5345f9e864bd2009c1a9d7eb65a63ca2841368bebc477a770fb8dcaf5"
],
[
"libksba",
"yjuh2aplj23qyvaqixukd7a6eokfdgyp",
"6944fc047e8f0eb41daec734e2505016369319c64929f5ec8d3a8f99e01928d4"
],
[
"pinentry",
"xd7vajghgcueohv5qgahdvbjpcnrurns",
"a6b37efd6ef9f9374aa0c7d1869da990ae3668938b47ad6af50138d2ea05da02"
],
[
"gnupg",
"ti2ddl27nilobj2ctwsgzl52qque5o7z",
"43781437e3dfae158e7a6911313a4162d8ffa5313182438d1e6547a854f6f38a"
]
],
"spec": "gnupg@2.3: %gcc platform=linux target=ppc64le"
},
{
"binaries": [
[
"libgpg-error",
"p7chd5hhecdkc27npia4uaoeabjit4gh",
"4b5e1f418b7afdd91755d54d38a51d5d048aa3b1e5239bcaf3453c8ca1cca4b6"
],
[
"libiconv",
"scpkgy6bmk3wcgfwzoiv7hw74drmnaoi",
"2bcb9a2868c20284ce65ab53d4f7bb4c7edccd4c14390460858e25a8bc48faa3"
],
[
"npth",
"6vh3jypaf7u2zez3vohn66fvo6znt35l",
"23a333c4e83910eb1f87c91caffb07f40b592561a4c44924fed9459751c017f7"
],
[
"zlib",
"uc25tb5r57nykfrxszsdy54trzqnk2jn",
"9e18c1146bc3dcb8454d18502013b8621ecf00d2f2d4d66d76cbe1e07f351ac8"
],
[
"libassuan",
"vdoskg5mldu6ixhvftwplp4zdftwxwws",
"1413b84af0c58127032e7bde86dbacf35dc65205aee1c2071718678bc57ce793"
],
[
"libgcrypt",
"ng7gfusjpnypmqgckq7rp4vq3bvylp3b",
"1a09e97eb2333812f8381d4737aca4d7cfd9f27ebae30eddbcf99f399ad67fec"
],
[
"libksba",
"p4feho36xa7dhabk766fzglwyo2dfbj6",
"000ef0f2ad3aa05c07272849be68e059ec60946970ab8875a824305afe832c9a"
],
[
"pinentry",
"m423kpm7k52r66q3sdctqcjxtekiyrrp",
"5739bee66271d7f0d5b9bcf5c248f1a434e9cdcb327a4a5a22fc47f565ac0de7"
],
[
"gnupg",
"dlapzqxrwduafgfq2evptizb7p4kgpkh",
"262177fa8f66468e589f8b3e10d17531f17a74ea0f5ac6905ac948198dca3c3c"
]
],
"spec": "gnupg@2.3: %gcc platform=linux target=x86_64"
}
]
}

View file

@ -511,7 +511,7 @@ _spack_buildcache_create() {
_spack_buildcache_install() { _spack_buildcache_install() {
if $list_options if $list_options
then then
SPACK_COMPREPLY="-h --help -f --force -m --multiple -a --allow-root -u --unsigned -o --otherarch --sha256" SPACK_COMPREPLY="-h --help -f --force -m --multiple -a --allow-root -u --unsigned -o --otherarch --sha256 --only-root"
else else
_all_packages _all_packages
fi fi