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