mbligh | dcd57a8 | 2007-07-11 23:06:47 +0000 | [diff] [blame] | 1 | # Copyright 2007 Google Inc. Released under the GPL v2 |
| 2 | |
mbligh | dc735a2 | 2007-08-02 16:54:37 +0000 | [diff] [blame] | 3 | """ |
| 4 | This module defines the Kernel class |
mbligh | dcd57a8 | 2007-07-11 23:06:47 +0000 | [diff] [blame] | 5 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 6 | Kernel: an os kernel |
mbligh | dcd57a8 | 2007-07-11 23:06:47 +0000 | [diff] [blame] | 7 | """ |
| 8 | |
mbligh | 02ff2d5 | 2008-06-03 15:00:21 +0000 | [diff] [blame] | 9 | import os, os.path, time |
mbligh | 313f12c | 2008-05-15 23:33:50 +0000 | [diff] [blame] | 10 | from autotest_lib.client.common_lib import error |
mbligh | ccb9e18 | 2008-04-17 15:42:10 +0000 | [diff] [blame] | 11 | from autotest_lib.server import kernel, utils |
mbligh | 03f4fc7 | 2007-11-29 20:56:14 +0000 | [diff] [blame] | 12 | |
mbligh | dcd57a8 | 2007-07-11 23:06:47 +0000 | [diff] [blame] | 13 | |
| 14 | class DEBKernel(kernel.Kernel): |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 15 | """ |
| 16 | This class represents a .deb pre-built kernel. |
mbligh | dcd57a8 | 2007-07-11 23:06:47 +0000 | [diff] [blame] | 17 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 18 | It is used to obtain a built kernel and install it on a Host. |
mbligh | dcd57a8 | 2007-07-11 23:06:47 +0000 | [diff] [blame] | 19 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 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__() |
mbligh | dcd57a8 | 2007-07-11 23:06:47 +0000 | [diff] [blame] | 26 | |
| 27 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 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) |
mbligh | dc735a2 | 2007-08-02 16:54:37 +0000 | [diff] [blame] | 59 | |
| 60 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 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() |
mbligh | dc735a2 | 2007-08-02 16:54:37 +0000 | [diff] [blame] | 79 | |
| 80 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 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(),) |
mbligh | dc735a2 | 2007-08-02 16:54:37 +0000 | [diff] [blame] | 93 | |
| 94 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 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") |
jadmanski | 6200ad7 | 2008-10-02 19:40:06 +0000 | [diff] [blame] | 141 | host.run('dpkg -x "%s" "%s"' % (utils.sh_escape(remote_filename), |
| 142 | utils.sh_escape(content_dir),)) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 143 | |
| 144 | return content_dir |