Home | History | Annotate | Download | only in virt
      1 '''
      2 Installer classes are responsible for building and installing virtualization
      3 specific software components. This is the main entry point for tests that
      4 wish to install virtualization software components.
      5 
      6 The most common use case is to simply call make_installer() inside your tests.
      7 '''
      8 
      9 from autotest_lib.client.common_lib import error
     10 from autotest_lib.client.virt import base_installer
     11 
     12 __all__ = ['InstallerRegistry', 'INSTALLER_REGISTRY', 'make_installer',
     13            'run_installers']
     14 
     15 class 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 #
     94 INSTALLER_REGISTRY = InstallerRegistry()
     95 
     96 
     97 #
     98 # Register base installers
     99 #
    100 INSTALLER_REGISTRY.register('yum',
    101                             base_installer.YumInstaller)
    102 INSTALLER_REGISTRY.register('koji',
    103                             base_installer.KojiInstaller)
    104 INSTALLER_REGISTRY.register('git_repo',
    105                             base_installer.GitRepoInstaller)
    106 INSTALLER_REGISTRY.register('local_src',
    107                             base_installer.LocalSourceDirInstaller)
    108 INSTALLER_REGISTRY.register('local_tar',
    109                             base_installer.LocalSourceTarInstaller)
    110 INSTALLER_REGISTRY.register('remote_tar',
    111                             base_installer.RemoteSourceTarInstaller)
    112 
    113 
    114 def 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 
    131 def 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 
    164 def 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