""" Action superclass with common functionality """
-import sys
+import sys, ConfigParser
import logging as log
from backupninja import config
+def fail_on_exception(f):
+ """
+ This is a decorator meant for methods on the Action class. It
+ catches any exceptions thrown, sets the failed attribute to True and
+ rethrows the exception.
+ """
+ def inner(self, *args, **kwargs):
+ try:
+ f(self, *args, **kwargs)
+ except:
+ self.failed = True
+ raise
+ return inner
+
class Action(object):
"""
Subclasses of Action represent handlers for various action types.
which is a combination of a action type and a specific action
configuration).
"""
- def __init__(self):
+ def __init__(self, logger):
# Subclasses should overwrite this with their default config
# See backupninja.config.load_config for the structure of this
# value.
self.default_config = {}
+ # Assume we'll run succesfully. If anything fails in the
+ # meanwhile, set this to True.
+ self.failed = False
+ # A logger object for this action. In the future, this might
+ # become a specific logger, that includes the action name and
+ # type.
+ self.log = logger
def run(self, **kwargs):
"""
"""
self.conf = config.load_config(filename, self.default_config)
-
+ def get_config_optional(self, section, option):
+ """
+ Returns the value of the given option. If the option was not set
+ (and no default was set in self.default_config), return None.
+
+ This is a convenience wrapper for ConfigParser.get(), since that
+ throws an exception on unset options.
+ """
+ try:
+ return self.conf.get(section, option)
+ except ConfigParser.NoOptionError:
+ return None
+
+ def get_config_mandatory(self, section, option):
+ """
+ Returns the value of the given option. If the option was not set
+ (and no default was set in self.default_config), raises a
+ backupninja.config.ConfigError.
+
+ This is a convenience wrapper for ConfigParser.get(), since that
+ has a very generic exception message on unknown options.
+ """
+ try:
+ return self.conf.get(section, option)
+ except ConfigParser.NoOptionError:
+ raise config.ConfigError("Option '%s' in section '%s' is mandatory, please configure it" % (option, section))
-def create_action(ty):
+def create_action(ty, **kwargs):
"""
Create a new (subclass of) Action object for an action with the
- given type.
+ given type. Any extra keyword arguments are passed to the
+ constructor.
If the handler class for this type cannot be loaded, an exception is
thrown.
% (module.__file__))
# Call the "handler" function to create the actual action
- action = module.handler()
+ action = module.handler(**kwargs)
# Check if the handler returned is really a subclass of Action
if not isinstance(action, Action):