Add cdist info command

This commit is contained in:
Darko Poljak 2019-12-30 09:32:15 +01:00
parent df05abd15b
commit 57298bcab8
5 changed files with 194 additions and 36 deletions

View file

@ -6,6 +6,7 @@ import collections
import functools import functools
import cdist.configuration import cdist.configuration
import cdist.preos import cdist.preos
import cdist.info
# set of beta sub-commands # set of beta sub-commands
@ -436,6 +437,30 @@ def get_parsers():
' should be POSIX compatible shell.')) ' should be POSIX compatible shell.'))
parser['shell'].set_defaults(func=cdist.shell.Shell.commandline) parser['shell'].set_defaults(func=cdist.shell.Shell.commandline)
# Info
parser['info'] = parser['sub'].add_parser('info')
parser['info'].add_argument(
'-a', '--all', help='Display all info.', action='store_true',
default=False)
parser['info'].add_argument(
'-c', '--conf-dir',
help='Add configuration directory (can be repeated).',
action='append')
parser['info'].add_argument(
'-e', '--global-explorers',
help='Display info for global explorers.', action='store_true',
default=False)
parser['info'].add_argument(
'-H', '--suppress-headers',
help='Suppress displaying header lines.', action='store_true',
default=False)
parser['info'].add_argument(
'-t', '--types', help='Display info for types.',
action='store_true', default=False)
parser['info'].add_argument(
'pattern', nargs='?', help='Glob pattern.')
parser['info'].set_defaults(func=cdist.info.Info.commandline)
for p in parser: for p in parser:
parser[p].epilog = EPILOG parser[p].epilog = EPILOG

View file

@ -69,7 +69,6 @@ class Local(object):
self.exec_path = exec_path self.exec_path = exec_path
self.custom_initial_manifest = initial_manifest self.custom_initial_manifest = initial_manifest
self._add_conf_dirs = add_conf_dirs
self.cache_path_pattern = cache_path_pattern self.cache_path_pattern = cache_path_pattern
self.quiet_mode = quiet_mode self.quiet_mode = quiet_mode
if configuration: if configuration:
@ -84,16 +83,7 @@ class Local(object):
self._init_cache_dir(None) self._init_cache_dir(None)
self._init_paths() self._init_paths()
self._init_object_marker() self._init_object_marker()
self._init_conf_dirs() self._init_conf_dirs(add_conf_dirs)
@property
def dist_conf_dir(self):
return os.path.abspath(os.path.join(os.path.dirname(cdist.__file__),
"conf"))
@property
def home_dir(self):
return cdist.home_dir()
def _init_log(self): def _init_log(self):
self.log = logging.getLogger(self.target_host[0]) self.log = logging.getLogger(self.target_host[0])
@ -140,28 +130,9 @@ class Local(object):
# Does not need to be secure - just randomly different from .cdist # Does not need to be secure - just randomly different from .cdist
self.object_marker_name = tempfile.mktemp(prefix='.cdist-', dir='') self.object_marker_name = tempfile.mktemp(prefix='.cdist-', dir='')
def _init_conf_dirs(self): def _init_conf_dirs(self, add_conf_dirs):
self.conf_dirs = [] self.conf_dirs = util.resolve_conf_dirs(
self.configuration, add_conf_dirs=add_conf_dirs)
self.conf_dirs.append(self.dist_conf_dir)
# Is the default place for user created explorer, type and manifest
if self.home_dir:
self.conf_dirs.append(self.home_dir)
# Add directories defined in the CDIST_PATH environment variable
# if 'CDIST_PATH' in os.environ:
# cdist_path_dirs = re.split(r'(?<!\\):', os.environ['CDIST_PATH'])
# cdist_path_dirs.reverse()
# self.conf_dirs.extend(cdist_path_dirs)
if 'conf_dir' in self.configuration:
conf_dirs = self.configuration['conf_dir']
if conf_dirs:
self.conf_dirs.extend(conf_dirs)
# Add command line supplied directories
if self._add_conf_dirs:
self.conf_dirs.extend(self._add_conf_dirs)
def _init_directories(self): def _init_directories(self):
self.mkdir(self.conf_path) self.mkdir(self.conf_path)
@ -187,10 +158,11 @@ class Local(object):
self.object_marker_name, self.object_marker_file)) self.object_marker_name, self.object_marker_file))
def _init_cache_dir(self, cache_dir): def _init_cache_dir(self, cache_dir):
home_dir = cdist.home_dir()
if cache_dir: if cache_dir:
self.cache_path = cache_dir self.cache_path = cache_dir
elif self.home_dir: elif home_dir:
self.cache_path = os.path.join(self.home_dir, "cache") self.cache_path = os.path.join(home_dir, "cache")
else: else:
raise cdist.Error( raise cdist.Error(
"No homedir setup and no cache dir location given") "No homedir setup and no cache dir location given")

View file

