Pull out all the qcreate specific changes and merge them into the virtinstall module. Most of them are fixes that will apply to the generic code anyways, but were probably only tested/noticed with the qemu code.
Signed-off-by: Cole Robinson <[email protected]> --- koan/qcreate.py | 210 +------------------------------------------- koan/virtinstall.py | 86 +++++++++++++++++-- tests/koan/virtinstall.py | 50 +++++++++++ 3 files changed, 134 insertions(+), 212 deletions(-) diff --git a/koan/qcreate.py b/koan/qcreate.py index 493c40a..1de5143 100755 --- a/koan/qcreate.py +++ b/koan/qcreate.py @@ -1,5 +1,5 @@ """ -Virtualization installation functions. +Virtualization installation functions. Copyright 2007-2008 Red Hat, Inc. Michael DeHaan <[email protected]> @@ -23,209 +23,9 @@ module for creating fullvirt guests via KVM/kqemu/qemu requires python-virtinst-0.200. """ -import os, sys, time, stat -import tempfile -import random -from optparse import OptionParser -import exceptions -import errno -import re -import tempfile -import shutil -import virtinst -import app as koan -try: - import subprocess -except: - import sub_process as subprocess +import virtinstall import utils -def random_mac(): - """ - from xend/server/netif.py - Generate a random MAC address. - Uses OUI 00-16-3E, allocated to - Xensource, Inc. Last 3 fields are random. - return: MAC address string - """ - mac = [ 0x00, 0x16, 0x3e, - random.randint(0x00, 0x7f), - random.randint(0x00, 0xff), - random.randint(0x00, 0xff) ] - return ':'.join(map(lambda x: "%02x" % x, mac)) - - -def start_install(name=None, - ram=None, - disks=None, - mac=None, - uuid=None, - extra=None, - vcpus=None, - profile_data=None, - arch=None, - no_gfx=False, - fullvirt=True, - bridge=None, - virt_type=None, - virt_auto_boot=False, - qemu_driver_type=None, - qemu_net_type=None): - - vtype = "qemu" - if virtinst.util.is_kvm_capable(): - vtype = "kvm" - arch = None # let virtinst.FullVirtGuest() default to the host arch - elif virtinst.util.is_kqemu_capable(): - vtype = "kqemu" - print "- using qemu hypervisor, type=%s" % vtype - - if arch is not None and arch.lower() in ["x86","i386"]: - arch = "i686" - - guest = virtinst.FullVirtGuest(hypervisorURI="qemu:///system",type=vtype, arch=arch) - - if not profile_data.has_key("file"): - # images don't need to source this - if not profile_data.has_key("install_tree"): - raise koan.InfoException("Cannot find install source in kickstart file, aborting.") - - - if not profile_data["install_tree"].endswith("/"): - profile_data["install_tree"] = profile_data["install_tree"] + "/" - - # virt manager doesn't like nfs:// and just wants nfs: - # (which cobbler should fix anyway) - profile_data["install_tree"] = profile_data["install_tree"].replace("nfs://","nfs:") - - if profile_data.has_key("file"): - # this is an image based installation - input_path = profile_data["file"] - print "- using image location %s" % input_path - if input_path.find(":") == -1: - # this is not an NFS path - guest.cdrom = input_path - else: - (tempdir, filename) = utils.nfsmount(input_path) - guest.cdrom = os.path.join(tempdir, filename) - - kickstart = profile_data.get("kickstart","") - if kickstart != "": - # we have a (windows?) answer file we have to provide - # to the ISO. - print "I want to make a floppy for %s" % kickstart - floppy_path = utils.make_floppy(kickstart) - guest.disks.append(virtinst.VirtualDisk(device=virtinst.VirtualDisk.DEVICE_FLOPPY, path=floppy_path)) - - - else: - guest.location = profile_data["install_tree"] - - extra = extra.replace("&","&") - guest.extraargs = extra - - if profile_data.has_key("breed"): - breed = profile_data["breed"] - if breed != "other" and breed != "": - if breed in [ "ubuntu", "debian", "redhat" ]: - guest.set_os_type("linux") - elif breed == "suse": - guest.set_os_type("linux") - # SUSE requires the correct arch to find - # kernel+initrd on the inst-source /boot/<arch>/loader/... - guest.arch = profile_data["arch"] - if guest.arch in [ "i386", "i486", "i586" ]: - guest.arch = "i686" - elif breed in [ "windows" ]: - guest.set_os_type("windows") - else: - guest.set_os_type("unix") - if profile_data.has_key("os_version"): - # FIXME: when os_version is not defined and it's linux, do we use generic24/generic26 ? - if breed == "ubuntu": - # If breed is Ubuntu, need to set the version to the type of "ubuntu<version>" - # as defined by virtinst. (i.e. ubuntunatty) - version = "ubuntu%s" % profile_data["os_version"] - else: - version = profile_data["os_version"] - if version != "other" and version != "": - try: - guest.set_os_variant(version) - except: - print "- virtinst library does not understand variant %s, treating as generic" % version - pass - - guest.set_name(name) - guest.set_memory(ram) - guest.set_vcpus(vcpus) - guest.set_autostart(virt_auto_boot) - # for KVM, we actually can't disable this, since it's the only - # console it has other than SDL - guest.set_graphics("vnc") - - if uuid is not None: - guest.set_uuid(uuid) - - for d in disks: - print "- adding disk: %s of size %s (driver type=%s)" % (d[0], d[1], d[2]) - if d[1] != 0 or d[0].startswith("/dev"): - vdisk = virtinst.VirtualDisk(d[0], size=d[1], bus=qemu_driver_type) - try: - vdisk.set_driver_type(d[2]) - except: - print "- virtinst failed to create the VirtualDisk with the specified driver type (%s), using whatever it defaults to instead" % d[2] - guest.disks.append(vdisk) - else: - raise koan.InfoException("this virtualization type does not work without a disk image, set virt-size in Cobbler to non-zero") - - if profile_data.has_key("interfaces"): - - counter = 0 - interfaces = profile_data["interfaces"].keys() - interfaces.sort() - vlanpattern = re.compile("[a-zA-Z0-9]+\.[0-9]+") - for iname in interfaces: - intf = profile_data["interfaces"][iname] - - if intf["interface_type"] in ("master","bond","bridge") or vlanpattern.match(iname) or iname.find(":") != -1: - continue - - mac = intf["mac_address"] - if mac == "": - mac = random_mac() - - if bridge is None: - profile_bridge = profile_data["virt_bridge"] - - intf_bridge = intf["virt_bridge"] - if intf_bridge == "": - if profile_bridge == "": - raise koan.InfoException("virt-bridge setting is not defined in cobbler") - intf_bridge = profile_bridge - else: - if bridge.find(",") == -1: - intf_bridge = bridge - else: - bridges = bridge.split(",") - intf_bridge = bridges[counter] - nic_obj = virtinst.VirtualNetworkInterface(macaddr=mac, bridge=intf_bridge, model=qemu_net_type) - guest.nics.append(nic_obj) - counter = counter + 1 - - else: - - if bridge is not None: - profile_bridge = bridge - else: - profile_bridge = profile_data["virt_bridge"] - - if profile_bridge == "": - raise koan.InfoException("virt-bridge setting is not defined in cobbler") - - nic_obj = virtinst.VirtualNetworkInterface(macaddr=random_mac(), bridge=profile_bridge, model=qemu_net_type) - guest.nics.append(nic_obj) - - guest.start_install() - - return "use virt-manager and connect to qemu to manage guest: %s" % name - +def start_install(*args, **kwargs): + cmd = virtinstall.build_commandline("qemu:///system", *args, **kwargs) + utils.subprocess_call(cmd) diff --git a/koan/virtinstall.py b/koan/virtinstall.py index 5a56634..a716d10 100755 --- a/koan/virtinstall.py +++ b/koan/virtinstall.py @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA """ +import os import re import app as koan @@ -34,8 +35,12 @@ import utils def _sanitize_disks(disks): ret = [] for d in disks: + driver_type = None + if len(d) > 2: + driver_type = d[2] + if d[1] != 0 or d[0].startswith("/dev"): - ret.append((d[0], d[1])) + ret.append((d[0], d[1], driver_type)) else: raise koan.InfoException("this virtualization type does not work without a disk image, set virt-size in Cobbler to non-zero") @@ -81,7 +86,8 @@ def _sanitize_nics(nics, bridge, profile_bridge): return ret -def build_commandline(name=None, +def build_commandline(uri, + name=None, ram=None, disks=None, uuid=None, @@ -97,8 +103,45 @@ def build_commandline(name=None, qemu_driver_type=None, qemu_net_type=None): + is_xen = uri.startswith("xen") + is_qemu = uri.startswith("qemu") + if is_qemu: + fullvirt = True + + floppy = None + cdrom = None + location = None + if profile_data.has_key("file"): - raise koan.InfoException("Xen does not work with --image yet") + if is_xen: + raise koan.InfoException("Xen does not work with --image yet") + + # this is an image based installation + input_path = profile_data["file"] + print "- using image location %s" % input_path + if input_path.find(":") == -1: + # this is not an NFS path + cdrom = input_path + else: + (tempdir, filename) = utils.nfsmount(input_path) + cdrom = os.path.join(tempdir, filename) + + kickstart = profile_data.get("kickstart","") + if kickstart != "": + # we have a (windows?) answer file we have to provide + # to the ISO. + print "I want to make a floppy for %s" % kickstart + floppy = utils.make_floppy(kickstart) + elif is_qemu: + # images don't need to source this + if not profile_data.has_key("install_tree"): + raise koan.InfoException("Cannot find install source in kickstart file, aborting.") + + if not profile_data["install_tree"].endswith("/"): + profile_data["install_tree"] = profile_data["install_tree"] + "/" + + location = profile_data["install_tree"] + disks = _sanitize_disks(disks) nics = _sanitize_nics(profile_data.get("interfaces"), @@ -120,8 +163,16 @@ def build_commandline(name=None, initrd = profile_data.get("initrd_local") breed = profile_data.get("breed") os_version = profile_data.get("os_version") + if os_version and breed == "ubuntu": + os_version = "ubuntu%s" % os_version + + net_model = None + disk_bus = None + if is_qemu: + net_model = qemu_net_type + disk_bus = qemu_driver_type - cmd = "virt-install --connect xen:/// " + cmd = "virt-install --connect %s " % uri cmd += "--name %s " % name cmd += "--ram %s " % ram @@ -138,9 +189,19 @@ def build_commandline(name=None, else: cmd += "--vnc " - if fullvirt: + if is_qemu and virt_type: + cmd += "--virt-type %s " % virt_type + + if fullvirt or is_qemu: cmd += "--hvm " - cmd += "--pxe " + if is_xen: + cmd += "--pxe " + + elif cdrom: + cmd += "--cdrom %s " % cdrom + elif location: + cmd += "--location %s " % location + if arch: cmd += "--arch %s " % arch else: @@ -160,16 +221,27 @@ def build_commandline(name=None, cmd += "--os-type %s " % distro - for path, size in disks: + for path, size, driver_type in disks: + print ("- adding disk: %s of size %s (driver type=%s)" % + (path, size, driver_type)) cmd += "--disk path=%s" % (path) if str(size) != "0": cmd += ",size=%s" % size + if disk_bus: + cmd += ",bus=%s" % disk_bus + if driver_type: + cmd += ",driver_type=%s" % driver_type cmd += " " + if floppy: + cmd += "--disk path=%s,device=floppy " % floppy + for bridge, mac in nics: cmd += "--network bridge=%s" % bridge if mac: cmd += ",mac=%s" % mac + if net_model: + cmd += ",model=%s" % net_model cmd += " " cmd += "--wait 0 " diff --git a/tests/koan/virtinstall.py b/tests/koan/virtinstall.py index cff0f2e..c57de1a 100644 --- a/tests/koan/virtinstall.py +++ b/tests/koan/virtinstall.py @@ -11,6 +11,8 @@ class KoanVirtInstallTest(unittest.TestCase): vcpus=1, bridge="br0", disks=[("/tmp/foo1.img", 8), ("/dev/foo1", 0)], + qemu_driver_type="virtio", + qemu_net_type="virtio", profile_data={ "kernel_local" : "kernel", "initrd_local" : "initrd", @@ -55,3 +57,51 @@ class KoanVirtInstallTest(unittest.TestCase): "--network bridge=br0,mac=11:22:33:44:55:66 " "--network bridge=br1,mac=11:22:33:33:22:11 " "--wait 0 --noautoconsole ")) + + def testQemuCDROM(self): + cmd = build_commandline("qemu:///system", + name="foo", + ram=256, + vcpus=1, + disks=[("/tmp/foo1.img", 8), ("/dev/foo1", 0)], + fullvirt=True, + bridge="br0", + profile_data = { + "breed" : "windows", + "file" : "/some/cdrom/path.iso", + }) + + self.assertEquals(cmd, + ("virt-install --connect qemu:///system --name foo --ram 256 " + "--vcpus 1 --vnc --hvm --cdrom /some/cdrom/path.iso " + "--os-type windows --disk path=/tmp/foo1.img,size=8 " + "--disk path=/dev/foo1 --network bridge=br0 " + "--wait 0 --noautoconsole ") + ) + + def testQemuURL(self): + cmd = build_commandline("qemu:///system", + name="foo", + ram=256, + vcpus=1, + disks=[("/tmp/foo1.img", 8), ("/dev/foo1", 0)], + fullvirt=True, + arch="i686", + bridge="br0", + qemu_driver_type="virtio", + qemu_net_type="virtio", + profile_data = { + "breed" : "ubuntu", + "os_version" : "natty", + "install_tree" : "http://example.com/some/install/tree", + }) + + self.assertEquals(cmd, + ("virt-install --connect qemu:///system --name foo --ram 256 " + "--vcpus 1 --vnc --hvm " + "--location http://example.com/some/install/tree/ --arch i686 " + "--os-variant ubuntunatty " + "--disk path=/tmp/foo1.img,size=8,bus=virtio " + "--disk path=/dev/foo1,bus=virtio " + "--network bridge=br0,model=virtio --wait 0 --noautoconsole ") + ) -- 1.7.7.5 _______________________________________________ cobbler mailing list [email protected] https://fedorahosted.org/mailman/listinfo/cobbler
