installer.py revision 456d3c115952bf1ae984770e226c5a50676b31c0
1'''
2Installer classes are responsible for building and installing virtualization
3specific software components. This is the main entry point for tests that
4wish to install virtualization software components.
5
6The most common use case is to simply call make_installer() inside your tests.
7'''
8
9from autotest_lib.client.common_lib import error
10from autotest_lib.client.virt import base_installer
11
12__all__ = ['InstallerRegistry', 'INSTALLER_REGISTRY', 'make_installer',
13           'run_installers']
14
15class InstallerRegistry(dict):
16    '''
17    Holds information on known installer classes
18
19    This class is used to create a single instance, named INSTALLER_REGISTRY,
20    that will hold all information on known installer types.
21
22    For registering a new installer class, use the register() method. If the
23    virt type is not set explicitly, it will be set to 'base'. Example:
24
25    >>> INSTALLER_REGISTRY.register('yum', base_installer.YumInstaller)
26
27    If you want to register a virt specific installer class, set the virt
28    (third) param:
29
30    >>> INSTALLER_REGISTRY.register('yum', kvm_installer.YumInstaller, 'kvm')
31
32    For getting a installer class, use the get_installer() method. This method
33    has a fallback option 'get_default_virt' that will return a generic virt
34    installer if set to true.
35    '''
36
37    DEFAULT_VIRT_NAME = 'base'
38
39    def __init__(self, **kwargs):
40        dict.__init__(self, **kwargs)
41        self[self.DEFAULT_VIRT_NAME] = {}
42
43
44    def register(self, mode, klass, virt=None):
45        '''
46        Register a class as responsible for installing virt software components
47
48        If virt is not set, it will assume a default of 'base'.
49        '''
50        if virt is None:
51            virt = self.DEFAULT_VIRT_NAME
52        elif not self.has_key(virt):
53            self[virt] = {}
54
55        self[virt][mode] = klass
56
57
58    def get_installer(self, mode, virt=None, get_default_virt=False):
59        '''
60        Gets a installer class that should be able to install the virt software
61
62        Always try to use classes that are specific to the virtualization
63        technology that is being tested. If you have confidence that the
64        installation is rather trivial and does not require custom steps, you
65        may be able to get away with a base class (by setting get_default_virt
66        to True).
67        '''
68        if virt is None:
69            virt = self.DEFAULT_VIRT_NAME
70        if not self.has_key(virt):
71            # return a base installer so the test could and give it a try?
72            if get_default_virt:
73                return self[self.DEFAULT_VIRT_NAME].get(mode)
74        else:
75            return self[virt].get(mode)
76
77
78    def get_modes(self, virt=None):
79        '''
80        Returns a list of all registered installer modes
81        '''
82        if virt is None:
83            virt = self.DEFAULT_VIRT_NAME
84
85        if not self.has_key(virt):
86            return []
87
88        return self[virt].keys()
89
90
91#
92# InstallerRegistry unique instance
93#
94INSTALLER_REGISTRY = InstallerRegistry()
95
96
97#
98# Register base installers
99#
100INSTALLER_REGISTRY.register('yum',
101                            base_installer.YumInstaller)
102INSTALLER_REGISTRY.register('koji',
103                            base_installer.KojiInstaller)
104INSTALLER_REGISTRY.register('git_repo',
105                            base_installer.GitRepoInstaller)
106INSTALLER_REGISTRY.register('local_src',
107                            base_installer.LocalSourceDirInstaller)
108INSTALLER_REGISTRY.register('local_tar',
109                            base_installer.LocalSourceTarInstaller)
110INSTALLER_REGISTRY.register('remote_tar',
111                            base_installer.RemoteSourceTarInstaller)
112
113
114def installer_name_split(fullname, virt=None):
115    '''
116    Split a full installer name into mode and short name
117
118    Examples:
119       git_repo_foo -> (git_repo, foo)
120       local_src_foo -> (local_src, foo)
121    '''
122    for mode in INSTALLER_REGISTRY.get_modes(virt):
123        if fullname.startswith('%s_' % mode):
124            null, _name = fullname.split(mode)
125            name = _name[1:]
126            return (mode, name)
127
128    return (None, None)
129
130
131def make_installer(fullname, params, test=None):
132    '''
133    Installer factory: returns a new installer for the chosen mode and vm type
134
135    This is the main entry point for acquiring an installer. Tests, such as
136    the build test, should use this function.
137
138    Param priority evaluation order is 'install_mode', then 'mode'. For virt
139    type, 'vm_type' is consulted.
140
141    @param fullname: the full name of instance, eg: git_repo_foo
142    @param params: dictionary with parameters generated from cartersian config
143    @param test: the test instance
144    '''
145    virt = params.get("vm_type", None)
146
147    mode, name = installer_name_split(fullname, virt)
148    if mode is None or name is None:
149
150        error_msg = ('Invalid installer mode or name for "%s". Probably an '
151                     'installer has not been registered' % fullname)
152        if virt is not None:
153            error_msg += ' specifically for virt type "%s"' % virt
154
155        raise error.TestError(error_msg)
156
157    klass = INSTALLER_REGISTRY.get_installer(mode, virt)
158    if klass is None:
159        raise error.TestError('Installer mode %s is not registered' % mode)
160    else:
161        return klass(mode, name, test, params)
162
163
164def run_installers(params, test=None):
165    '''
166    Runs the installation routines for all installers, one at a time
167
168    This is usually the main entry point for tests
169    '''
170    for name in params.get("installers", "").split():
171        installer = make_installer(name, params, test)
172        installer.install()
173