rewrite emulator to class based approach for better logging

Signed-off-by: Nico Schottelius <nico@kr.ethz.ch>
This commit is contained in:
Nico Schottelius 2011-10-15 02:31:40 +02:00
parent 00a1f1eeb9
commit e002710c4c
2 changed files with 116 additions and 82 deletions

View file

@ -145,6 +145,10 @@ def configinstall(args, mode):
log.info("Total processing time for %s host(s): %s", len(args.host), log.info("Total processing time for %s host(s): %s", len(args.host),
(time_end - time_start)) (time_end - time_start))
def emulator():
"""Prepare and run emulator"""
emulator = cdist.emulator.Emulator(sys.argv)
emulator.run()
if __name__ == "__main__": if __name__ == "__main__":
try: try:
@ -152,7 +156,8 @@ if __name__ == "__main__":
if re.match(TYPE_PREFIX, os.path.basename(sys.argv[0])): if re.match(TYPE_PREFIX, os.path.basename(sys.argv[0])):
import cdist.emulator import cdist.emulator
cdist.emulator.run(sys.argv)
emulator()
else: else:
import cdist.banner import cdist.banner
import cdist.config import cdist.config

View file

@ -26,8 +26,6 @@ import os
import cdist import cdist
from cdist import core from cdist import core
log = logging.getLogger(__name__)
class IllegalRequirementError(cdist.Error): class IllegalRequirementError(cdist.Error):
def __init__(self, requirement, message=None): def __init__(self, requirement, message=None):
@ -37,100 +35,131 @@ class IllegalRequirementError(cdist.Error):
def __str__(self): def __str__(self):
return '%s: %s' % (self.message, self.requirement) return '%s: %s' % (self.message, self.requirement)
class Emulator(object):
def __init__(self, argv):
self.argv = argv
self.object_id = False
def run(argv): self.global_path = os.environ['__global']
"""Emulate type commands (i.e. __file and co)""" self.object_source = os.environ['__cdist_manifest']
global_path = os.environ['__global'] self.target_host = os.environ['__target_host']
object_source = os.environ['__cdist_manifest'] self.type_base_path = os.environ['__cdist_type_base_path']
target_host = os.environ['__target_host']
type_name = os.path.basename(argv[0]) self.object_base_path = os.path.join(self.global_path, "object")
# Logsetup - FIXME: add object_fq as soon as setup! self.type_name = os.path.basename(argv[0])
#id = target_host + ": " + cdist_type + '/' + object_id self.cdist_type = core.Type(self.type_base_path, self.type_name)
id = target_host + ": "
# logformat = '%(levelname)s: ' + target_host + ": " + cdist_type + '/' + object_id + ': %(message)s'
logformat = '%(levelname)s: ' + id + ': %(message)s'
logging.basicConfig(format=logformat)
if '__debug' in os.environ: self.__init_log()
logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.INFO)
object_base_path = os.path.join(global_path, "object") def filter(self, record):
type_base_path = os.environ['__cdist_type_base_path'] """Add hostname and object to logs via logging Filter"""
cdist_type = core.Type(type_base_path, type_name)
if '__install' in os.environ: prefix = self.target_host + ": "
if not cdist_type.is_install:
log.debug("Running in install mode, ignoring non install type")
return True
parser = argparse.ArgumentParser(add_help=False) if self.object_id:
prefix = prefix + self.type_name + "/" + self.object_id
for parameter in cdist_type.optional_parameters: record.msg = prefix + ": " + record.msg
argument = "--" + parameter
parser.add_argument(argument, action='store', required=False)
for parameter in cdist_type.required_parameters:
argument = "--" + parameter
parser.add_argument(argument, action='store', required=True)
# If not singleton support one positional parameter return True
if not cdist_type.is_singleton:
parser.add_argument("object_id", nargs=1)
# And finally verify parameter def run(self):
args = parser.parse_args(argv[1:]) """Emulate type commands (i.e. __file and co)"""
# Setup object_id if '__install' in os.environ:
if cdist_type.is_singleton: if not self.cdist_type.is_install:
object_id = "singleton" self.log.debug("Running in install mode, ignoring non install type")
else: return True
object_id = args.object_id[0]
del args.object_id
# strip leading slash from object_id self.commandline()
object_id = object_id.lstrip('/') self.setup_object()
self.record_requirements()
self.log.debug("Finished %s %s" % (self.cdist_object.path, self.parameters))
# Instantiate the cdist object whe are defining def __init_log(self):
cdist_object = core.Object(cdist_type, object_base_path, object_id) """Setup logging facility"""
logformat = '%(levelname)s: %(message)s'
logging.basicConfig(format=logformat)
# FIXME: verify object id if '__debug' in os.environ:
log.debug('#### emulator args: %s' % args) logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.INFO)
# Create object with given parameters self.log = logging.getLogger(__name__)
parameters = {} self.log.addFilter(self)
for key,value in vars(args).items():
if value is not None: def commandline(self):
parameters[key] = value """Parse command line"""
if cdist_object.exists: parser = argparse.ArgumentParser(add_help=False)
if cdist_object.parameters != parameters:
raise cdist.Error("Object %s already exists with conflicting parameters:\n%s: %s\n%s: %s" for parameter in self.cdist_type.optional_parameters:
% (cdist_object, " ".join(cdist_object.source), cdist_object.parameters, object_source, parameters) argument = "--" + parameter
parser.add_argument(argument, action='store', required=False)
for parameter in self.cdist_type.required_parameters:
argument = "--" + parameter
parser.add_argument(argument, action='store', required=True)
# If not singleton support one positional parameter
if not self.cdist_type.is_singleton:
parser.add_argument("object_id", nargs=1)
# And finally parse/verify parameter
self.args = parser.parse_args(self.argv[1:])
self.log.debug('Emulator args: %s' % self.args)
def setup_object(self):
# FIXME: verify object id
# Setup object_id
if self.cdist_type.is_singleton:
self.object_id = "singleton"
else:
self.object_id = self.args.object_id[0]
del self.args.object_id
# strip leading slash from object_id
self.object_id = self.object_id.lstrip('/')
# Instantiate the cdist object we are defining
self.cdist_object = core.Object(self.cdist_type, self.object_base_path, self.object_id)
# Create object with given parameters
self.parameters = {}
for key,value in vars(self.args).items():
if value is not None:
self.parameters[key] = value
if self.cdist_object.exists:
if cdist_object.parameters != self.parameters:
raise cdist.Error("Object %s already exists with conflicting parameters:\n%s: %s\n%s: %s"
% (self.cdist_object, " ".join(self.cdist_object.source), self.cdist_object.parameters, self.object_source, self.parameters)
) )
else: else:
cdist_object.create() self.cdist_object.create()
cdist_object.parameters = parameters self.cdist_object.parameters = self.parameters
# Record requirements def record_requirements(self):
if "require" in os.environ: """record requirements"""
requirements = os.environ['require']
for requirement in requirements.split(" "):
requirement_parts = requirement.split(os.sep, 1)
requirement_parts.reverse()
requirement_type_name = requirement_parts.pop()
try:
requirement_object_id = requirement_parts.pop()
except IndexError:
# no object id, must be singleton
requirement_object_id = 'singleton'
if requirement_object_id.startswith('/'):
raise IllegalRequirementError(requirement, 'requirements object_id may not start with /')
log.debug("Recording requirement: %s -> %s" % (cdist_object.path, requirement))
cdist_object.requirements.append(requirement)
# Record / Append source if "require" in os.environ:
cdist_object.source.append(object_source) requirements = os.environ['require']
for requirement in requirements.split(" "):
requirement_parts = requirement.split(os.sep, 1)
requirement_parts.reverse()
requirement_type_name = requirement_parts.pop()
try:
requirement_object_id = requirement_parts.pop()
except IndexError:
# no object id, must be singleton
requirement_object_id = 'singleton'
if requirement_object_id.startswith('/'):
raise IllegalRequirementError(requirement, 'requirements object_id may not start with /')
self.log.debug("Recording requirement: %s -> %s" % (self.cdist_object.path, requirement))
self.cdist_object.requirements.append(requirement)
log.debug("Finished %s %s" % (cdist_object.path, parameters)) # Record / Append source
self.cdist_object.source.append(self.object_source)