1# 2# Copyright 2007 Google Inc. Released under the GPL v2 3 4""" 5This module defines the Kernel class 6 7 Kernel: an os kernel 8""" 9 10__author__ = """ 11mbligh@google.com (Martin J. Bligh), 12poirier@google.com (Benjamin Poirier), 13stutsman@google.com (Ryan Stutsman)""" 14 15 16import os, time 17from autotest_lib.client.common_lib import error 18from autotest_lib.server import kernel, utils 19 20 21class RPMKernel(kernel.Kernel): 22 """ 23 This class represents a .rpm pre-built kernel. 24 25 It is used to obtain a built kernel and install it on a Host. 26 27 Implementation details: 28 This is a leaf class in an abstract class hierarchy, it must 29 implement the unimplemented methods in parent classes. 30 """ 31 def __init__(self): 32 super(RPMKernel, self).__init__() 33 34 def install(self, host, label='autotest', 35 default=False, kernel_args = '', install_vmlinux=True): 36 """ 37 Install a kernel on the remote host. 38 39 This will also invoke the guest's bootloader to set this 40 kernel as the default kernel if default=True. 41 42 Args: 43 host: the host on which to install the kernel 44 [kwargs]: remaining keyword arguments will be passed 45 to Bootloader.add_kernel() 46 47 Raises: 48 AutoservError: no package has yet been obtained. Call 49 RPMKernel.get() with a .rpm package. 50 """ 51 if len(label) > 15: 52 raise error.AutoservError("label for kernel is too long \ 53 (> 15 chars): %s" % label) 54 if self.source_material is None: 55 raise error.AutoservError("A kernel must first be \ 56 specified via get()") 57 rpm = self.source_material 58 59 remote_tmpdir = host.get_tmp_dir() 60 remote_rpm = os.path.join(remote_tmpdir, os.path.basename(rpm)) 61 rpm_package = utils.run('/usr/bin/rpm -q -p %s' % rpm).stdout 62 vmlinuz = self.get_image_name() 63 host.send_file(rpm, remote_rpm) 64 host.run('rpm -e ' + rpm_package, ignore_status = True) 65 host.run('rpm --force -i ' + remote_rpm) 66 67 # Copy over the uncompressed image if there is one 68 if install_vmlinux: 69 vmlinux = self.get_vmlinux_name() 70 host.run('cd /;rpm2cpio %s | cpio -imuv .%s' 71 % (remote_rpm, vmlinux)) 72 host.run('ls ' + vmlinux) # Verify 73 74 host.bootloader.remove_kernel(label) 75 host.bootloader.add_kernel(vmlinuz, label, 76 args=kernel_args, default=default) 77 if kernel_args: 78 host.bootloader.add_args(label, kernel_args) 79 if not default: 80 host.bootloader.boot_once(label) 81 82 83 def get_version(self): 84 """Get the version of the kernel to be installed. 85 86 Returns: 87 The version string, as would be returned 88 by 'make kernelrelease'. 89 90 Raises: 91 AutoservError: no package has yet been obtained. Call 92 RPMKernel.get() with a .rpm package. 93 """ 94 if self.source_material is None: 95 raise error.AutoservError("A kernel must first be \ 96 specified via get()") 97 98 retval = utils.run('rpm -qpi %s | grep Version | awk \'{print($3);}\'' 99 % utils.sh_escape(self.source_material)) 100 return retval.stdout.strip() 101 102 103 def get_image_name(self): 104 """Get the name of the kernel image to be installed. 105 106 Returns: 107 The full path to the kernel image file as it will be 108 installed on the host. 109 110 Raises: 111 AutoservError: no package has yet been obtained. Call 112 RPMKernel.get() with a .rpm package. 113 """ 114 if self.source_material is None: 115 raise error.AutoservError("A kernel must first be \ 116 specified via get()") 117 118 vmlinuz = utils.run('rpm -q -l -p %s | grep /boot/vmlinuz' 119 % self.source_material).stdout.strip() 120 return vmlinuz 121 122 123 def get_vmlinux_name(self): 124 """Get the name of the kernel image to be installed. 125 126 Returns: 127 The full path to the kernel image file as it will be 128 installed on the host. It is the uncompressed and 129 unstripped version of the kernel that can be used with 130 oprofile. 131 132 Raises: 133 AutoservError: no package has yet been obtained. Call 134 RPMKernel.get() with a .rpm package. 135 """ 136 if self.source_material is None: 137 raise error.AutoservError("A kernel must first be \ 138 specified via get()") 139 140 vmlinux = utils.run('rpm -q -l -p %s | grep /boot/vmlinux' 141 % self.source_material).stdout.strip() 142 return vmlinux 143 144 145 def get_initrd_name(self): 146 """Get the name of the initrd file to be installed. 147 148 Returns: 149 The full path to the initrd file as it will be 150 installed on the host. If the package includes no 151 initrd file, None is returned 152 153 Raises: 154 AutoservError: no package has yet been obtained. Call 155 RPMKernel.get() with a .rpm package. 156 """ 157 if self.source_material is None: 158 raise error.AutoservError("A kernel must first be \ 159 specified via get()") 160 161 res = utils.run('rpm -q -l -p %s | grep /boot/initrd' 162 % self.source_material, ignore_status=True) 163 if res.exit_status: 164 return None 165 return res.stdout.strip() 166