]> git.llucax.com Git - software/pymin.git/blobdiff - services/util.py
Change "var" for "attr" where it refer to an object attribute.
[software/pymin.git] / services / util.py
index cbfc091032653cfb784fd206b47477ab6e017eb8..7239867f34e1f8e1dbb12ad1ed7d43aa594b56cc 100644 (file)
@@ -72,6 +72,29 @@ class ExecutionError(Error):
             command = ' '.join(command)
         return "Can't execute command %s: %s" % (command, self.error)
 
+class ParameterError(Error, KeyError):
+    r"""
+    ParameterError(paramname) -> ParameterError instance
+
+    This is the base exception for all DhcpHandler parameters related errors.
+    """
+
+    def __init__(self, paramname):
+        r"Initialize the object. See class documentation for more info."
+        self.message = 'Parameter error: "%s"' % paramname
+
+class ParameterNotFoundError(ParameterError):
+    r"""
+    ParameterNotFoundError(hostname) -> ParameterNotFoundError instance
+
+    This exception is raised when trying to operate on a parameter that doesn't
+    exists.
+    """
+
+    def __init__(self, paramname):
+        r"Initialize the object. See class documentation for more info."
+        self.message = 'Parameter not found: "%s"' % paramname
+
 def call(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
             stderr=subprocess.PIPE, close_fds=True, universal_newlines=True,
             **kw):
