This code was using the API equivalent of the virt-image tool, however it's really unnecessary here, all we are doing is importing an existing disk image which is an install option long provided by virt-install. Merge the functionality into the virtinstall module and convert it.
This code has actually been broken for about 6 months, since the start_install signature was never updated for the qemu_net_type change. Signed-off-by: Cole Robinson <[email protected]> --- koan/imagecreate.py | 171 ++------------------------------------------- koan/virtinstall.py | 47 +++++++++++-- tests/koan/virtinstall.py | 21 ++++++ 3 files changed, 67 insertions(+), 172 deletions(-) diff --git a/koan/imagecreate.py b/koan/imagecreate.py index c336dcb..cf4db36 100644 --- a/koan/imagecreate.py +++ b/koan/imagecreate.py @@ -23,170 +23,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA """ -import os, sys, time, stat -import shutil -import random -import exceptions -import errno -import virtinst -try: - from virtinst import ImageParser, Guest, CapabilitiesParser, VirtualNetworkInterface -except: - # if this fails, this is ok, the user just won't be able to use image objects... - # keeping this dynamic allows this to work on older EL. - pass -import libvirt +import utils +import virtinstall -import app as koan - -#FIXME this was copied -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 transform_arch(arch): - if arch == "i386": - return "i686" - else: - return arch - -def copy_image(original_file, new_location): - shutil.copyfile(original_file, new_location) - return new_location - - -def process_disk(image, boot, file, location, target): - image_location = copy_image(file, location) - # Create the disk - disk = ImageParser.Disk() - disk.format = "raw" - disk.file = image_location - disk.use = "user" - disk.id = image_location - image.storage[disk.id] = disk - - #Create the drive - drive = ImageParser.Drive() - drive.id = image_location - drive.target = target - drive.disk = disk - boot.disks.append(drive) - #dev api - #boot.drives.append(drive) - - -def process_networks(domain, guest, profile_data, bridge): - # Create a bridge or default network for every requested nic. If there are more - # bridges then nics discard the last one. - domain.interface = int(profile_data["network_count"]) - bridges = [] - #use the provided bridge first - guest_bridge = bridge - if guest_bridge is None: - guest_bridge = profile_data["virt_bridge"] - - # Look for commas - if (guest_bridge is not None) and (len(guest_bridge.strip()) > 0): - if guest_bridge.find(",") == -1: - bridges.append(guest_bridge) - else: - bridges == guest_bridge.split(",") - - for cnt in range(0,domain.interface): - if cnt < len(bridges): - nic = VirtualNetworkInterface(random_mac(), type="bridge", bridge = bridges[cnt]) - #dev api - #nic = VirtualNetworkInterface(random_mac(), type="bridge", bridge = bridge, conn=guest.conn) - else: - default_network = virtinst.util.default_network() - #dev api - #default_network = virtinst.util.default_network(guest.conn) - nic = VirtualNetworkInterface(random_mac(), type=default_network[0], network=default_network[1]) - guest.nics.append(nic) - -def start_install(name=None, - ram=None, - disks=None, - uuid=None, - extra=None, - vcpus=None, - profile_data=None, - arch=None, - no_gfx=False, - fullvirt=False, - bridge=None, - virt_type=None, - virt_auto_boot=False, - qemu_driver_type=None): - - #FIXME how to do a non-default connection - #Can we drive off of virt-type? - connection = None - - if (virt_type is None ) or (virt_type == "auto"): - connection = virtinst.util.default_connection() - elif virt_type.lower()[0:3] == "xen": - connection = "xen" - else: - connection = "qemu:///system" - - connection = libvirt.open(connection) - capabilities = virtinst.CapabilitiesParser.parse(connection.getCapabilities()) - image_arch = transform_arch(arch) - - image = ImageParser.Image() - #dev api - #image = ImageParser.Image(filename="") #FIXME, ImageParser should take in None - image.name = name - - domain = ImageParser.Domain() - domain.vcpu = vcpus - domain.memory = ram - image.domain = domain - - boot = ImageParser.Boot() - boot.type = "hvm" #FIXME HARDCODED - boot.loader = "hd" #FIXME HARDCODED - boot.arch = image_arch - domain.boots.append(boot) - - #FIXME Several issues. Single Disk, type is hardcoded - #And there is no way to provision with access to "file" - process_disk(image, boot, profile_data["file"], disks[0][0], "hda") - - #FIXME boot_index?? - installer = virtinst.ImageInstaller(boot_index = 0, image=image, capabilities=capabilities) - guest = virtinst.FullVirtGuest(connection = connection, installer=installer, arch=image_arch) - - extra = extra.replace("&","&") - - guest.extraargs = extra - guest.set_name(name) - guest.set_memory(ram) - guest.set_vcpus(vcpus) - - if not no_gfx: - guest.set_graphics("vnc") - else: - guest.set_graphics(False) - - if uuid is not None: - guest.set_uuid(uuid) - - process_networks(domain, guest, profile_data, bridge) - - guest.start_install() - - return "use virt-manager or reconnect with virsh console %s" % name - +def start_install(*args, **kwargs): + cmd = virtinstall.build_commandline("import", *args, **kwargs) + utils.subprocess_call(cmd) diff --git a/koan/virtinstall.py b/koan/virtinstall.py index a716d10..f7267a6 100755 --- a/koan/virtinstall.py +++ b/koan/virtinstall.py @@ -46,9 +46,19 @@ def _sanitize_disks(disks): return ret -def _sanitize_nics(nics, bridge, profile_bridge): +def _sanitize_nics(nics, bridge, profile_bridge, network_count): ret = [] + if network_count is not None and not nics: + # Fill in some stub nics so we can take advantage of the loop logic + nics = {} + for i in range(int(network_count)): + nics["foo%s" % i] = { + "interface_type" : "na", + "mac_address": None, + "virt_bridge": None, + } + if not nics: return ret @@ -103,6 +113,14 @@ def build_commandline(uri, qemu_driver_type=None, qemu_net_type=None): + is_import = uri.startswith("import") + if is_import: + # We use the special value 'import' for imagecreate.py. Since + # it is connection agnostic, just let virt-install choose the + # best hypervisor. + uri = "" + fullvirt = None + is_xen = uri.startswith("xen") is_qemu = uri.startswith("qemu") if is_qemu: @@ -111,8 +129,15 @@ def build_commandline(uri, floppy = None cdrom = None location = None + importpath = None - if profile_data.has_key("file"): + if is_import: + importpath = profile_data.get("file") + if not importpath: + raise koan.InfoException("Profile 'file' required for image " + "install") + + elif profile_data.has_key("file"): if is_xen: raise koan.InfoException("Xen does not work with --image yet") @@ -146,7 +171,8 @@ def build_commandline(uri, disks = _sanitize_disks(disks) nics = _sanitize_nics(profile_data.get("interfaces"), bridge, - profile_data.get("virt_bridge")) + profile_data.get("virt_bridge"), + profile_data.get("network_count")) if not nics: # for --profile you get one NIC, go define a system if you want more. # FIXME: can mac still be sent on command line in this case? @@ -172,7 +198,9 @@ def build_commandline(uri, net_model = qemu_net_type disk_bus = qemu_driver_type - cmd = "virt-install --connect %s " % uri + cmd = "virt-install " + if uri: + cmd += "--connect %s " % uri cmd += "--name %s " % name cmd += "--ram %s " % ram @@ -192,8 +220,9 @@ def build_commandline(uri, if is_qemu and virt_type: cmd += "--virt-type %s " % virt_type - if fullvirt or is_qemu: - cmd += "--hvm " + if fullvirt or is_qemu or is_import: + if fullvirt is not None: + cmd += "--hvm " if is_xen: cmd += "--pxe " @@ -201,6 +230,8 @@ def build_commandline(uri, cmd += "--cdrom %s " % cdrom elif location: cmd += "--location %s " % location + elif importpath: + cmd += "--import " if arch: cmd += "--arch %s " % arch @@ -221,6 +252,10 @@ def build_commandline(uri, cmd += "--os-type %s " % distro + if importpath: + # This needs to be the first disk for import to work + cmd += "--disk path=%s " % importpath + for path, size, driver_type in disks: print ("- adding disk: %s of size %s (driver type=%s)" % (path, size, driver_type)) diff --git a/tests/koan/virtinstall.py b/tests/koan/virtinstall.py index c57de1a..6898a10 100644 --- a/tests/koan/virtinstall.py +++ b/tests/koan/virtinstall.py @@ -105,3 +105,24 @@ class KoanVirtInstallTest(unittest.TestCase): "--disk path=/dev/foo1,bus=virtio " "--network bridge=br0,model=virtio --wait 0 --noautoconsole ") ) + + def testImage(self): + cmd = build_commandline("import", + name="foo", + ram=256, + vcpus=1, + fullvirt=True, + bridge="br0,br2", + disks=[], + qemu_driver_type="virtio", + qemu_net_type="virtio", + profile_data = { + "file" : "/some/install/image.img", + "network_count" : 2, + }) + + self.assertEquals(cmd, + ("virt-install --name foo --ram 256 --vcpus 1 --vnc --import " + "--disk path=/some/install/image.img --network bridge=br0 " + "--network bridge=br2 --wait 0 --noautoconsole ") + ) -- 1.7.7.5 _______________________________________________ cobbler mailing list [email protected] https://fedorahosted.org/mailman/listinfo/cobbler
