From 193f68083f71f43027e8c89e11319b9e64a70bce Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Sat, 15 Oct 2016 17:00:11 -0700 Subject: Platform-specific config scopes (#2030) * Add platform-specific configuration scopes. * Update `spack config` to use the new scope arguments. --- lib/spack/spack/architecture.py | 3 +- lib/spack/spack/cmd/config.py | 9 ++--- lib/spack/spack/config.py | 75 ++++++++++++++++++++++++++++++++--------- 3 files changed, 64 insertions(+), 23 deletions(-) diff --git a/lib/spack/spack/architecture.py b/lib/spack/spack/architecture.py index 57e266722e..b14de35109 100644 --- a/lib/spack/spack/architecture.py +++ b/lib/spack/spack/architecture.py @@ -83,7 +83,6 @@ from llnl.util.filesystem import join_path import llnl.util.tty as tty import spack -import spack.compilers from spack.util.naming import mod_to_class from spack.util.environment import get_path from spack.util.multiproc import parmap @@ -276,6 +275,8 @@ class OperatingSystem(object): # Once the paths are cleaned up, do a search for each type of # compiler. We can spawn a bunch of parallel searches to reduce # the overhead of spelunking all these directories. + # NOTE: we import spack.compilers here to avoid init order cycles + import spack.compilers types = spack.compilers.all_compiler_types() compiler_lists = parmap(lambda cmp_cls: self.find_compiler(cmp_cls, *filtered_path), diff --git a/lib/spack/spack/cmd/config.py b/lib/spack/spack/cmd/config.py index c189e37036..5e041192e2 100644 --- a/lib/spack/spack/cmd/config.py +++ b/lib/spack/spack/cmd/config.py @@ -29,13 +29,8 @@ description = "Get and set configuration options." def setup_parser(subparser): # User can only choose one - scope_group = subparser.add_mutually_exclusive_group() - scope_group.add_argument( - '--user', action='store_const', const='user', dest='scope', - help="Use config file in user home directory (default).") - scope_group.add_argument( - '--site', action='store_const', const='site', dest='scope', - help="Use config file in spack prefix.") + subparser.add_argument('--scope', choices=spack.config.config_scopes, + help="Configuration scope to read/modify.") sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='config_command') diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py index dec43726a0..6a67f01d66 100644 --- a/lib/spack/spack/config.py +++ b/lib/spack/spack/config.py @@ -30,18 +30,47 @@ Configuration file scopes When Spack runs, it pulls configuration data from several config directories, each of which contains configuration files. In Spack, -there are two configuration scopes: - -1. ``site``: Spack loads site-wide configuration options from - ``$(prefix)/etc/spack/``. - -2. ``user``: Spack next loads per-user configuration options from - ``~/.spack/``. - -Spack may read configuration files from both of these locations. When -configurations conflict, the user config options take precedence over -the site configurations. Each configuration directory may contain -several configuration files, such as compilers.yaml or mirrors.yaml. +there are three configuration scopes (lowest to highest): + +1. ``defaults``: Spack loads default configuration settings from + ``$(prefix)/etc/spack/defaults/``. These settings are the "out of the + box" settings Spack will use without site- or user- modification, and + this is where settings that are versioned with Spack should go. + +2. ``site``: This scope affects only this *instance* of Spack, and + overrides the ``defaults`` scope. Configuration files in + ``$(prefix)/etc/spack/`` determine site scope. These can be used for + per-project settings (for users with their own spack instance) or for + site-wide settings (for admins maintaining a common spack instance). + +3. ``user``: User configuration goes in the user's home directory, + specifically in ``~/.spack/``. + +Spack may read configuration files from any of these locations. When +configurations conflict, settings from higher-precedence scopes override +lower-precedence settings. + +fCommands that modify scopes (``spack compilers``, ``spack config``, +etc.) take a ``--scope=`` parameter that you can use to control +which scope is modified. + +For each scope above, there can *also* be platform-specific +overrides. For example, on Blue Gene/Q machines, Spack needs to know the +location of cross-compilers for the compute nodes. This configuration is +in ``etc/spack/defaults/bgq/compilers.yaml``. It will take precedence +over settings in the ``defaults`` scope, but can still be overridden by +settings in ``site``, ``site/bgq``, ``user``, or ``user/bgq``. So, the +full list of scopes and their precedence is: + +1. ``defaults`` +2. ``defaults/`` +3. ``site`` +4. ``site/`` +5. ``user`` +6. ``user/`` + +Each configuration directory may contain several configuration files, +such as compilers.yaml or mirrors.yaml. ========================= Configuration file format @@ -118,6 +147,7 @@ a key in a configuration file. For example, this:: Will make Spack take compilers *only* from the user configuration, and the site configuration will be ignored. + """ import copy @@ -135,6 +165,7 @@ import llnl.util.tty as tty from llnl.util.filesystem import mkdirp import spack +import spack.architecture from spack.error import SpackError import spack.schema @@ -267,16 +298,30 @@ class ConfigScope(object): """Empty cached config information.""" self.sections = {} +# +# Below are configuration scopes. +# +# Each scope can have per-platfom overrides in subdirectories of the +# configuration directory. +# +_platform = spack.architecture.platform().name + """Default configuration scope is the lowest-level scope. These are versioned with Spack and can be overridden by sites or users.""" -ConfigScope('defaults', os.path.join(spack.etc_path, 'spack', 'defaults')) +_defaults_path = os.path.join(spack.etc_path, 'spack', 'defaults') +ConfigScope('defaults', _defaults_path) +ConfigScope('defaults/%s' % _platform, os.path.join(_defaults_path, _platform)) """Site configuration is per spack instance, for sites or projects. No site-level configs should be checked into spack by default.""" -ConfigScope('site', os.path.join(spack.etc_path, 'spack')) +_site_path = os.path.join(spack.etc_path, 'spack') +ConfigScope('site', _site_path) +ConfigScope('site/%s' % _platform, os.path.join(_site_path, _platform)) """User configuration can override both spack defaults and site config.""" -ConfigScope('user', spack.user_config_path) +_user_path = spack.user_config_path +ConfigScope('user', _user_path) +ConfigScope('user/%s' % _platform, os.path.join(_user_path, _platform)) def highest_precedence_scope(): -- cgit v1.2.3-70-g09d2