@@ -89,120 +112,18 @@ def call(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
     if r is not 0:
         raise ExecutionError(command, ReturnNot0Error(r))
 
-class ServiceHandler(Handler):
-    r"""ServiceHandler([start[, stop[, restart[, reload]]]]) -> ServiceHandler.
-
-    This is a helper class to inherit from to automatically handle services
-    with start, stop, restart, reload actions.
-
-    The actions can be defined by calling the constructor with all the
-    parameters or in a more declarative way as class attributes, like:
-
-    class TestHandler(ServiceHandler):
-        _service_start = ('command', 'start')
-        _service_stop = ('command', 'stop')
-        _service_restart = ('command', 'restart')
-        _service_reload = 'reload-command'
-
-    Commands are executed without using the shell, that's why they are specified
-    as tuples (where the first element is the command and the others are the
-    command arguments). If only a command is needed (without arguments) a single
-    string can be specified.
-
-    All commands must be specified.
-    """
-    # TODO implement it using metaclasses to add the handlers method by demand
-    # (only for specifieds commands).
-
-    def __init__(self, start=None, stop=None, restart=None, reload=None):
-        r"Initialize the object, see the class documentation for details."
-        for (name, action) in dict(start=start, stop=stop, restart=restart,
-                                                    reload=reload).items():
-            if action is not None:
-                setattr(self, '_service_%s' % name, action)
-
-    @handler(u'Start the service.')
-    def start(self):
-        r"start() -> None :: Start the service."
-        call(self._service_start)
-
-    @handler(u'Stop the service.')
-    def stop(self):
-        r"stop() -> None :: Stop the service."
-        call(self._service_stop)
-
-    @handler(u'Restart the service.')
-    def restart(self):
-        r"restart() -> None :: Restart the service."
-        call(self._service_restart)
-
-    @handler(u'Reload the service config (without restarting, if possible).')
-    def reload(self):
-        r"reload() -> None :: Reload the configuration of the service."
-        call(self._service_reload)
-
-class InitdHandler(Handler):
-    r"""InitdHandler([initd_name[, initd_dir]]) -> InitdHandler.
-
-    This is a helper class to inherit from to automatically handle services
-    with start, stop, restart, reload actions using a /etc/init.d like script.
-
-    The name and directory of the script can be defined by calling the
-    constructor or in a more declarative way as class attributes, like:
-
-    class TestHandler(ServiceHandler):
-        _initd_name = 'some-service'
-        _initd_dir = '/usr/local/etc/init.d'
-
-    The default _initd_dir is '/etc/init.d', _initd_name has no default and
-    must be specified in either way.
-
-    Commands are executed without using the shell.
-    """
-    # TODO implement it using metaclasses to add the handlers method by demand
-    # (only for specifieds commands).
-
-    _initd_dir = '/etc/init.d'
-
-    def __init__(self, initd_name=None, initd_dir=None):
-        r"Initialize the object, see the class documentation for details."
-        if initd_name is not None:
-            self._initd_name = initd_name
-        if initd_dir is not None:
-            self._initd_dir = initd_dir
-
-    @handler(u'Start the service.')
-    def start(self):
-        r"start() -> None :: Start the service."
-        call((path.join(self._initd_dir, self._initd_name), 'start'))
-
-    @handler(u'Stop the service.')
-    def stop(self):
-        r"stop() -> None :: Stop the service."
-        call((path.join(self._initd_dir, self._initd_name), 'stop'))
-
-    @handler(u'Restart the service.')
-    def restart(self):
-        r"restart() -> None :: Restart the service."
-        call((path.join(self._initd_dir, self._initd_name), 'restart'))
-
-    @handler(u'Reload the service config (without restarting, if possible).')
-    def reload(self):
-        r"reload() -> None :: Reload the configuration of the service."
-        call((path.join(self._initd_dir, self._initd_name), 'reload'))
-
 class Persistent:
-    r"""Persistent([vars[, dir[, ext]]]) -> Persistent.
+    r"""Persistent([attrs[, dir[, ext]]]) -> Persistent.
 
     This is a helper class to inherit from to automatically handle data
     persistence using pickle.
 
-    The variables attributes to persist (vars), and the pickle directory (dir)
+    The variables attributes to persist (attrs), and the pickle directory (dir)
     and file extension (ext) can be defined by calling the constructor or in a
     more declarative way as class attributes, like:
 
     class TestHandler(Persistent):
-        _persistent_vars = ('some_var', 'other_var')
+        _persistent_attrs = ('some_attr', 'other_attr')
         _persistent_dir = 'persistent-data'
         _persistent_ext = '.pickle'
 
@@ -217,14 +138,14 @@ class Persistent:
     # TODO implement it using metaclasses to add the handlers method by demand
     # (only for specifieds commands).
 
-    _persistent_vars = ()
+    _persistent_attrs = ()
     _persistent_dir = '.'
     _persistent_ext = '.pkl'
 
-    def __init__(self, vars=None, dir=None, ext=None):
+    def __init__(self, attrs=None, dir=None, ext=None):
         r"Initialize the object, see the class documentation for details."
-        if vars is not None:
-            self._persistent_vars = vars
+        if attrs is not None:
+            self._persistent_attrs = attrs
         if dir is not None:
             self._persistent_dir = dir
         if ext is not None:
@@ -232,28 +153,28 @@ class Persistent:
 
     def _dump(self):
         r"_dump() -> None :: Dump all persistent data to pickle files."
-        if isinstance(self._persistent_vars, basestring):
-            self._persistent_vars = (self._persistent_vars,)
-        for varname in self._persistent_vars:
-            self._dump_var(varname)
+        if isinstance(self._persistent_attrs, basestring):
+            self._persistent_attrs = (self._persistent_attrs,)
+        for attrname in self._persistent_attrs:
+            self._dump_attr(attrname)
 
     def _load(self):
         r"_load() -> None :: Load all persistent data from pickle files."
-        if isinstance(self._persistent_vars, basestring):
-            self._persistent_vars = (self._persistent_vars,)
-        for varname in self._persistent_vars:
-            self._load_var(varname)
-
-    def _dump_var(self, varname):
-        r"_dump_var() -> None :: Dump a especific variable to a pickle file."
-        f = file(self._pickle_filename(varname), 'wb')
-        pickle.dump(getattr(self, varname), f, 2)
+        if isinstance(self._persistent_attrs, basestring):
+            self._persistent_attrs = (self._persistent_attrs,)
+        for attrname in self._persistent_attrs:
+            self._load_attr(attrname)
+
+    def _dump_attr(self, attrname):
+        r"_dump_attr() -> None :: Dump a specific variable to a pickle file."
+        f = file(self._pickle_filename(attrname), 'wb')
+        pickle.dump(getattr(self, attrname), f, 2)
         f.close()
 
-    def _load_var(self, varname):
-        r"_load_var() -> object :: Load a especific pickle file."
-        f = file(self._pickle_filename(varname))
-        setattr(self, varname, pickle.load(f))
+    def _load_attr(self, attrname):
+        r"_load_attr() -> object :: Load a specific pickle file."
+        f = file(self._pickle_filename(attrname))
+        setattr(self, attrname, pickle.load(f))
         f.close()
 
     def _pickle_filename(self, name):
@@ -271,14 +192,14 @@ class Restorable(Persistent):
     declarative way as class attributes, like:
 
     class TestHandler(Restorable):
-        _persistent_vars = ('some_var', 'other_var')
+        _persistent_attrs = ('some_attr', 'other_attr')
         _restorable_defaults = dict(
-                some_var = 'some_default',
-                other_var = 'other_default')
+                some_attr = 'some_default',
+                other_attr = 'other_default')
 
