summaryrefslogtreecommitdiffstats
path: root/ipapython/install/common.py
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2015-06-02 12:04:25 +0000
committerJan Cholasta <jcholast@redhat.com>2015-06-08 15:34:11 +0000
commit9e9c01fba2938f26843a6c4f44622c86416ef525 (patch)
tree7c7253d28f91d90949cbf9ec6b0e19215bcf07e0 /ipapython/install/common.py
parent08229a0c5457d4e0c13d6b02a1f38f60ea787856 (diff)
downloadfreeipa-9e9c01fba2938f26843a6c4f44622c86416ef525.tar.gz
freeipa-9e9c01fba2938f26843a6c4f44622c86416ef525.tar.xz
freeipa-9e9c01fba2938f26843a6c4f44622c86416ef525.zip
install: Introduce installer framework ipapython.install
https://fedorahosted.org/freeipa/ticket/4468 Reviewed-By: Martin Basti <mbasti@redhat.com>
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