Home | History | Annotate | Download | only in server
      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