-    The defaults is a dictionary, very coupled with the _persistent_vars
+    The defaults is a dictionary, very coupled with the _persistent_attrs
     attribute inherited from Persistent. The defaults keys should be the
-    values from _persistent_vars, and the values the default values.
+    values from _persistent_attrs, and the values the default values.
 
     The _restore() method returns True if the data was restored successfully
     or False if the defaults were loaded (in case you want to take further
@@ -419,8 +340,110 @@ class ConfigWriter:
         for t in self._config_writer_files:
             self._write_single_config(t)
 
+class ServiceHandler(Handler):
+    r"""ServiceHandler([start[, stop[, restart[, reload]]]]) -> ServiceHandler.
+
+    This is a helper class to inherit from to automatically handle services
+    with start, stop, restart, reload actions.
+
+    The actions can be defined by calling the constructor with all the
+    parameters or in a more declarative way as class attributes, like:
+
+    class TestHandler(ServiceHandler):
+        _service_start = ('command', 'start')
+        _service_stop = ('command', 'stop')
+        _service_restart = ('command', 'restart')
+        _service_reload = 'reload-command'
+
+    Commands are executed without using the shell, that's why they are specified
+    as tuples (where the first element is the command and the others are the
+    command arguments). If only a command is needed (without arguments) a single
+    string can be specified.
+
+    All commands must be specified.
+    """
+    # TODO implement it using metaclasses to add the handlers method by demand
+    # (only for specifieds commands).
+
+    def __init__(self, start=None, stop=None, restart=None, reload=None):
+        r"Initialize the object, see the class documentation for details."
+        for (name, action) in dict(start=start, stop=stop, restart=restart,
+                                                    reload=reload).items():
+            if action is not None:
+                setattr(self, '_service_%s' % name, action)
+
+    @handler(u'Start the service.')
+    def start(self):
+        r"start() -> None :: Start the service."
+        call(self._service_start)
+
+    @handler(u'Stop the service.')
+    def stop(self):
+        r"stop() -> None :: Stop the service."
+        call(self._service_stop)
+
+    @handler(u'Restart the service.')
+    def restart(self):
+        r"restart() -> None :: Restart the service."
+        call(self._service_restart)
+
+    @handler(u'Reload the service config (without restarting, if possible).')
+    def reload(self):
+        r"reload() -> None :: Reload the configuration of the service."
+        call(self._service_reload)
+
+class InitdHandler(Handler):
+    r"""InitdHandler([initd_name[, initd_dir]]) -> InitdHandler.
+
+    This is a helper class to inherit from to automatically handle services
+    with start, stop, restart, reload actions using a /etc/init.d like script.
+
+    The name and directory of the script can be defined by calling the
+    constructor or in a more declarative way as class attributes, like:
+
+    class TestHandler(ServiceHandler):
+        _initd_name = 'some-service'
+        _initd_dir = '/usr/local/etc/init.d'
+
+    The default _initd_dir is '/etc/init.d', _initd_name has no default and
+    must be specified in either way.
+
+    Commands are executed without using the shell.
+    """
+    # TODO implement it using metaclasses to add the handlers method by demand
+    # (only for specifieds commands).
+
+    _initd_dir = '/etc/init.d'
+
+    def __init__(self, initd_name=None, initd_dir=None):
+        r"Initialize the object, see the class documentation for details."
+        if initd_name is not None:
+            self._initd_name = initd_name
+        if initd_dir is not None:
+            self._initd_dir = initd_dir
+
+    @handler(u'Start the service.')
+    def start(self):
+        r"start() -> None :: Start the service."
+        call((path.join(self._initd_dir, self._initd_name), 'start'))
+
+    @handler(u'Stop the service.')
+    def stop(self):
+        r"stop() -> None :: Stop the service."
+        call((path.join(self._initd_dir, self._initd_name), 'stop'))
+
+    @handler(u'Restart the service.')
+    def restart(self):
+        r"restart() -> None :: Restart the service."
+        call((path.join(self._initd_dir, self._initd_name), 'restart'))
+
+    @handler(u'Reload the service config (without restarting, if possible).')
+    def reload(self):
+        r"reload() -> None :: Reload the configuration of the service."
+        call((path.join(self._initd_dir, self._initd_name), 'reload'))
+
 class TransactionalHandler(Handler):
-    r"""TransactionalHandler([initd_name[, initd_dir]]) -> TransactionalHandler.
+    r"""Handle command transactions providing a commit and rollback commands.
 
     This is a helper class to inherit from to automatically handle
     transactional handlers, which have commit and rollback commands.
@@ -451,6 +474,54 @@ class TransactionalHandler(Handler):
         if hasattr(self, '_load'):
             self._load()
 
+class ParametersHandler(Handler):
+    r"""ParametersHandler([attr]) -> ParametersHandler.
+
+    This is a helper class to inherit from to automatically handle
+    service parameters, providing set, get, list and show commands.
+
+    The attribute that holds the parameters can be defined by calling the
+    constructor or in a more declarative way as class attributes, like:
+
+    class TestHandler(ServiceHandler):
+        _parameters_attr = 'some_attr'
+
+    The default is 'params' and it should be a dictionary.
+    """
+    # TODO implement it using metaclasses to add the handlers method by demand
+    # (only for specifieds commands).
+
+    _parameters_attr = 'params'
+
+    def __init__(self, attr=None):
+        r"Initialize the object, see the class documentation for details."
+        if attr is not None:
+            self._parameters_attr = attr
+
+    @handler(u'Set a service parameter.')
+    def set(self, param, value):
+        r"set(param, value) -> None :: Set a service parameter."
+        if not param in self.params:
+            raise ParameterNotFoundError(param)
+        self.params[param] = value
+
+    @handler(u'Get a service parameter.')
+    def get(self, param):
+        r"get(param) -> None :: Get a service parameter."
+        if not param in self.params:
+            raise ParameterNotFoundError(param)
+        return self.params[param]
+
+    @handler(u'List all available service parameters.')
+    def list(self):
+        r"list() -> tuple :: List all the parameter names."
+        return self.params.keys()
+
+    @handler(u'Get all service parameters, with their values.')
+    def show(self):
+        r"show() -> (key, value) tuples :: List all the parameters."
+        return self.params.items()
+
 
 if __name__ == '__main__':
 
@@ -498,7 +569,7 @@ if __name__ == '__main__':
     # Persistent test
     print 'PTestHandler'
     class PTestHandler(Persistent):
-        _persistent_vars = 'vars'
+        _persistent_attrs = 'vars'
         def __init__(self):
             self.vars = dict(a=1, b=2)
     h = PTestHandler()
@@ -520,7 +591,7 @@ if __name__ == '__main__':
     # Restorable test
     print 'RTestHandler'
     class RTestHandler(Restorable):
-        _persistent_vars = 'vars'
+        _persistent_attrs = 'vars'
         _restorable_defaults = dict(vars=dict(a=1, b=2))
         def __init__(self):
             self._restore()