summaryrefslogtreecommitdiffstats
path: root/ipapython/install/common.py
diff options
context:
space:
mode:
Diffstat (limited to 'ipapython/install/common.py')
-rw-r--r--ipapython/install/common.py115
1 files changed, 115 insertions, 0 deletions
diff --git a/ipapython/install/common.py b/ipapython/install/common.py
new file mode 100644
index 000000000..799ce5009
--- /dev/null
+++ b/ipapython/install/common.py
@@ -0,0 +1,115 @@
+#
+# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
+#
+
+"""
+Common stuff.
+"""
+
+import traceback
+
+from . import core
+from .util import from_
+
+__all__ = ['step', 'Installable', 'Interactive', 'Continuous', 'installer',
+ 'uninstaller']
+
+
+def step():
+ def decorator(func):
+ cls = core.Component(Step)
+ cls._installer = staticmethod(func)
+ return cls
+
+ return decorator
+
+
+class Installable(core.Configurable):
+ """
+ Configurable which does install or uninstall.
+ """
+
+ uninstalling = core.Property(False)
+
+ def _get_components(self):
+ components = super(Installable, self)._get_components()
+ if self.uninstalling:
+ components = reversed(list(components))
+ return components
+
+ def _configure(self):
+ if self.uninstalling:
+ return self._uninstall()
+ else:
+ return self._install()
+
+ def _install(self):
+ assert not hasattr(super(Installable, self), '_install')
+
+ return super(Installable, self)._configure()
+
+ def _uninstall(self):
+ assert not hasattr(super(Installable, self), '_uninstall')
+
+ return super(Installable, self)._configure()
+
+
+class Step(Installable):
+ @property
+ def parent(self):
+ raise AttributeError('parent')
+
+ def _install(self):
+ for nothing in self._installer(self.parent):
+ yield from_(super(Step, self)._install())
+
+ @staticmethod
+ def _installer(obj):
+ yield
+
+ def _uninstall(self):
+ for nothing in self._uninstaller(self.parent):
+ yield from_(super(Step, self)._uninstall())
+
+ @staticmethod
+ def _uninstaller(obj):
+ yield
+
+ @classmethod
+ def uninstaller(cls, func):
+ cls._uninstaller = staticmethod(func)
+ return cls
+
+
+class Interactive(core.Configurable):
+ interactive = core.Property(False)
+
+
+class Continuous(core.Configurable):
+ def _handle_exception(self, exc_info):
+ try:
+ super(Continuous, self)._handle_exception(exc_info)
+ except BaseException as e:
+ self.log.debug(traceback.format_exc())
+ if isinstance(e, Exception):
+ self.log.error("%s", e)
+
+
+def installer(cls):
+ class Installer(cls, Installable):
+ def __init__(self, **kwargs):
+ super(Installer, self).__init__(uninstalling=False,
+ **kwargs)
+ Installer.__name__ = 'installer({0})'.format(cls.__name__)
+
+ return Installer
+
+
+def uninstaller(cls):
+ class Uninstaller(Continuous, cls, Installable):
+ def __init__(self, **kwargs):
+ super(Uninstaller, self).__init__(uninstalling=True,
+ **kwargs)
+ Uninstaller.__name__ = 'uninstaller({0})'.format(cls.__name__)
+
+ return Uninstaller