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