Add -l/--log-level option. Honor __cdist_loglevel env var. (#572)

Add -l/--log-level option, __cdist_loglevel -> __cdist_log_level; honor __cdist_log_level env var
This commit is contained in:
Darko Poljak 2017-09-09 21:17:29 +02:00 committed by GitHub
commit 3454da076f
23 changed files with 152 additions and 69 deletions

View file

@ -3,6 +3,7 @@ import cdist
import multiprocessing
import logging
import collections
import functools
import cdist.configuration
@ -72,15 +73,15 @@ def check_beta(args_dict):
raise cdist.CdistBetaRequired(cmd, arg)
def check_positive_int(value):
def check_lower_bounded_int(value, lower_bound, name):
try:
val = int(value)
except ValueError:
raise argparse.ArgumentTypeError(
"{} is invalid int value".format(value))
if val <= 0:
if val < lower_bound:
raise argparse.ArgumentTypeError(
"{} is invalid positive int value".format(val))
"{} is invalid {} value".format(val, name))
return val
@ -94,6 +95,17 @@ def get_parsers():
parser = {}
# Options _all_ parsers have in common
parser['loglevel'] = argparse.ArgumentParser(add_help=False)
parser['loglevel'].add_argument(
'-l', '--log-level', metavar='LOGLEVEL',
type=functools.partial(check_lower_bounded_int, lower_bound=-1,
name="log level"),
help=('Set the specified verbosity level. '
'The levels, in order from the lowest to the highest, are: '
'ERROR (-1), WARNING (0), INFO (1), VERBOSE (2), DEBUG (3) '
'TRACE (4 or higher). If used along with -v then -v '
'increases last set value and -l overwrites last set '
'value.'),
action='store', dest='verbose', required=False)
parser['loglevel'].add_argument(
'-q', '--quiet',
help='Quiet mode: disables logging, including WARNING and ERROR.',
@ -105,7 +117,9 @@ def get_parsers():
'is 0 which includes ERROR and WARNING levels. '
'The levels, in order from the lowest to the highest, are: '
'ERROR (-1), WARNING (0), INFO (1), VERBOSE (2), DEBUG (3) '
'TRACE (4 or higher).'),
'TRACE (4 or higher). If used along with -l then -l '
'overwrites last set value and -v increases last set '
'value.'),
action='count', default=None)
parser['beta'] = argparse.ArgumentParser(add_help=False)
@ -164,7 +178,8 @@ def get_parsers():
dest='manifest', required=False)
parser['config_main'].add_argument(
'-j', '--jobs', nargs='?',
type=check_positive_int,
type=functools.partial(check_lower_bounded_int, lower_bound=1,
name="positive int"),
help=('Operate in parallel in specified maximum number of jobs. '
'Global explorers, object prepare and object run are '
'supported. Without argument CPU count is used by default. '
@ -229,7 +244,8 @@ def get_parsers():
dest='hostfile', required=False)
parser['config_args'].add_argument(
'-p', '--parallel', nargs='?', metavar='HOST_MAX',
type=check_positive_int,
type=functools.partial(check_lower_bounded_int, lower_bound=1,
name="positive int"),
help=('Operate on multiple hosts in parallel for specified maximum '
'hosts at a time. Without argument CPU count is used by '
'default.'),

View file

@ -22,27 +22,10 @@ chroot="$(cat "$__object/parameter/chroot")"
remote_exec="$__type/files/remote/exec"
remote_copy="$__type/files/remote/copy"
cdist_args=""
case "$__cdist_loglevel" in
INFO)
cdist_args="-v"
;;
VERBOSE)
cdist_args="-vv"
;;
DEBUG)
cdist_args="-vvv"
;;
TRACE)
cdist_args="-vvvv"
;;
esac
cat << DONE
export __default_remote_exec="$__remote_exec"
export __default_remote_copy="$__remote_copy"
cdist config \
$cdist_args \
--remote-exec="$remote_exec $chroot" \
--remote-copy="$remote_copy $chroot" \
$__target_host

View file

@ -22,7 +22,7 @@ uri="$(cat "$__object/parameter/uri" 2>/dev/null \
|| echo "$__object_id")"
target="$(cat "$__object/parameter/target")"
case "$__cdist_loglevel" in
case "$__cdist_log_level" in
DEBUG|TRACE)
curl="curl"
tar="tar -xvzp"

View file

@ -278,6 +278,7 @@ class Configuration(metaclass=Singleton):
'CDIST_REMOTE_COPY': 'remote_copy',
'CDIST_INVENTORY_DIR': 'inventory_dir',
'CDIST_CACHE_PATH_PATTERN': 'cache_path_pattern',
'__cdist_log_level': 'verbosity',
}
ENV_VAR_BOOLEAN_OPTIONS = ('CDIST_BETA', )

View file

@ -28,3 +28,4 @@ from cdist.core.explorer import Explorer
from cdist.core.manifest import Manifest
from cdist.core.code import Code
from cdist.core.util import listdir
from cdist.core.util import log_level_env_var_val

View file

