1 # Copyright 2007 Google Inc. Released under the GPL v2 2 3 """ 4 This module defines the Kernel class 5 6 Kernel: an os kernel 7 """ 8 9 import os, os.path, time 10 from autotest_lib.client.common_lib import error 11 from autotest_lib.server import kernel, utils 12 13 14 class DEBKernel(kernel.Kernel): 15 """ 16 This class represents a .deb pre-built kernel. 17 18 It is used to obtain a built kernel and install it on a Host. 19 20 Implementation details: 21 This is a leaf class in an abstract class hierarchy, it must 22 implement the unimplemented methods in parent classes. 23 """ 24 def __init__(self): 25 super(DEBKernel, self).__init__() 26 27 28 def install(self, host, **kwargs): 29 """ 30 Install a kernel on the remote host. 31 32 This will also invoke the guest's bootloader to set this 33 kernel as the default kernel. 34 35 Args: 36 host: the host on which to install the kernel 37 [kwargs]: remaining keyword arguments will be passed 38 to Bootloader.add_kernel() 39 40 Raises: 41 AutoservError: no package has yet been obtained. Call 42 DEBKernel.get() with a .deb package. 43 """ 44 if self.source_material is None: 45 raise error.AutoservError("A kernel must first be " 46 "specified via get()") 47 48 remote_tmpdir = host.get_tmp_dir() 49 basename = os.path.basename(self.source_material) 50 remote_filename = os.path.join(remote_tmpdir, basename) 51 host.send_file(self.source_material, remote_filename) 52 host.run('dpkg -i "%s"' % (utils.sh_escape(remote_filename),)) 53 host.run('mkinitramfs -o "%s" "%s"' % ( 54 utils.sh_escape(self.get_initrd_name()), 55 utils.sh_escape(self.get_version()),)) 56 57 host.bootloader.add_kernel(self.get_image_name(), 58 initrd=self.get_initrd_name(), **kwargs) 59 60 61 def get_version(self): 62 """Get the version of the kernel to be installed. 63 64 Returns: 65 The version string, as would be returned 66 by 'make kernelrelease'. 67 68 Raises: 69 AutoservError: no package has yet been obtained. Call 70 DEBKernel.get() with a .deb package. 71 """ 72 if self.source_material is None: 73 raise error.AutoservError("A kernel must first be " 74 "specified via get()") 75 76 retval= utils.run('dpkg-deb -f "%s" version' % 77 utils.sh_escape(self.source_material),) 78 return retval.stdout.strip() 79 80 81 def get_image_name(self): 82 """Get the name of the kernel image to be installed. 83 84 Returns: 85 The full path to the kernel image file as it will be 86 installed on the host. 87 88 Raises: 89 AutoservError: no package has yet been obtained. Call 90 DEBKernel.get() with a .deb package. 91 """ 92 return "/boot/vmlinuz-%s" % (self.get_version(),) 93 94 95 def get_initrd_name(self): 96 """Get the name of the initrd file to be installed. 97 98 Returns: 99 The full path to the initrd file as it will be 100 installed on the host. If the package includes no 101 initrd file, None is returned 102 103 Raises: 104 AutoservError: no package has yet been obtained. Call 105 DEBKernel.get() with a .deb package. 106 """ 107 if self.source_material is None: 108 raise error.AutoservError("A kernel must first be " 109 "specified via get()") 110 111 return "/boot/initrd.img-%s" % (self.get_version(),) 112 113 def extract(self, host): 114 """Extract the kernel package. 115 116 This function is only useful to access the content of the 117 package (for example the kernel image) without 118 installing it. It is not necessary to run this function to 119 install the kernel. 120 121 Args: 122 host: the host on which to extract the kernel package. 123 124 Returns: 125 The full path to the temporary directory on host where 126 the package was extracted. 127 128 Raises: 129 AutoservError: no package has yet been obtained. Call 130 DEBKernel.get() with a .deb package. 131 """ 132 if self.source_material is None: 133 raise error.AutoservError("A kernel must first be " 134 "specified via get()") 135 136 remote_tmpdir = host.get_tmp_dir() 137 basename = os.path.basename(self.source_material) 138 remote_filename = os.path.join(remote_tmpdir, basename) 139 host.send_file(self.source_material, remote_filename) 140 content_dir= os.path.join(remote_tmpdir, "contents") 141 host.run('dpkg -x "%s" "%s"' % (utils.sh_escape(remote_filename), 142 utils.sh_escape(content_dir),)) 143 144 return content_dir 145