Index: client/tests/kvm/scripts/unattended.py |
diff --git a/client/tests/kvm/scripts/unattended.py b/client/tests/kvm/scripts/unattended.py |
index e9e4751d5e44e9b4dd3e22f29f12ed9c312ab27b..1029d1eb5e84bf4b6536843dee304453bda5c57a 100755 |
--- a/client/tests/kvm/scripts/unattended.py |
+++ b/client/tests/kvm/scripts/unattended.py |
@@ -242,8 +242,9 @@ class CdromDisk(Disk): |
class UnattendedInstall(object): |
""" |
Creates a floppy disk image that will contain a config file for unattended |
- OS install. The parameters to the script are retrieved from environment |
- variables. |
+ OS install. Optionally, sets up a PXE install server using qemu built in |
+ TFTP and DHCP servers to install a particular operating system. The |
+ parameters to the script are retrieved from environment variables. |
""" |
def __init__(self): |
""" |
@@ -255,9 +256,9 @@ class UnattendedInstall(object): |
attributes = ['kernel_args', 'finish_program', 'cdrom_cd1', |
'unattended_file', 'medium', 'url', 'kernel', 'initrd', |
- 'nfs_server', 'nfs_dir', 'install_virtio', 'floppy', |
- 'cdrom_unattended', 'boot_path', 'extra_params'] |
- |
+ 'nfs_server', 'nfs_dir', 'pxe_dir', 'pxe_image', |
+ 'pxe_initrd', 'install_virtio', 'tftp', |
+ 'floppy', 'cdrom_unattended'] |
for a in attributes: |
self._setattr(a) |
@@ -268,6 +269,13 @@ class UnattendedInstall(object): |
for va in v_attributes: |
self._setattr(va) |
+ # Silly attribution just to calm pylint down... |
+ self.tftp = self.tftp |
+ if self.tftp: |
+ self.tftp = os.path.join(KVM_TEST_DIR, self.tftp) |
+ if not os.path.isdir(self.tftp): |
+ os.makedirs(self.tftp) |
+ |
if self.cdrom_cd1: |
self.cdrom_cd1 = os.path.join(KVM_TEST_DIR, self.cdrom_cd1) |
self.cdrom_cd1_mount = tempfile.mkdtemp(prefix='cdrom_cd1_', dir='/tmp') |
@@ -279,7 +287,9 @@ class UnattendedInstall(object): |
if not os.path.isdir(os.path.dirname(self.floppy)): |
os.makedirs(os.path.dirname(self.floppy)) |
- self.image_path = os.path.dirname(self.kernel) |
+ self.image_path = KVM_TEST_DIR |
+ self.kernel_path = os.path.join(self.image_path, self.kernel) |
+ self.initrd_path = os.path.join(self.image_path, self.initrd) |
def _setattr(self, key): |
@@ -398,7 +408,7 @@ class UnattendedInstall(object): |
boot_disk.setup_answer_file(dest_fname, answer_contents) |
elif self.unattended_file.endswith('.xml'): |
- if "autoyast" in self.extra_params: |
+ if self.tftp: |
# SUSE autoyast install |
dest_fname = "autoinst.xml" |
if self.cdrom_unattended: |
@@ -426,44 +436,87 @@ class UnattendedInstall(object): |
boot_disk.close() |
- def setup_cdrom(self): |
+ def setup_pxe_boot(self): |
""" |
- Mount cdrom and copy vmlinuz and initrd.img. |
+ Sets up a PXE boot environment using the built in qemu TFTP server. |
+ Copies the PXE Linux bootloader pxelinux.0 from the host (needs the |
+ pxelinux package or equivalent for your distro), and vmlinuz and |
+ initrd.img files from the CD to a directory that qemu will serve trough |
+ TFTP to the VM. |
""" |
- print "Copying vmlinuz and initrd.img from cdrom" |
- m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' % |
- (self.cdrom_cd1, self.cdrom_cd1_mount)) |
- run(m_cmd, info='Could not mount CD image %s.' % self.cdrom_cd1) |
+ print "Setting up PXE boot using TFTP root %s" % self.tftp |
+ |
+ pxe_file = None |
+ pxe_paths = ['/usr/lib/syslinux/pxelinux.0', |
+ '/usr/share/syslinux/pxelinux.0'] |
+ for path in pxe_paths: |
+ if os.path.isfile(path): |
+ pxe_file = path |
+ break |
+ |
+ if not pxe_file: |
+ raise SetupError('Cannot find PXE boot loader pxelinux.0. Make ' |
+ 'sure pxelinux or equivalent package for your ' |
+ 'distro is installed.') |
+ |
+ pxe_dest = os.path.join(self.tftp, 'pxelinux.0') |
+ shutil.copyfile(pxe_file, pxe_dest) |
try: |
- img_path_cmd = ("mkdir -p %s" % self.image_path) |
- run(img_path_cmd, info=("Could not create image path dir %s" % |
- self.image_path)) |
- kernel_fetch_cmd = ("cp %s/%s/%s %s" % |
- (self.cdrom_cd1_mount, self.boot_path, |
- os.path.basename(self.kernel), self.kernel)) |
- run(kernel_fetch_cmd, info=("Could not copy the vmlinuz from %s" % |
- self.cdrom_cd1_mount)) |
- initrd_fetch_cmd = ("cp %s/%s/%s %s" % |
- (self.cdrom_cd1_mount, self.boot_path, |
- os.path.basename(self.initrd), self.initrd)) |
- run(initrd_fetch_cmd, info=("Could not copy the initrd.img from " |
- "%s" % self.cdrom_cd1_mount)) |
+ m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' % |
+ (self.cdrom_cd1, self.cdrom_cd1_mount)) |
+ run(m_cmd, info='Could not mount CD image %s.' % self.cdrom_cd1) |
+ |
+ pxe_dir = os.path.join(self.cdrom_cd1_mount, self.pxe_dir) |
+ pxe_image = os.path.join(pxe_dir, self.pxe_image) |
+ pxe_initrd = os.path.join(pxe_dir, self.pxe_initrd) |
+ |
+ if not os.path.isdir(pxe_dir): |
+ raise SetupError('The ISO image does not have a %s dir. The ' |
+ 'script assumes that the cd has a %s dir ' |
+ 'where to search for the vmlinuz image.' % |
+ (self.pxe_dir, self.pxe_dir)) |
+ |
+ if not os.path.isfile(pxe_image) or not os.path.isfile(pxe_initrd): |
+ raise SetupError('The location %s is lacking either a vmlinuz ' |
+ 'or a initrd.img file. Cannot find a PXE ' |
+ 'image to proceed.' % self.pxe_dir) |
+ |
+ tftp_image = os.path.join(self.tftp, 'vmlinuz') |
+ tftp_initrd = os.path.join(self.tftp, 'initrd.img') |
+ shutil.copyfile(pxe_image, tftp_image) |
+ shutil.copyfile(pxe_initrd, tftp_initrd) |
+ |
finally: |
cleanup(self.cdrom_cd1_mount) |
+ pxe_config_dir = os.path.join(self.tftp, 'pxelinux.cfg') |
+ if not os.path.isdir(pxe_config_dir): |
+ os.makedirs(pxe_config_dir) |
+ pxe_config_path = os.path.join(pxe_config_dir, 'default') |
+ |
+ pxe_config = open(pxe_config_path, 'w') |
+ pxe_config.write('DEFAULT pxeboot\n') |
+ pxe_config.write('TIMEOUT 20\n') |
+ pxe_config.write('PROMPT 0\n') |
+ pxe_config.write('LABEL pxeboot\n') |
+ pxe_config.write(' KERNEL vmlinuz\n') |
+ pxe_config.write(' APPEND initrd=initrd.img %s\n' % |
+ self.kernel_args) |
+ pxe_config.close() |
+ |
+ print "PXE boot successfuly set" |
+ |
def setup_url(self): |
""" |
Download the vmlinuz and initrd.img from URL. |
""" |
- print "Downloading vmlinuz and initrd.img from URL" |
+ print "Downloading the vmlinuz and initrd.img" |
os.chdir(self.image_path) |
- kernel_fetch_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path, |
- os.path.basename(self.kernel)) |
- initrd_fetch_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path, |
- os.path.basename(self.initrd)) |
+ kernel_fetch_cmd = "wget -q %s/isolinux/%s" % (self.url, self.kernel) |
+ initrd_fetch_cmd = "wget -q %s/isolinux/%s" % (self.url, self.initrd) |
if os.path.exists(self.kernel): |
os.unlink(self.kernel) |
@@ -473,6 +526,7 @@ class UnattendedInstall(object): |
run(kernel_fetch_cmd, info="Could not fetch vmlinuz from %s" % self.url) |
run(initrd_fetch_cmd, info=("Could not fetch initrd.img from %s" % |
self.url)) |
+ print "Download of vmlinuz and initrd.img finished" |
def setup_nfs(self): |
@@ -486,14 +540,12 @@ class UnattendedInstall(object): |
run(m_cmd, info='Could not mount nfs server') |
try: |
- kernel_fetch_cmd = ("cp %s/%s/%s %s" % |
- (self.nfs_mount, self.boot_path, |
- os.path.basename(self.kernel), self.image_path)) |
+ kernel_fetch_cmd = ("cp %s/isolinux/%s %s" % |
+ (self.nfs_mount, self.kernel, self.image_path)) |
run(kernel_fetch_cmd, info=("Could not copy the vmlinuz from %s" % |
self.nfs_mount)) |
- initrd_fetch_cmd = ("cp %s/%s/%s %s" % |
- (self.nfs_mount, self.boot_path, |
- os.path.basename(self.initrd), self.image_path)) |
+ initrd_fetch_cmd = ("cp %s/isolinux/%s %s" % |
+ (self.nfs_mount, self.initrd, self.image_path)) |
run(initrd_fetch_cmd, info=("Could not copy the initrd.img from " |
"%s" % self.nfs_mount)) |
finally: |
@@ -520,8 +572,8 @@ class UnattendedInstall(object): |
if self.unattended_file and (self.floppy or self.cdrom_unattended): |
self.setup_boot_disk() |
if self.medium == "cdrom": |
- if self.kernel and self.initrd: |
- self.setup_cdrom() |
+ if self.tftp: |
+ self.setup_pxe_boot() |
elif self.medium == "url": |
self.setup_url() |
elif self.medium == "nfs": |