@ -175,3 +175,27 @@ def log_std_fd(log, command, stdfd, prefix):
stdfd.seek(0, 0) stdfd.seek(0, 0)
log.trace("Command: {}; {}: {}".format( log.trace("Command: {}; {}: {}".format(
command, prefix, stdfd.read().decode())) command, prefix, stdfd.read().decode()))
def dist_conf_dir():
return os.path.abspath(os.path.join(os.path.dirname(cdist.__file__),
"conf"))
def resolve_conf_dirs(configuration, add_conf_dirs):
conf_dirs = []
conf_dirs.append(dist_conf_dir())
home_dir = cdist.home_dir()
if home_dir:
conf_dirs.append(home_dir)
if 'conf_dir' in configuration:
conf_dirs = configuration['conf_dir']
if conf_dirs:
conf_dirs.extend(conf_dirs)
if add_conf_dirs:
conf_dirs.extend(add_conf_dirs)
return conf_dirs

109
cdist/info.py Normal file
View file

@ -0,0 +1,109 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# 2019-2020 Darko Poljak (darko.poljak at gmail.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
import cdist
import cdist.configuration
import cdist.core
import cdist.exec.util as util
import os
import glob
import fnmatch
class Info(object):
def __init__(self, conf_dirs, args):
self.conf_dirs = conf_dirs
self.all = args.all
self.display_global_explorers = args.global_explorers
self.display_types = args.types
if not self.display_global_explorers and not self.display_types:
self.all = True
if args.pattern is None:
self.glob_pattern = '*'
else:
self.glob_pattern = args.pattern
self.display_headers = not args.suppress_headers
@classmethod
def commandline(cls, args):
cfg = cdist.configuration.Configuration(args)
configuration = cfg.get_config(section='GLOBAL')
conf_dirs = util.resolve_conf_dirs(configuration,
args.conf_dir)
c = cls(conf_dirs, args)
c.run()
def _print_line(self):
print('-' * 78)
def _print_double_line(self):
print('=' * 78)
def _display_global_explorers_info(self, conf_path):
if self.display_headers:
print("{} config directory global explorers:".format(conf_path))
self._print_double_line()
global_explorer_path = os.path.join(conf_path, "explorer",
self.glob_pattern)
for explorer in glob.glob(global_explorer_path):
print(explorer)
if self.display_headers:
self._print_line()
def _should_display_type(self, dir_entry):
if not dir_entry.is_dir():
return False
if self.glob_pattern is None:
return True
return fnmatch.fnmatch(dir_entry.name, self.glob_pattern)
def _display_types_info(self, conf_path):
if self.display_headers:
print("{} config directory types:".format(conf_path))
self._print_double_line()
types_path = os.path.join(conf_path, "type")
if not os.path.exists(types_path):
if self.display_headers:
self._print_line()
return
with os.scandir(types_path) as it:
for entry in it:
if self._should_display_type(entry):
print(entry.path)
if self.display_headers:
self._print_line()
def _display_conf_dirs(self):
print("Config directories:")
self._print_double_line()
print("{}".format('\n'.join(self.conf_dirs)))
self._print_line()
def run(self):
if self.display_headers:
self._display_conf_dirs()
for conf_path in self.conf_dirs:
if self.all or self.display_global_explorers:
self._display_global_explorers_info(conf_path)
if self.all or self.display_types:
self._display_types_info(conf_path)

View file

@ -11,7 +11,7 @@ SYNOPSIS
:: ::
cdist [-h] [-V] {banner,config,install,inventory,preos,shell} ... cdist [-h] [-V] {banner,config,install,inventory,preos,shell,info} ...
cdist banner [-h] [-l LOGLEVEL] [-q] [-v] cdist banner [-h] [-l LOGLEVEL] [-q] [-v]
@ -84,6 +84,8 @@ SYNOPSIS
cdist shell [-h] [-l LOGLEVEL] [-q] [-v] [-s SHELL] cdist shell [-h] [-l LOGLEVEL] [-q] [-v] [-s SHELL]
cdist info [-h] [-a] [-c CONF_DIR] [-e] [-H] [-t] [pattern]
DESCRIPTION DESCRIPTION
----------- -----------
@ -604,6 +606,32 @@ usage. Its primary use is for debugging type parameters.
be POSIX compatible shell. be POSIX compatible shell.
INFO
----
Display information for cdist (global explorers, types).
**pattern**
Glob pattern.
**-h, --help**
Show help message and exit.
**-a, --all**
Display all info.
**-c CONF_DIR, --conf-dir CONF_DIR**
Add configuration directory (can be repeated).
**-e, --global-explorers**
Display info for global explorers.
**-H, --suppress-headers**
Suppress displaying header lines.
**-t, --types**
Display info for types.
CONFIGURATION CONFIGURATION
------------- -------------
cdist obtains configuration data from the following sources in the following cdist obtains configuration data from the following sources in the following