From patchwork Thu Jul 22 04:23:13 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Meneghel Rodrigues X-Patchwork-Id: 113507 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6M4NZ6h011758 for ; Thu, 22 Jul 2010 04:23:35 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753227Ab0GVEXb (ORCPT ); Thu, 22 Jul 2010 00:23:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35233 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752691Ab0GVEX0 (ORCPT ); Thu, 22 Jul 2010 00:23:26 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6M4NPPn031952 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 22 Jul 2010 00:23:25 -0400 Received: from freedom.redhat.com (vpn-8-204.rdu.redhat.com [10.11.8.204]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6M4NH6E019026; Thu, 22 Jul 2010 00:23:23 -0400 From: Lucas Meneghel Rodrigues To: autotest@test.kernel.org Cc: kvm@vger.kernel.org, Lucas Meneghel Rodrigues Subject: [PATCH 2/3] KVM test: Adapt scripts/unattended.py to handle win virtio drivers Date: Thu, 22 Jul 2010 01:23:13 -0300 Message-Id: <1279772594-10281-2-git-send-email-lmr@redhat.com> In-Reply-To: <1279772594-10281-1-git-send-email-lmr@redhat.com> References: <1279772594-10281-1-git-send-email-lmr@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 22 Jul 2010 04:23:36 +0000 (UTC) diff --git a/client/tests/kvm/scripts/unattended.py b/client/tests/kvm/scripts/unattended.py index d9b8912..80e848a 100755 --- a/client/tests/kvm/scripts/unattended.py +++ b/client/tests/kvm/scripts/unattended.py @@ -3,9 +3,49 @@ Simple script to setup unattended installs on KVM guests. """ # -*- coding: utf-8 -*- -import os, sys, shutil, tempfile, re +import os, sys, shutil, tempfile, re, ConfigParser, glob import common +KNOWN_PACKAGE_MANAGERS = ['rpm', 'dpkg'] + + +def command(cmd): + """ + Find a given command on the user's PATH. + + @param cmd: Command you wish to find (ie, 'ls'). + @return: Full path to the command. + @raise ValueError: In case the command are not found on PATH. + """ + for dir in os.environ['PATH'].split(':'): + file = os.path.join(dir, cmd) + if os.path.exists(file): + return file + raise ValueError('Missing command: %s' % cmd) + + +def package_that_owns(file): + """ + Inquiry the main package manager which package owns file. + + @param file: Path to a given file + """ + support_info = {} + for package_manager in KNOWN_PACKAGE_MANAGERS: + try: + command(package_manager) + support_info[package_manager] = True + except: + support_info[package_manager] = False + + if support_info['rpm']: + return str(os.popen('rpm -qf %s' % file).read()) + elif support_info['dpkg']: + return str(os.popen('dpkg -S %s' % file).read()) + else: + return ('Did not find a known package manager to inquire about ' + 'file %s' % file) + class SetupError(Exception): """ @@ -40,10 +80,44 @@ class UnattendedInstall(object): self.tftp_root = tftp_root self.kernel_args = os.environ.get('KVM_TEST_kernel_args', '') - self.finish_program= os.environ.get('KVM_TEST_finish_program', '') + self.finish_program = os.environ.get('KVM_TEST_finish_program', '') + cdrom_iso = os.environ.get('KVM_TEST_cdrom') self.unattended_file = os.environ.get('KVM_TEST_unattended_file') + install_virtio = os.environ.get('KVM_TEST_install_virtio', 'no') + if install_virtio == 'yes': + self.install_virtio = True + else: + self.install_virtio = False + + virtio_floppy = os.environ.get('KVM_TEST_virtio_floppy', '') + self.virtio_floppy = None + self.virtio_floppy_mount = tempfile.mkdtemp(prefix='floppy_', + dir='/tmp') + if self.install_virtio: + if virtio_floppy and os.path.isfile(virtio_floppy): + print package_that_owns(virtio_floppy) + self.virtio_floppy = virtio_floppy + elif virtio_floppy and not os.path.isfile(virtio_floppy): + print ('Virtio floppy path %s was not found. Please verify' % + virtio_floppy) + + vni = os.environ.get('KVM_TEST_virtio_network_installer', '') + self.virtio_network_installer = None + if self.install_virtio and vni: + self.virtio_network_installer = vni + + voi = os.environ.get('KVM_TEST_virtio_oemsetup_id', '') + self.virtio_oemsetup_identifier = None + if self.install_virtio and voi: + self.virtio_oemsetup_identifier = voi + + vsp = os.environ.get('KVM_TEST_virtio_storage_path', '') + self.virtio_storage_path = None + if self.install_virtio and vsp: + self.virtio_storage_path = vsp + self.qemu_img_bin = os.environ.get('KVM_TEST_qemu_img_binary') if not os.path.isabs(self.qemu_img_bin): self.qemu_img_bin = os.path.join(kvm_test_dir, self.qemu_img_bin) @@ -72,6 +146,84 @@ class UnattendedInstall(object): self.initrd_path = os.path.join(self.image_path, self.initrd) + def copy_virtio_drivers_floppy(self): + """ + Copy the virtio drivers on the virtio floppy to the install floppy. + + 1) Mount the floppy containing the viostor drivers + 2) Copy its contents to the root of the install floppy + """ + m_cmd = 'mount -o loop %s %s' % (self.virtio_floppy, + self.virtio_floppy_mount) + pwd = os.getcwd() + try: + if os.system(m_cmd): + raise SetupError('Could not mount virtio floppy driver') + os.chdir(self.virtio_floppy_mount) + path_list = glob.glob('*') + for path in path_list: + src = os.path.join(self.virtio_floppy_mount, path) + dst = os.path.join(self.floppy_mount, path) + if os.path.isdir(path): + shutil.copytree(src, dst) + elif os.path.isfile(path): + shutil.copyfile(src, dst) + finally: + os.chdir(pwd) + u_cmd = 'umount %s' % self.virtio_floppy_mount + if os.system(u_cmd): + raise SetupError('Could not unmount virtio floppy at %s' % + self.virtio_floppy_mount) + self.cleanup(self.virtio_floppy_mount) + + + def setup_virtio_win2008(self): + """ + Setup the install floppy with the virtio storage drivers, win2008 style. + + Win2008, Vista and 7 require people to point out the path to the drivers + on the unattended file, so we just need to copy the drivers to the + driver floppy disk. + Process: + + 1) Copy the virtio drivers on the virtio floppy to the install floppy + """ + self.copy_virtio_drivers_floppy() + + + def setup_virtio_win2003(self): + """ + Setup the install floppy with the virtio storage drivers, win2003 style. + + Win2003 and WinXP depend on the file txtsetup.oem file to install + the virtio drivers from the floppy, which is a .ini file. + Process: + + 1) Copy the virtio drivers on the virtio floppy to the install floppy + 2) Parse the ini file with config parser + 3) Modify the identifier of the default session that is going to be + executed on the config parser object + 4) Re-write the config file to the disk + """ + self.copy_virtio_drivers_floppy() + txtsetup_oem = os.path.join(self.floppy_mount, 'txtsetup.oem') + if not os.path.isfile(txtsetup_oem): + raise SetupError('File txtsetup.oem not found on the install ' + 'floppy. Please verify if your floppy virtio ' + 'driver image has this file') + parser = ConfigParser.ConfigParser() + parser.read(txtsetup_oem) + if not parser.has_section('Defaults'): + raise SetupError('File txtsetup.oem does not have the session ' + '"Defaults". Please check txtsetup.oem') + default_driver = parser.get('Defaults', 'SCSI') + if default_driver != self.virtio_oemsetup_identifier: + parser.set('Defaults', 'SCSI', self.virtio_oemsetup_identifier) + fp = open(txtsetup_oem, 'w') + parser.write(fp) + fp.close() + + def create_boot_floppy(self): """ Prepares a boot floppy by creating a floppy image file, mounting it and @@ -93,7 +245,8 @@ class UnattendedInstall(object): raise SetupError('Error formatting floppy image.') try: - m_cmd = 'mount -o loop %s %s' % (self.floppy_img, self.floppy_mount) + m_cmd = 'mount -o loop,rw %s %s' % (self.floppy_img, + self.floppy_mount) if os.system(m_cmd): raise SetupError('Could not mount floppy image.') @@ -103,6 +256,9 @@ class UnattendedInstall(object): setup_file_path = os.path.join(self.unattended_dir, setup_file) setup_file_dest = os.path.join(self.floppy_mount, setup_file) shutil.copyfile(setup_file_path, setup_file_dest) + if self.install_virtio: + self.setup_virtio_win2003() + elif self.unattended_file.endswith('.ks'): # Red Hat kickstart install dest_fname = 'ks.cfg' @@ -110,6 +266,8 @@ class UnattendedInstall(object): if self.tftp_root is '': # Windows unattended install dest_fname = "autounattend.xml" + if self.install_virtio: + self.setup_virtio_win2008() else: # SUSE autoyast install dest_fname = "autoinst.xml" @@ -130,7 +288,7 @@ class UnattendedInstall(object): print ("WARNING: 'cdkey' required but not specified for " "this unattended installation") - dummy_re = r'\bKVM_TEST_MEDIUM\b' + dummy_medium_re = r'\bKVM_TEST_MEDIUM\b' if self.medium == "cdrom": content = "cdrom" elif self.medium == "url": @@ -140,7 +298,46 @@ class UnattendedInstall(object): else: raise SetupError("Unexpected installation medium %s" % self.url) - unattended_contents = re.sub(dummy_re, content, unattended_contents) + unattended_contents = re.sub(dummy_medium_re, content, unattended_contents) + + dummy_path = "C:" + + dummy_storage_re = r'\bKVM_TEST_STORAGE_DRIVER_PATH\b' + storage_driver = os.environ.get('KVM_TEST_virtio_storage_path', '') + if re.search(dummy_storage_re, unattended_contents): + if self.install_virtio: + unattended_contents = re.sub(dummy_storage_re, + storage_driver, + unattended_contents) + else: + unattended_contents = re.sub(dummy_storage_re, + dummy_path, + unattended_contents) + + dummy_network_re = r'\bKVM_TEST_NETWORK_DRIVER_PATH\b' + network_driver = os.environ.get('KVM_TEST_virtio_network_path', '') + if re.search(dummy_network_re, unattended_contents): + if self.install_virtio: + unattended_contents = re.sub(dummy_network_re, + network_driver, + unattended_contents) + else: + unattended_contents = re.sub(dummy_network_re, + dummy_path, + unattended_contents) + + dummy_nw_install_re = r'\bKVM_TEST_VIRTIO_NETWORK_INSTALLER\b' + nw_install = os.environ.get('KVM_TEST_virtio_network_installer', + 'help') + if re.search(dummy_nw_install_re, unattended_contents): + if self.install_virtio: + unattended_contents = re.sub(dummy_nw_install_re, + nw_install, + unattended_contents) + else: + unattended_contents = re.sub(dummy_nw_install_re, + 'help', + unattended_contents) print print "Unattended install %s contents:" % dest_fname