@ -22,6 +22,7 @@
#
import os
from . import util
'''
@ -107,6 +108,7 @@ class Code(object):
'__global': self.local.base_path,
'__files': self.local.files_path,
'__target_host_tags': self.local.target_host_tags,
'__cdist_log_level': util.log_level_env_var_val(local.log),
}
def _run_gencode(self, cdist_object, which):

View file

@ -25,6 +25,7 @@ import os
import glob
import multiprocessing
from cdist.mputil import mp_pool_run
from . import util
'''
common:
@ -78,6 +79,7 @@ class Explorer(object):
'__target_fqdn': self.target_host[2],
'__explorer': self.remote.global_explorer_path,
'__target_host_tags': self.local.target_host_tags,
'__cdist_log_level': util.log_level_env_var_val(self.log),
}
self._type_explorers_transferred = []
self.jobs = jobs

View file

@ -24,6 +24,7 @@ import logging
import os
import cdist
from . import util
'''
common:
@ -111,12 +112,9 @@ class Manifest(object):
'__target_fqdn': self.target_host[2],
'__files': self.local.files_path,
'__target_host_tags': self.local.target_host_tags,
'__cdist_log_level': util.log_level_env_var_val(self.log),
}
self.env.update(
{'__cdist_loglevel': logging.getLevelName(
self.log.getEffectiveLevel())})
def _open_logger(self):
self.log = logging.getLogger(self.target_host[0])

View file

@ -20,6 +20,7 @@
#
import os
import logging
def listdir(path='.', include_dot=False):
@ -34,3 +35,7 @@ def listdir(path='.', include_dot=False):
def _ishidden(path):
return path[0] in ('.', b'.'[0])
def log_level_env_var_val(log):
return logging.getLevelName(log.getEffectiveLevel())

View file

@ -109,9 +109,9 @@ class Emulator(object):
def __init_log(self):
"""Setup logging facility"""
if '__cdist_loglevel' in self.env:
if '__cdist_log_level' in self.env:
try:
loglevel = self.env['__cdist_loglevel']
loglevel = self.env['__cdist_log_level']
# For a text level it returns its numerical value.
level = logging.getLevelName(loglevel)
except ValueError:
@ -121,7 +121,7 @@ class Emulator(object):
try:
logging.root.setLevel(level)
except (ValueError, TypeError):
# if invalid __cdist_loglevel value
# if invalid __cdist_log_level value
logging.root.setLevel(logging.WARNING)
self.log = logging.getLogger(self.target_host[0])

View file

@ -23,6 +23,7 @@
import getpass
import os
import shutil
import logging
import cdist
from cdist import core
@ -100,6 +101,7 @@ class CodeTestCase(test.CdistTestCase):
self.assertEqual(output_dict['__files'], self.local.files_path)
self.assertEqual(output_dict['__target_host_tags'],
self.local.target_host_tags)
self.assertEqual(output_dict['__cdist_log_level'], 'WARNING')
def test_run_gencode_remote_environment(self):
output_string = self.code.run_gencode_remote(self.cdist_object)
@ -125,6 +127,7 @@ class CodeTestCase(test.CdistTestCase):
self.assertEqual(output_dict['__files'], self.local.files_path)
self.assertEqual(output_dict['__target_host_tags'],
self.local.target_host_tags)
self.assertEqual(output_dict['__cdist_log_level'], 'WARNING')
def test_transfer_code_remote(self):
self.cdist_object.code_remote = self.code.run_gencode_remote(

View file

@ -10,3 +10,4 @@ echo "echo __object_id: $__object_id"
echo "echo __object_name: $__object_name"
echo "echo __files: $__files"
echo "echo __target_host_tags: $__target_host_tags"
echo "echo __cdist_log_level: $__cdist_log_level"

View file

@ -64,8 +64,8 @@ class EmulatorTestCase(test.CdistTestCase):
self.manifest = core.Manifest(self.target_host, self.local)
self.env = self.manifest.env_initial_manifest(self.script)
self.env['__cdist_object_marker'] = self.local.object_marker_name
if '__cdist_loglevel' in self.env:
del self.env['__cdist_loglevel']
if '__cdist_log_level' in self.env:
del self.env['__cdist_log_level']
def tearDown(self):
shutil.rmtree(self.temp_dir)
@ -124,11 +124,11 @@ class EmulatorTestCase(test.CdistTestCase):
emu = emulator.Emulator(argv, env=self.env)
emu_loglevel = emu.log.getEffectiveLevel()
self.assertEqual(emu_loglevel, logging.WARNING)
self.env['__cdist_loglevel'] = logging.getLevelName(logging.DEBUG)
self.env['__cdist_log_level'] = logging.getLevelName(logging.DEBUG)
emu = emulator.Emulator(argv, env=self.env)
emu_loglevel = emu.log.getEffectiveLevel()
self.assertEqual(emu_loglevel, logging.DEBUG)
del self.env['__cdist_loglevel']
del self.env['__cdist_log_level']
def test_invalid_loglevel_value(self):
argv = ['__file', '/tmp/foobar']
@ -137,11 +137,11 @@ class EmulatorTestCase(test.CdistTestCase):
emu_loglevel = emu.log.getEffectiveLevel()
self.assertEqual(emu_loglevel, logging.WARNING)
# lowercase is invalid
self.env['__cdist_loglevel'] = 'debug'
self.env['__cdist_log_level'] = 'debug'
emu = emulator.Emulator(argv, env=self.env)
emu_loglevel = emu.log.getEffectiveLevel()
self.assertEqual(emu_loglevel, logging.WARNING)
del self.env['__cdist_loglevel']
del self.env['__cdist_log_level']
def test_requirement_via_order_dependency(self):
self.env['CDIST_ORDER_DEPENDENCY'] = 'on'

View file

@ -210,6 +210,31 @@ class ExplorerClassTestCase(test.CdistTestCase):
self.assertEqual(names, output)
shutil.rmtree(out_path)
def test_explorer_environment(self):
cdist_type = core.CdistType(self.local.type_path, '__dump_env')
cdist_object = core.CdistObject(cdist_type, self.local.object_path,
self.local.object_marker_name,
'whatever')
self.explorer.transfer_type_explorers(cdist_type)
output = self.explorer.run_type_explorer('dump', cdist_object)
output_dict = {}
for line in output.split('\n'):
if line:
key, value = line.split(': ')
output_dict[key] = value
self.assertEqual(output_dict['__target_host'],
self.local.target_host[0])
self.assertEqual(output_dict['__target_hostname'],
self.local.target_host[1])
self.assertEqual(output_dict['__target_fqdn'],
self.local.target_host[2])
self.assertEqual(output_dict['__explorer'],
self.remote.global_explorer_path)
self.assertEqual(output_dict['__target_host_tags'],
self.local.target_host_tags)
self.assertEqual(output_dict['__cdist_log_level'], 'WARNING')
if __name__ == '__main__':
import unittest

View file

@ -0,0 +1,8 @@
#!/bin/sh
echo "__target_host: $__target_host"
echo "__target_hostname: $__target_hostname"
echo "__target_fqdn: $__target_fqdn"
echo "__explorer: $__explorer"
echo "__target_host_tags: $__target_host_tags"
echo "__cdist_log_level: $__cdist_log_level"

View file

@ -73,7 +73,10 @@ class ManifestTestCase(test.CdistTestCase):
handle, output_file = self.mkstemp(dir=self.temp_dir)
os.close(handle)
os.environ['__cdist_test_out'] = output_file
self.manifest.run_initial_manifest(initial_manifest)
old_loglevel = logging.root.getEffectiveLevel()
self.log.setLevel(logging.VERBOSE)
manifest = cdist.core.manifest.Manifest(self.target_host, self.local)
manifest.run_initial_manifest(initial_manifest)
with open(output_file, 'r') as fd:
output_string = fd.read()
@ -96,6 +99,8 @@ class ManifestTestCase(test.CdistTestCase):
self.assertEqual(output_dict['__files'], self.local.files_path)
self.assertEqual(output_dict['__target_host_tags'],
self.local.target_host_tags)
self.assertEqual(output_dict['__cdist_log_level'], 'VERBOSE')
self.log.setLevel(old_loglevel)
def test_type_manifest_environment(self):
cdist_type = core.CdistType(self.local.type_path, '__dump_environment')
@ -105,7 +110,10 @@ class ManifestTestCase(test.CdistTestCase):
handle, output_file = self.mkstemp(dir=self.temp_dir)
os.close(handle)
os.environ['__cdist_test_out'] = output_file
self.manifest.run_type_manifest(cdist_object)
old_loglevel = self.log.getEffectiveLevel()
self.log.setLevel(logging.VERBOSE)
manifest = cdist.core.manifest.Manifest(self.target_host, self.local)
manifest.run_type_manifest(cdist_object)
with open(output_file, 'r') as fd:
output_string = fd.read()
@ -131,13 +139,15 @@ class ManifestTestCase(test.CdistTestCase):
self.assertEqual(output_dict['__files'], self.local.files_path)
self.assertEqual(output_dict['__target_host_tags'],
self.local.target_host_tags)
self.assertEqual(output_dict['__cdist_log_level'], 'VERBOSE')
self.log.setLevel(old_loglevel)
def test_debug_env_setup(self):
def test_loglevel_env_setup(self):
current_level = self.log.getEffectiveLevel()
self.log.setLevel(logging.DEBUG)
manifest = cdist.core.manifest.Manifest(self.target_host, self.local)
self.assertTrue("__cdist_loglevel" in manifest.env)
self.assertEqual(manifest.env["__cdist_loglevel"], 'DEBUG')
self.assertTrue("__cdist_log_level" in manifest.env)
self.assertEqual(manifest.env["__cdist_log_level"], 'DEBUG')
self.log.setLevel(current_level)

View file

@ -10,4 +10,5 @@ __cdist_type_base_path: $__cdist_type_base_path
__manifest: $__manifest
__files: $__files
__target_host_tags: $__target_host_tags
__cdist_log_level: $__cdist_log_level
DONE

View file

@ -14,4 +14,5 @@ __object_id: $__object_id
__object_name: $__object_name
__files: $__files
__target_host_tags: $__target_host_tags
__cdist_log_level: $__cdist_log_level
DONE