144 lines
4.9 KiB
Python
144 lines
4.9 KiB
Python
# Copyright 2007 Google Inc. Released under the GPL v2
|
|
|
|
"""
|
|
This module defines the Kernel class
|
|
|
|
Kernel: an os kernel
|
|
"""
|
|
|
|
import os, os.path, time
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.server import kernel, utils
|
|
|
|
|
|
class DEBKernel(kernel.Kernel):
|
|
"""
|
|
This class represents a .deb pre-built kernel.
|
|
|
|
It is used to obtain a built kernel and install it on a Host.
|
|
|
|
Implementation details:
|
|
This is a leaf class in an abstract class hierarchy, it must
|
|
implement the unimplemented methods in parent classes.
|
|
"""
|
|
def __init__(self):
|
|
super(DEBKernel, self).__init__()
|
|
|
|
|
|
def install(self, host, **kwargs):
|
|
"""
|
|
Install a kernel on the remote host.
|
|
|
|
This will also invoke the guest's bootloader to set this
|
|
kernel as the default kernel.
|
|
|
|
Args:
|
|
host: the host on which to install the kernel
|
|
[kwargs]: remaining keyword arguments will be passed
|
|
to Bootloader.add_kernel()
|
|
|
|
Raises:
|
|
AutoservError: no package has yet been obtained. Call
|
|
DEBKernel.get() with a .deb package.
|
|
"""
|
|
if self.source_material is None:
|
|
raise error.AutoservError("A kernel must first be "
|
|
"specified via get()")
|
|
|
|
remote_tmpdir = host.get_tmp_dir()
|
|
basename = os.path.basename(self.source_material)
|
|
remote_filename = os.path.join(remote_tmpdir, basename)
|
|
host.send_file(self.source_material, remote_filename)
|
|
host.run('dpkg -i "%s"' % (utils.sh_escape(remote_filename),))
|
|
host.run('mkinitramfs -o "%s" "%s"' % (
|
|
utils.sh_escape(self.get_initrd_name()),
|
|
utils.sh_escape(self.get_version()),))
|
|
|
|
host.bootloader.add_kernel(self.get_image_name(),
|
|
initrd=self.get_initrd_name(), **kwargs)
|
|
|
|
|
|
def get_version(self):
|
|
"""Get the version of the kernel to be installed.
|
|
|
|
Returns:
|
|
The version string, as would be returned
|
|
by 'make kernelrelease'.
|
|
|
|
Raises:
|
|
AutoservError: no package has yet been obtained. Call
|
|
DEBKernel.get() with a .deb package.
|
|
"""
|
|
if self.source_material is None:
|
|
raise error.AutoservError("A kernel must first be "
|
|
"specified via get()")
|
|
|
|
retval= utils.run('dpkg-deb -f "%s" version' %
|
|
utils.sh_escape(self.source_material),)
|
|
return retval.stdout.strip()
|
|
|
|
|
|
def get_image_name(self):
|
|
"""Get the name of the kernel image to be installed.
|
|
|
|
Returns:
|
|
The full path to the kernel image file as it will be
|
|
installed on the host.
|
|
|
|
Raises:
|
|
AutoservError: no package has yet been obtained. Call
|
|
DEBKernel.get() with a .deb package.
|
|
"""
|
|
return "/boot/vmlinuz-%s" % (self.get_version(),)
|
|
|
|
|
|
def get_initrd_name(self):
|
|
"""Get the name of the initrd file to be installed.
|
|
|
|
Returns:
|
|
The full path to the initrd file as it will be
|
|
installed on the host. If the package includes no
|
|
initrd file, None is returned
|
|
|
|
Raises:
|
|
AutoservError: no package has yet been obtained. Call
|
|
DEBKernel.get() with a .deb package.
|
|
"""
|
|
if self.source_material is None:
|
|
raise error.AutoservError("A kernel must first be "
|
|
"specified via get()")
|
|
|
|
return "/boot/initrd.img-%s" % (self.get_version(),)
|
|
|
|
def extract(self, host):
|
|
"""Extract the kernel package.
|
|
|
|
This function is only useful to access the content of the
|
|
package (for example the kernel image) without
|
|
installing it. It is not necessary to run this function to
|
|
install the kernel.
|
|
|
|
Args:
|
|
host: the host on which to extract the kernel package.
|
|
|
|
Returns:
|
|
The full path to the temporary directory on host where
|
|
the package was extracted.
|
|
|
|
Raises:
|
|
AutoservError: no package has yet been obtained. Call
|
|
DEBKernel.get() with a .deb package.
|
|
"""
|
|
if self.source_material is None:
|
|
raise error.AutoservError("A kernel must first be "
|
|
"specified via get()")
|
|
|
|
remote_tmpdir = host.get_tmp_dir()
|
|
basename = os.path.basename(self.source_material)
|
|
remote_filename = os.path.join(remote_tmpdir, basename)
|
|
host.send_file(self.source_material, remote_filename)
|
|
content_dir= os.path.join(remote_tmpdir, "contents")
|
|
host.run('dpkg -x "%s" "%s"' % (utils.sh_escape(remote_filename),
|
|
utils.sh_escape(content_dir),))
|
|
|
|
return content_dir
|