summaryrefslogtreecommitdiffstats
path: root/ipapython/install/common.py
blob: 799ce50093d6e8509b9116bf7e4a2e28720f77df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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