From: Lucas Meneghel Rodrigues <lmr@redhat.com>
To: autotest@test.kernel.org
Cc: kvm@vger.kernel.org
Subject: [PATCH 11/16] Virt: add support for XEN via libvirt installs and auto url
Date: Thu, 3 Nov 2011 19:26:17 -0200 [thread overview]
Message-ID: <1320355582-4342-12-git-send-email-lmr@redhat.com> (raw)
In-Reply-To: <1320355582-4342-1-git-send-email-lmr@redhat.com>
This patch adds support to unattended installs via libvirt+XEN and
serving installation content via the auto url feature (using a
builtin http server).
A sample configuration is provided to run a Fedora 15 64 bits PV
based test (libvirt_xenpv_f15_quick).
Signed-off-by: Cleber Rosa <crosa@redhat.com>
---
client/tests/libvirt/tests.cfg.sample | 15 ++
client/tests/libvirt/tests_base.cfg.sample | 7 +
client/virt/tests/unattended_install.py | 220 +++++++++++++++++++++++++---
3 files changed, 222 insertions(+), 20 deletions(-)
diff --git a/client/tests/libvirt/tests.cfg.sample b/client/tests/libvirt/tests.cfg.sample
index a068587..8a1d318 100644
--- a/client/tests/libvirt/tests.cfg.sample
+++ b/client/tests/libvirt/tests.cfg.sample
@@ -38,6 +38,21 @@ variants:
only Fedora.15.64
only unattended_install.cdrom, boot, reboot, shutdown
+ # Runs virt-install, f15 64 as a 64 bit PV guest OS, install, boot, shutdown
+ - @libvirt_xenpv_f15_quick:
+ virt_install_binary = /usr/bin/virt-install
+ qemu_img_binary = /usr/bin/qemu-img
+ url = auto
+ cdrom_cd1 = isos/linux/Fedora-15-x86_64-DVD.iso
+ only raw
+ only xennet
+ only xenblk
+ only smp2
+ only no_pci_assignable
+ only smallpages
+ only Fedora.15.64
+ only unattended_install.url, boot, reboot, shutdown
+
# Runs virt-install, RHEL 6.0 64 bit guest OS, install, boot, shutdown
- @libvirt_rhel60_quick:
virt_install_binary = /usr/bin/virt-install
diff --git a/client/tests/libvirt/tests_base.cfg.sample b/client/tests/libvirt/tests_base.cfg.sample
index 6c5a785..409fe80 100644
--- a/client/tests/libvirt/tests_base.cfg.sample
+++ b/client/tests/libvirt/tests_base.cfg.sample
@@ -90,6 +90,9 @@ use_os_variant = no
use_os_type = yes
# libvirt network to use examples network=default or bridge=br0
virsh_network = network=default
+# if using 'url = auto' to install, url_auto_ip must match IP on
+# selected virsh network or bridge
+url_auto_ip = 192.168.122.1
# wait in minutes for virt-install to finish (bz still open)
use_virt_install_wait = no
virt_install_wait_time = 300
@@ -1165,6 +1168,8 @@ variants:
# Device selection for the NDISTest server machine
dp_regex_servermsgdev = VirtIO Ethernet Adapter$
dp_regex_serversupportdev = VirtIO Ethernet Adapter #2$
+ -xennet:
+ # placeholder
# Guests
variants:
@@ -2802,6 +2807,8 @@ variants:
drive_format=usb2
- usb.cdrom:
cd_format=usb2
+ - xenblk:
+ # placeholder
virtio_net, virtio_blk, e1000, balloon_check:
diff --git a/client/virt/tests/unattended_install.py b/client/virt/tests/unattended_install.py
index 81f3806..daeb453 100644
--- a/client/virt/tests/unattended_install.py
+++ b/client/virt/tests/unattended_install.py
@@ -1,8 +1,45 @@
import logging, time, socket, re, os, shutil, tempfile, glob, ConfigParser
+import threading
import xml.dom.minidom
from autotest_lib.client.common_lib import error
from autotest_lib.client.bin import utils
-from autotest_lib.client.virt import virt_vm, virt_utils
+from autotest_lib.client.virt import virt_vm, virt_utils, virt_http_server
+
+
+_url_auto_content_server_thread = None
+_url_auto_content_server_thread_event = None
+
+_unattended_server_thread = None
+_unattended_server_thread_event = None
+
+
+def terminate_auto_content_server_thread():
+ global _url_auto_content_server_thread
+ global _url_auto_content_server_thread_event
+
+ if _url_auto_content_server_thread is None:
+ return False
+ if _url_auto_content_server_thread_event is None:
+ return False
+
+ if _url_auto_content_server_thread_event.isSet():
+ return True
+
+ return False
+
+
+def terminate_unattended_server_thread():
+ global _unattended_server_thread, _unattended_server_thread_event
+
+ if _unattended_server_thread is None:
+ return False
+ if _unattended_server_thread_event is None:
+ return False
+
+ if _unattended_server_thread_event.isSet():
+ return True
+
+ return False
@error.context_aware
@@ -213,12 +250,13 @@ class UnattendedInstallConfig(object):
root_dir = test.bindir
self.deps_dir = os.path.join(test.virtdir, 'deps')
self.unattended_dir = os.path.join(test.virtdir, 'unattended')
+ self.params = params
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',
- 'qemu_img_binary', 'cdkey', 'finish_program']
+ 'qemu_img_binary', 'cdkey', 'finish_program', 'vm_type']
for a in attributes:
setattr(self, a, params.get(a, ''))
@@ -258,6 +296,14 @@ class UnattendedInstallConfig(object):
self.image_path = os.path.dirname(self.kernel)
+ # Content server params
+ self.url_auto_content_ip = params.get('url_auto_ip', '192.168.122.1')
+ self.url_auto_content_port = None
+
+ # Kickstart server params
+ # use the same IP as url_auto_content_ip, but a different port
+ self.unattended_server_port = None
+
def answer_kickstart(self, answer_path):
"""
@@ -278,7 +324,13 @@ class UnattendedInstallConfig(object):
if self.medium in ["cdrom", "kernel_initrd"]:
content = "cdrom"
elif self.medium == "url":
- content = "url --url %s" % self.url
+ if self.url == 'auto':
+ url = "http://%s:%s" % (self.url_auto_content_ip,
+ self.url_auto_content_port)
+ else:
+ url = self.url
+ content = "url --url %s" % url
+
elif self.medium == "nfs":
content = "nfs --server=%s --dir=%s" % (self.nfs_server,
self.nfs_dir)
@@ -418,14 +470,22 @@ class UnattendedInstallConfig(object):
logging.debug("Remastering initrd.gz file with preseed file")
dest_fname = 'preseed.cfg'
remaster_path = os.path.join(self.image_path, "initrd_remaster")
- os.makedirs(remaster_path)
+ if not os.path.isdir(remaster_path):
+ os.makedirs(remaster_path)
+ base_initrd = os.path.basename(self.initrd)
os.chdir(remaster_path)
utils.run("gzip -d < ../%s | cpio --extract --make-directories "
- "--no-absolute-filenames" % os.path.basename(self.initrd))
+ "--no-absolute-filenames" % base_initrd)
utils.run("cp %s %s" % (self.unattended_file, dest_fname))
- utils.run("find . | cpio -H newc --create | gzip -9 > ../%s" %
- os.path.basename(self.initrd))
+
+ if self.params.get("vm_type") == "libvirt":
+ utils.run("find . | cpio -H newc --create > ../%s.img" %
+ base_initrd.rstrip(".gz"))
+ else:
+ utils.run("find . | cpio -H newc --create | gzip -9 > ../%s" %
+ base_initrd)
+
os.chdir(self.image_path)
utils.run("rm -rf initrd_remaster")
contents = open(self.unattended_file).read()
@@ -435,6 +495,51 @@ class UnattendedInstallConfig(object):
logging.debug(line)
+ def setup_unattended_http_server(self):
+ '''
+ Setup a builtin http server for serving the kickstart file
+
+ Does nothing if unattended file is not a kickstart file
+ '''
+ global _unattended_server_thread, _unattended_server_thread_event
+
+ if self.unattended_file.endswith('.ks'):
+ # Red Hat kickstart install
+ dest_fname = 'ks.cfg'
+
+ answer_path = os.path.join(self.tmpdir, dest_fname)
+ self.answer_kickstart(answer_path)
+
+ if self.unattended_server_port is None:
+ self.unattended_server_port = virt_utils.find_free_port(
+ 8000,
+ 8100,
+ self.url_auto_content_ip)
+
+ if _unattended_server_thread is None:
+ _unattended_server_thread_event = threading.Event()
+ _unattended_server_thread = threading.Thread(
+ target=virt_http_server.http_server,
+ args=(self.unattended_server_port, self.tmpdir,
+ terminate_unattended_server_thread))
+ _unattended_server_thread.start()
+
+ # Point installation to this kickstart url
+ ks_param = 'ks=http://%s:%s/%s' % (self.url_auto_content_ip,
+ self.unattended_server_port,
+ dest_fname)
+ if 'ks=' in getattr(self, 'extra_params'):
+ extra_params = re.sub('ks\=[\w\d\:\.\/]+',
+ ks_param,
+ getattr(self, 'extra_params'))
+ else:
+ extra_params += ' %s ' % ks_param
+
+ # reflect change on params
+ self.extra_params = extra_params
+ self.params['extra_params'] = self.extra_params
+
+
def setup_boot_disk(self):
if self.unattended_file.endswith('.sif'):
dest_fname = 'winnt.sif'
@@ -522,30 +627,83 @@ class UnattendedInstallConfig(object):
utils.run(initrd_fetch_cmd)
if self.unattended_file.endswith('.preseed'):
self.preseed_initrd()
+ # Virtinstall command needs files named "vmlinuz" and "initrd.img"
+ elif self.params.get("vm_type") == "libvirt":
+ os.chdir(self.image_path)
+ base_kernel = os.path.basename(self.kernel)
+ base_initrd = os.path.basename(self.initrd)
+ utils.run("mv %s vmlinuz" % base_kernel)
+ utils.run("mv %s initrd.img" % base_initrd)
finally:
cleanup(self.cdrom_cd1_mount)
@error.context_aware
+ def setup_url_auto(self):
+ """
+ Configures the builtin web server for serving content
+ """
+ global _url_auto_content_server_thread
+ global _url_auto_content_server_thread_event
+
+ logging.debug("starting unattended content web server")
+
+ if self.params.get('cdrom_cd1'):
+ # setup and mount cdrom contents to be served by http server
+ m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' %
+ (self.cdrom_cd1, self.cdrom_cd1_mount))
+ utils.run(m_cmd)
+
+ self.url_auto_content_port = virt_utils.find_free_port(
+ 8000,
+ 8100,
+ self.url_auto_content_ip)
+
+ if _url_auto_content_server_thread is None:
+ _url_auto_content_server_thread_event = threading.Event()
+ _url_auto_content_server_thread = threading.Thread(
+ target=virt_http_server.http_server,
+ args=(self.url_auto_content_port, self.cdrom_cd1_mount,
+ terminate_auto_content_server_thread))
+ _url_auto_content_server_thread.start()
+
+ auto_content_url = 'http://%s:%s' % (self.url_auto_content_ip,
+ self.url_auto_content_port)
+ self.params['auto_content_url'] = auto_content_url
+
+
+ @error.context_aware
def setup_url(self):
"""
Download the vmlinuz and initrd.img from URL.
"""
- error.context("downloading vmlinuz and initrd.img from %s" % self.url)
- 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))
+ # it's only necessary to download kernel/initrd if running bare qemu
+ if self.vm_type == 'kvm':
+ error.context("downloading vmlinuz/initrd.img from %s" % self.url)
+ os.chdir(self.image_path)
+ kernel_cmd = "wget -q %s/%s/%s" % (self.url,
+ self.boot_path,
+ os.path.basename(self.kernel))
+ initrd_cmd = "wget -q %s/%s/%s" % (self.url,
+ self.boot_path,
+ os.path.basename(self.initrd))
- if os.path.exists(self.kernel):
- os.remove(self.kernel)
- if os.path.exists(self.initrd):
- os.remove(self.initrd)
+ if os.path.exists(self.kernel):
+ os.remove(self.kernel)
+ if os.path.exists(self.initrd):
+ os.remove(self.initrd)
- utils.run(kernel_fetch_cmd)
- utils.run(initrd_fetch_cmd)
+ utils.run(kernel_cmd)
+ utils.run(initrd_cmd)
+
+ elif self.vm_type == 'libvirt':
+ error.context("not downloading vmlinuz/initrd.img from %s, "
+ "letting virt-install do it instead")
+
+ else:
+ error.context("no action defined/needed for the current virt "
+ "type: '%s'" % self.vm_type)
def setup_nfs(self):
@@ -587,6 +745,9 @@ class UnattendedInstallConfig(object):
self.setup_cdrom()
elif self.medium == "url":
self.setup_url()
+ if self.url == 'auto':
+ self.setup_url_auto()
+ self.setup_unattended_http_server()
elif self.medium == "nfs":
self.setup_nfs()
else:
@@ -608,7 +769,10 @@ def run_unattended_install(test, params, env):
unattended_install_config = UnattendedInstallConfig(test, params)
unattended_install_config.setup()
vm = env.get_vm(params["main_vm"])
- vm.create()
+
+ # params passed explicitly, because they may have been updated by
+ # unattended install config code, such as when params['url'] == auto
+ vm.create(params=params)
install_timeout = int(params.get("timeout", 3000))
port = vm.get_port(int(params.get("guest_port_unattended_install")))
@@ -651,6 +815,22 @@ def run_unattended_install(test, params, env):
raise error.TestFail("Timeout elapsed while waiting for install to "
"finish")
+ logging.debug('cleaning up threads and mounts that may be active')
+ global _url_auto_content_server_thread
+ global _url_auto_content_server_thread_event
+ if _url_auto_content_server_thread is not None:
+ _url_auto_content_server_thread_event.set()
+ _url_auto_content_server_thread.join(3)
+ _url_auto_content_server_thread = None
+ cleanup(unattended_install_config.cdrom_cd1_mount)
+
+ global _unattended_server_thread
+ global _unattended_server_thread_event
+ if _unattended_server_thread is not None:
+ _unattended_server_thread_event.set()
+ _unattended_server_thread.join(3)
+ _unattended_server_thread = None
+
time_elapsed = time.time() - start_time
logging.info("Guest reported successful installation after %d s (%d min)",
time_elapsed, time_elapsed/60)
--
1.7.7
next prev parent reply other threads:[~2011-11-03 21:26 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-03 21:26 [PATCH 00/16] Libvirt test v5 Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 02/16] virt: Introducing virt_test.virt_test class Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 03/16] Moving unattended_install test from kvm test to common virt location Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 04/16] Moving get_started code to client.virt.virt_utils Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 05/16] virt: Introducing libvirt VM class Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 06/16] virt: Introducing libvirt monitor Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 07/16] virt.virt_env_process: Add libvirt vm handling Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 08/16] client.tests: Introducing libvirt test Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 09/16] Virt: builtin HTTP server for unattended installs Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 10/16] Virt: support XEN via libvirt and auto url installer Lucas Meneghel Rodrigues
2011-11-03 21:26 ` Lucas Meneghel Rodrigues [this message]
2011-11-03 21:26 ` [PATCH 12/16] Virt: small fixes related to libvirt unattended install when using auto url Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 13/16] Virt: pass verbatim hvm_or_pv option to virt_install Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 14/16] Virt: add sample configuration for XEN HVM domains Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 15/16] virt: Fix unattended install for libvirt case Lucas Meneghel Rodrigues
2011-11-03 21:26 ` [PATCH 16/16] Virt: adjust auto http servers (content/kickstart) ports to not overlap Lucas Meneghel Rodrigues
2011-11-04 3:57 ` [PATCH 00/16] Libvirt test v5 Lucas Meneghel Rodrigues
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1320355582-4342-12-git-send-email-lmr@redhat.com \
--to=lmr@redhat.com \
--cc=autotest@test.kernel.org \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.