diff --git a/doc/examples/defaults.conf-rsh b/doc/examples/defaults.conf-rsh index 140201eb..84540798 100644 --- a/doc/examples/defaults.conf-rsh +++ b/doc/examples/defaults.conf-rsh @@ -4,7 +4,8 @@ # Example defaults.conf file for clusters using rsh instead of ssh. # # To enable this file, install it in one of the following locations: -# /etc/clustershell/defaults.conf (system-wide) +# $CLUSTERSHELL_CFGDIR/defaults.conf (global configuration, default to +# /etc/clustershell/defaults.conf) # $XDG_CONFIG_HOME/clustershell/defaults.conf (per-user) # $HOME/.local/etc/clustershell/defaults.conf (per-user) # diff --git a/doc/sphinx/config.rst b/doc/sphinx/config.rst index 1320d48f..204baee2 100644 --- a/doc/sphinx/config.rst +++ b/doc/sphinx/config.rst @@ -8,13 +8,16 @@ Configuration clush ----- -The following configuration file defines system-wide default values for +The following configuration file defines global default values for several *clush* tool parameters:: - /etc/clustershell/clush.conf + $CLUSTERSHELL_CFGDIR/clush.conf + +If *$CLUSTERSHELL_CFGDIR* is not defined, */etc/clustershell/clush.conf* will +be used, -*clush* settings might then be overridden per user if one of the following -files is found, in priority order:: +*clush* settings might then be overridden (globally, or per user) if one of the +following files is found, in priority order:: $XDG_CONFIG_HOME/clustershell/clush.conf $HOME/.config/clustershell/clush.conf (only if $XDG_CONFIG_HOME is not defined) @@ -123,13 +126,16 @@ ClusterShell loads *groups.conf* configuration files that define how to obtain node groups configuration, ie. the way the library should access file-based or external node group **sources**. -The following configuration file defines system-wide default values for +The following configuration file defines global default values for *groups.conf*:: - /etc/clustershell/groups.conf + $CLUSTERSHELL_CFGDIR/groups.conf + +If *$CLUSTERSHELL_CFGDIR* is not defined, */etc/clustershell/groups.conf* will +be used, -*groups.conf* settings might then be overridden per user if one of the -following files is found, in priority order:: +*groups.conf* settings might then be overridden (globally, or per user) if one +of the following files is found, in priority order:: $XDG_CONFIG_HOME/clustershell/groups.conf $HOME/.config/clustershell/groups.conf (only if $XDG_CONFIG_HOME is not defined) @@ -542,10 +548,13 @@ in *defaults.conf*. The following configuration file defines ClusterShell system-wide defaults:: - /etc/clustershell/defaults.conf + $CLUSTERSHELL_CFGDIR/defaults.conf -*defaults.conf* settings might then be overridden per user if one of the -following files is found, in priority order:: +If *$CLUSTERSHELL_CFGDIR* is not defined, */etc/clustershell/defaults.conf* +will be used, + +*defaults.conf* settings might then be overridden (globally, or per user) if +one of the following files is found, in priority order:: $XDG_CONFIG_HOME/clustershell/defaults.conf $HOME/.config/clustershell/defaults.conf (only if $XDG_CONFIG_HOME is not defined) diff --git a/doc/sphinx/release.rst b/doc/sphinx/release.rst index fbd1f116..574aa201 100644 --- a/doc/sphinx/release.rst +++ b/doc/sphinx/release.rst @@ -564,8 +564,11 @@ versions. Configuration files """"""""""""""""""" -When ``$XDG_CONFIG_HOME`` is defined, ClusterShell will use it to search for -additional configuration files. +When ``$CLUSTERSHELL_CFGDIR`` or ``$XDG_CONFIG_HOME`` are defined, +ClusterShell will use them to search for additional configuration files. + +If ``$CLUSTERSHELL_CFGDIR`` is not defined, the global configuration files will +be searched for in `/etc/clustershell` PIP user installation support """"""""""""""""""""""""""""" diff --git a/doc/txt/clush.conf.txt b/doc/txt/clush.conf.txt index 34b928fe..938dbdf8 100644 --- a/doc/txt/clush.conf.txt +++ b/doc/txt/clush.conf.txt @@ -23,7 +23,8 @@ following order: 1. command-line options 2. user configuration file (*$XDG_CONFIG_HOME/clustershell/clush.conf*) 3. local pip user installation (*$HOME/.local/etc/clustershell/clush.conf*) - 4. system-wide configuration file (*/etc/clustershell/clush.conf*) + 4. global configuration file (*$CLUSTERSHELL_CFGDIR/clush.conf*, defaults to + */etc/clustershell/clush.conf*) For each parameter, the first obtained value will be used. @@ -122,8 +123,9 @@ Simple configuration file. FILES ===== -*/etc/clustershell/clush.conf* - System-wide clush configuration file. +*$CLUSTERSHELL_CFGDIR/clush.conf* + Global clush configuration file. If $CLUSTERSHELL_CFGDIR is not defined, + */etc/slutershell/clush.conf* is used instead. *$XDG_CONFIG_HOME/clustershell/clush.conf* User configuration file for clush. If $XDG_CONFIG_HOME is not defined, diff --git a/doc/txt/clush.txt b/doc/txt/clush.txt index 61aa8465..09c1df0a 100644 --- a/doc/txt/clush.txt +++ b/doc/txt/clush.txt @@ -278,8 +278,9 @@ Copy files FILES ===== -*/etc/clustershell/clush.conf* - System-wide clush configuration file. +*$CLUSTERSHELL_CFGDIR/clush.conf* + Global clush configuration file. If $CLUSTERSHELL_CFGDIR is not defined, + */etc/clustershell/clush.conf* is used instead. *$XDG_CONFIG_HOME/clustershell/clush.conf* User configuration file for clush. If $XDG_CONFIG_HOME is not defined, diff --git a/doc/txt/groups.conf.txt b/doc/txt/groups.conf.txt index e361653c..9676526b 100644 --- a/doc/txt/groups.conf.txt +++ b/doc/txt/groups.conf.txt @@ -22,7 +22,8 @@ following sources in the following order: 1. user configuration file (*$XDG_CONFIG_HOME/clustershell/groups.conf*) 2. local pip user installation (*$HOME/.local/etc/clustershell/groups.conf*) - 3. system-wide configuration file (*/etc/clustershell/groups.conf*) + 3. Global configuration file (*$CLUSTERSHELL_CFGDIR/groups.conf*, defaults to + */etc/clustershell/groups.conf*) If no *groups.conf* is found, group support will be disabled. @@ -159,13 +160,14 @@ Simple configuration file for local groups and slurm partitions binding. FILES ===== -*/etc/clustershell/groups.conf* - System-wide node groups configuration file. +*$CLUSTERSHELL_CFGDIR/groups.conf* (defaults to */etc/clustershell/groups.conf*) + Global node groups configuration file. -*/etc/clustershell/groups.conf.d/* +*$CLUSTERSHELL_CFGDIR/groups.conf.d/* (defaults to + */etc/clustershell/groups.conf.d/*) Recommended directory for additional configuration files. -*/etc/clustershell/groups.d/* +*$CLUSTERSHELL_CFGDIR/groups.d/* (defaults to */etc/clustershell/groups.d/*) Recommended directory for *autodir*, where native group definition files (.yaml files) are found. diff --git a/lib/ClusterShell/Defaults.py b/lib/ClusterShell/Defaults.py index ce8b4741..a4406688 100644 --- a/lib/ClusterShell/Defaults.py +++ b/lib/ClusterShell/Defaults.py @@ -90,7 +90,9 @@ def _distant_workerclass(defaults): def config_paths(config_name): """Return default path list for a ClusterShell config file name.""" - return ['/etc/clustershell/%s' % config_name, # system-wide config file + return [os.path.join(os.environ.get('CLUSTERSHELL_CFGDIR', + '/etc/clustershell/%s'), + config_name), # global config file # default pip --user config file os.path.expanduser('~/.local/etc/clustershell/%s' % config_name), # per-user config (top override) diff --git a/tests/CLIConfigTest.py b/tests/CLIConfigTest.py index 2853398c..42e6bf1c 100644 --- a/tests/CLIConfigTest.py +++ b/tests/CLIConfigTest.py @@ -319,6 +319,59 @@ def testClushConfigWithInstalledConfig(self): options, _ = parser.parse_args([]) config = ClushConfig(options) + def testClushConfigCustomGlobal(self): + """test CLI.Config.ClushConfig (CLUSTERSHELL_CFGDIR global custom + config) + """ + + # Save existing environment variable, if it's defined + custom_config_save = os.environ.get('CLUSTERSHELL_CFGDIR') + + # Create fake CLUSTERSHELL_CFGDIR + custom_cfg_dir = make_temp_dir() + + try: + os.environ['CLUSTERSHELL_CFGDIR'] = custom_cfg_dir + + cfgfile = open(os.path.join(custom_cfg_dir, 'clush.conf'), 'w') + cfgfile.write(dedent(""" + [Main] + fanout: 42 + connect_timeout: 14 + command_timeout: 0 + history_size: 100 + color: never + verbosity: 2 + ssh_user: joebar + ssh_path: ~/bin/ssh + ssh_options: -oSomeDummyUserOption=yes + """)) + + cfgfile.flush() + parser = OptionParser("dummy") + parser.install_clush_config_options() + parser.install_display_options(verbose_options=True) + parser.install_connector_options() + options, _ = parser.parse_args([]) + config = ClushConfig(options) # filename=None to use defaults! + self.assertEqual(config.color, THREE_CHOICES[1]) + self.assertEqual(config.verbosity, VERB_VERB) # takes biggest + self.assertEqual(config.fanout, 42) + self.assertEqual(config.connect_timeout, 14) + self.assertEqual(config.command_timeout, 0) + self.assertEqual(config.ssh_user, 'joebar') + self.assertEqual(config.ssh_path, '~/bin/ssh') + self.assertEqual(config.ssh_options, '-oSomeDummyUserOption=yes') + cfgfile.close() + + finally: + if custom_config_save: + os.environ['CLUSTERSHELL_CFGDIR'] = custom_config_save + else: + del os.environ['CLUSTERSHELL_CFGDIR'] + shutil.rmtree(custom_cfg_dir, ignore_errors=True) + + def testClushConfigUserOverride(self): """test CLI.Config.ClushConfig (XDG_CONFIG_HOME user config)"""