diff --git a/lib/spack/docs/configuration.rst b/lib/spack/docs/configuration.rst index 32e1a8c170..5f76a76c81 100644 --- a/lib/spack/docs/configuration.rst +++ b/lib/spack/docs/configuration.rst @@ -45,20 +45,27 @@ Configuration Scopes ------------------------- Spack pulls configuration data from files in several directories. There -are three configuration scopes. From lowest to highest: +are four configuration scopes. From lowest to highest: -1. **defaults**: Stored in ``$(prefix)/etc/spack/defaults/``. These are +#. **defaults**: Stored in ``$(prefix)/etc/spack/defaults/``. These are the "factory" settings. Users should generally not modify the settings here, but should override them in other configuration scopes. The defaults here will change from version to version of Spack. -2. **site**: Stored in ``$(prefix)/etc/spack/``. Settings here affect +#. **system**: Stored in ``/etc/spack``. These are settings for this + machine, or for all machines on which this file system is + mounted. The site scope can be used for settings idiosyncratic to a + particular machine, such as the locations of compilers or external + packages. These settings are presumably controlled by someone with + root access on the machine. + +#. **site**: Stored in ``$(prefix)/etc/spack/``. Settings here affect only *this instance* of Spack, and they override defaults. The site scope can can be used for per-project settings (one spack instance per project) or for site-wide settings on a multi-user machine (e.g., for a common spack instance). -3. **user**: Stored in the home directory: ``~/.spack/``. These settings +#. **user**: Stored in the home directory: ``~/.spack/``. These settings affect all instances of Spack and take the highest precedence. Each configuration directory may contain several configuration files, @@ -78,22 +85,25 @@ Platform-specific scopes ------------------------- For each scope above, there can *also* be platform-specific settings. -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 scope precedence is: +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 ``system``, ``system/bgq``, ``site``, ``site/bgq``, +``user``, or ``user/bgq``. So, the full scope precedence is: 1. ``defaults`` 2. ``defaults/`` -3. ``site`` -4. ``site/`` -5. ``user`` -6. ``user/`` +3. ``system`` +4. ``system/`` +5. ``site`` +6. ``site/`` +7. ``user`` +8. ``user/`` You can get the name to use for ```` by running ``spack arch ---platform``. +--platform``. The system config scope has a ```` section for +sites at which ``/etc`` is mounted on multiple heterogeneous machines. ------------------------- Scope precedence diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py index 3f99c5581c..b67fcaf2f6 100644 --- a/lib/spack/spack/__init__.py +++ b/lib/spack/spack/__init__.py @@ -64,9 +64,9 @@ user_config_path = os.path.expanduser('~/.spack') prefix = spack_root -opt_path = join_path(prefix, "opt") -etc_path = join_path(prefix, "etc") - +opt_path = join_path(prefix, "opt") +etc_path = join_path(prefix, "etc") +system_etc_path = '/etc' # GPG paths. gpg_keys_path = join_path(var_path, "gpg") diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py index 585df23320..826e74bbbb 100644 --- a/lib/spack/spack/compilers/__init__.py +++ b/lib/spack/spack/compilers/__init__.py @@ -100,7 +100,8 @@ def init_compiler_config(): # Check the site config and update the user config if # nothing is configured at the site level. site_config = spack.config.get_config('compilers', scope='site') - if not site_config: + sys_config = spack.config.get_config('compilers', scope='system') + if not site_config and not sys_config: init_compiler_config() config = spack.config.get_config('compilers', scope=scope) return config diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py index 7c3d614aee..d0d6b6be2d 100644 --- a/lib/spack/spack/config.py +++ b/lib/spack/spack/config.py @@ -30,6 +30,7 @@ configuration system behaves. The scopes are: #. ``default`` + #. ``system`` #. ``site`` #. ``user`` @@ -211,11 +212,17 @@ def __repr__(self): _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.""" + versioned with Spack and can be overridden by systems, sites or users.""" _defaults_path = os.path.join(spack.etc_path, 'spack', 'defaults') ConfigScope('defaults', _defaults_path) ConfigScope('defaults/%s' % _platform, os.path.join(_defaults_path, _platform)) +"""System configuration is per machine. + No system-level configs should be checked into spack by default""" +_system_path = os.path.join(spack.system_etc_path, 'spack') +ConfigScope('system', _system_path) +ConfigScope('system/%s' % _platform, os.path.join(_system_path, _platform)) + """Site configuration is per spack instance, for sites or projects. No site-level configs should be checked into spack by default.""" _site_path = os.path.join(spack.etc_path, 'spack') @@ -398,6 +405,7 @@ def get_config(section, scope=None): for scope in scopes: # read potentially cached data from the scope. + data = scope.get_section(section) # Skip empty configs diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py index c8720ddbc8..19e7844090 100644 --- a/lib/spack/spack/test/conftest.py +++ b/lib/spack/spack/test/conftest.py @@ -173,6 +173,7 @@ def config(configuration_dir): real_scope = spack.config.config_scopes spack.config.config_scopes = ordereddict_backport.OrderedDict() spack.config.ConfigScope('site', str(configuration_dir.join('site'))) + spack.config.ConfigScope('system', str(configuration_dir.join('system'))) spack.config.ConfigScope('user', str(configuration_dir.join('user'))) Config = collections.namedtuple('Config', ['real', 'mock'])