X-Git-Url: https://git.llucax.com/software/pymin.git/blobdiff_plain/296d853cc95fd5bef262248cfe21b507abd26a4f..b1c83f0151bd8a0de3d56778c64e2de368e64e58:/pymin/services/util.py diff --git a/pymin/services/util.py b/pymin/services/util.py index 81b2767..c0371a1 100644 --- a/pymin/services/util.py +++ b/pymin/services/util.py @@ -14,8 +14,10 @@ from pymin.dispatcher import Handler, handler, HandlerError #DEBUG = False DEBUG = True -__ALL__ = ('ServiceHandler', 'InitdHandler', 'Persistent', 'ConfigWriter', - 'Error', 'ReturnNot0Error', 'ExecutionError', 'call') +__ALL__ = ('ServiceHandler', 'InitdHandler', 'SubHandler', 'DictSubHandler', + 'ListSubHandler', 'Persistent', 'ConfigWriter', 'Error', + 'ReturnNot0Error', 'ExecutionError', 'ItemError', + 'ItemAlreadyExistsError', 'ItemNotFoundError', 'call') class Error(HandlerError): r""" @@ -26,13 +28,7 @@ class Error(HandlerError): message - A descriptive error message. """ - - def __init__(self, message): - r"Initialize the object. See class documentation for more info." - self.message = message - - def __str__(self): - return self.message + pass class ReturnNot0Error(Error): r""" @@ -47,7 +43,7 @@ class ReturnNot0Error(Error): r"Initialize the object. See class documentation for more info." self.return_value = return_value - def __str__(self): + def __unicode__(self): return 'The command returned %d' % self.return_value class ExecutionError(Error): @@ -66,7 +62,7 @@ class ExecutionError(Error): self.command = command self.error = error - def __str__(self): + def __unicode__(self): command = self.command if not isinstance(self.command, basestring): command = ' '.join(command) @@ -85,7 +81,7 @@ class ParameterError(Error, KeyError): class ParameterNotFoundError(ParameterError): r""" - ParameterNotFoundError(hostname) -> ParameterNotFoundError instance + ParameterNotFoundError(paramname) -> ParameterNotFoundError instance This exception is raised when trying to operate on a parameter that doesn't exists. @@ -95,6 +91,40 @@ class ParameterNotFoundError(ParameterError): r"Initialize the object. See class documentation for more info." self.message = 'Parameter not found: "%s"' % paramname +class ItemError(Error, KeyError): + r""" + ItemError(key) -> ItemError instance. + + This is the base exception for all item related errors. + """ + + def __init__(self, key): + r"Initialize the object. See class documentation for more info." + self.message = u'Item error: "%s"' % key + +class ItemAlreadyExistsError(ItemError): + r""" + ItemAlreadyExistsError(key) -> ItemAlreadyExistsError instance. + + This exception is raised when trying to add an item that already exists. + """ + + def __init__(self, key): + r"Initialize the object. See class documentation for more info." + self.message = u'Item already exists: "%s"' % key + +class ItemNotFoundError(ItemError): + r""" + ItemNotFoundError(key) -> ItemNotFoundError instance + + This exception is raised when trying to operate on an item that doesn't + exists. + """ + + def __init__(self, key): + r"Initialize the object. See class documentation for more info." + self.message = u'Item not found: "%s"' % key + def call(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, universal_newlines=True, @@ -221,13 +251,22 @@ class Restorable(Persistent): r"_restore() -> bool :: Restore persistent data or create a default." try: self._load() + # TODO tener en cuenta servicios que hay que levantar y los que no + if hasattr(self, 'commit'): # TODO deberia ser reload y/o algo para comandos + self.commit() return True except IOError: for (k, v) in self._restorable_defaults.items(): setattr(self, k, v) + # TODO tener en cuenta servicios que hay que levantar y los que no + if hasattr(self, 'commit'): + self.commit() + return False self._dump() if hasattr(self, '_write_config'): self._write_config() + if hasattr(self, 'reload'): + self.reload() return False class ConfigWriter: @@ -467,7 +506,7 @@ class TransactionalHandler(Handler): self._dump() if hasattr(self, '_write_config'): self._write_config() - if hasattr(self, '_reload'): + if hasattr(self, 'reload'): self.reload() @handler(u'Discard all the uncommited changes.') @@ -524,6 +563,91 @@ class ParametersHandler(Handler): r"show() -> (key, value) tuples :: List all the parameters." return self.params.items() +class SubHandler(Handler): + r"""SubHandler(parent) -> SubHandler instance :: Handles subcommands. + + This is a helper class to build sub handlers that needs to reference the + parent handler. + + parent - Parent Handler object. + """ + + def __init__(self, parent): + r"Initialize the object, see the class documentation for details." + self.parent = parent + +class DictSubHandler(SubHandler): + r"""DictSubHandler(parent) -> DictSubHandler instance. + + This is a helper class to inherit from to automatically handle subcommands + that operates over a dict parent attribute. + + The dict attribute to handle and the class of objects that it contains can + be defined by calling the constructor or in a more declarative way as + class attributes, like: + + class TestHandler(DictSubHandler): + _dict_subhandler_attr = 'some_dict' + _dict_subhandler_class = SomeClass + + This way, the parent's some_dict attribute (self.parent.some_dict) will be + managed automatically, providing the commands: add, update, delete, get, + list and show. + """ + + def __init__(self, parent, attr=None, key=None, cls=None): + r"Initialize the object, see the class documentation for details." + self.parent = parent + if attr is not None: + self._dict_subhandler_attr = attr + if key is not None: + self._dict_subhandler_key = key + if cls is not None: + self._dict_subhandler_class = cls + + def _dict(self): + return getattr(self.parent, self._dict_subhandler_attr) + + @handler(u'Add a new item') + def add(self, key, *args, **kwargs): + r"add(key, ...) -> None :: Add an item to the dict." + item = self._dict_subhandler_class(key, *args, **kwargs) + if key in self._dict(): + raise ItemAlreadyExistsError(key) + self._dict()[key] = item + + @handler(u'Update an item') + def update(self, key, *args, **kwargs): + r"update(key, ...) -> None :: Update an item of the dict." + if not key in self._dict(): + raise ItemNotFoundError(key) + self._dict()[key].update(*args, **kwargs) + + @handler(u'Delete an item') + def delete(self, key): + r"delete(key) -> None :: Delete an item of the dict." + if not key in self._dict(): + raise ItemNotFoundError(key) + del self._dict()[key] + + @handler(u'Get information about an item') + def get(self, key): + r"get(key) -> Host :: List all the information of an item." + if not key in self._dict(): + raise ItemNotFoundError(key) + return self._dict()[key] + + @handler(u'List all the items by key') + def list(self): + r"list() -> tuple :: List all the item keys." + return self._dict().keys() + + @handler(u'Get information about all items') + def show(self): + r"show() -> list of Hosts :: List all the complete items information." + return self._dict().values() + + if __name__ == '__main__':