We break out the virt-install logic to a separate file, since further
conversions are going to be able to share 90% of the code (basically
the whole point of libvirt :) ).

In the process we drop a lot of hacks and workarounds for things that
have been fixed in virtinst for at least a year, some for as long as
3. The required virtinst dep is fairly recent anyways with the
call to guest.set_autostart.

Signed-off-by: Cole Robinson <[email protected]>
---
 koan/virtinstall.py       |  182 +++++++++++++++++++++++++++++++++++++++++++++
 koan/xencreate.py         |  173 ++-----------------------------------------
 tests/koan/__init__.py    |    1 +
 tests/koan/virtinstall.py |   57 ++++++++++++++
 4 files changed, 246 insertions(+), 167 deletions(-)
 create mode 100755 koan/virtinstall.py
 create mode 100644 tests/koan/virtinstall.py

diff --git a/koan/virtinstall.py b/koan/virtinstall.py
new file mode 100755
index 0000000..5a56634
--- /dev/null
+++ b/koan/virtinstall.py
@@ -0,0 +1,182 @@
+"""
+Virtualization installation functions.
+Currently somewhat Xen/paravirt specific, will evolve later.
+
+Copyright 2006-2008 Red Hat, Inc.
+Michael DeHaan <[email protected]>
+
+Original version based on virtguest-install
+Jeremy Katz <[email protected]>
+Option handling added by Andrew Puch <[email protected]>
+Simplified for use as library by koan, Michael DeHaan <[email protected]>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301  USA
+"""
+
+import re
+
+import app as koan
+import utils
+
+def _sanitize_disks(disks):
+    ret = []
+    for d in disks:
+        if d[1] != 0 or d[0].startswith("/dev"):
+            ret.append((d[0], d[1]))
+        else:
+            raise koan.InfoException("this virtualization type does not work 
without a disk image, set virt-size in Cobbler to non-zero")
+
+    return ret
+
+def _sanitize_nics(nics, bridge, profile_bridge):
+    ret = []
+
+    if not nics:
+        return ret
+
+    interfaces = nics.keys()
+    interfaces.sort()
+    counter = -1
+    vlanpattern = re.compile("[a-zA-Z0-9]+\.[0-9]+")
+
+    for iname in interfaces:
+        counter = counter + 1
+        intf = nics[iname]
+
+        if (intf["interface_type"] in ("master","bond","bridge") or
+            vlanpattern.match(iname) or iname.find(":") != -1):
+            continue
+
+        mac = intf["mac_address"]
+
+        if not 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]
+
+        ret.append((intf_bridge, mac))
+
+    return ret
+
+
+def build_commandline(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,
+                      qemu_net_type=None):
+
+    if profile_data.has_key("file"):
+        raise koan.InfoException("Xen does not work with --image yet")
+
+    disks = _sanitize_disks(disks)
+    nics = _sanitize_nics(profile_data.get("interfaces"),
+                          bridge,
+                          profile_data.get("virt_bridge"))
+    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?
+
+        if bridge is None:
+            bridge = profile_data["virt_bridge"]
+
+        if bridge == "":
+            raise koan.InfoException("virt-bridge setting is not defined in 
cobbler")
+        nics = [(bridge, None)]
+
+
+    kernel = profile_data.get("kernel_local")
+    initrd = profile_data.get("initrd_local")
+    breed = profile_data.get("breed")
+    os_version = profile_data.get("os_version")
+
+    cmd = "virt-install --connect xen:/// "
+
+    cmd += "--name %s " % name
+    cmd += "--ram %s " % ram
+    cmd += "--vcpus %s " % vcpus
+
+    if uuid:
+        cmd += "--uuid %s " % uuid
+
+    if virt_auto_boot:
+        cmd += "--autostart "
+
+    if no_gfx:
+        cmd += "--nographics "
+    else:
+        cmd += "--vnc "
+
+    if fullvirt:
+        cmd += "--hvm "
+        cmd += "--pxe "
+        if arch:
+            cmd += "--arch %s " % arch
+    else:
+        cmd += "--paravirt "
+        cmd += ("--boot kernel=%s,initrd=%s,kernel_args=%s " %
+                (kernel, initrd, extra))
+
+    if breed and breed != "other":
+        if os_version and os_version != "other":
+            cmd += "--os-variant %s " % os_version
+        else:
+            distro = "unix"
+            if breed in [ "debian", "suse", "redhat" ]:
+                distro = "linux"
+            elif breed in [ "windows" ]:
+                distro = "windows"
+
+            cmd += "--os-type %s " % distro
+
+    for path, size in disks:
+        cmd += "--disk path=%s" % (path)
+        if str(size) != "0":
+            cmd += ",size=%s" % size
+        cmd += " "
+
+    for bridge, mac in nics:
+        cmd += "--network bridge=%s" % bridge
+        if mac:
+            cmd += ",mac=%s" % mac
+        cmd += " "
+
+    cmd += "--wait 0 "
+    cmd += "--noautoconsole "
+
+    return cmd
+
+def start_install(*args, **kwargs):
+    cmd = build_commandline(*args, **kwargs)
+    utils.subprocess_call(cmd)
diff --git a/koan/xencreate.py b/koan/xencreate.py
index 50178a3..6279fe7 100755
--- a/koan/xencreate.py
+++ b/koan/xencreate.py
@@ -1,5 +1,5 @@
 """
-Virtualization installation functions.  
+Virtualization installation functions.
 Currently somewhat Xen/paravirt specific, will evolve later.
 
 Copyright 2006-2008 Red Hat, Inc.
@@ -26,170 +26,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
MA
 02110-1301  USA
 """
 
-import os, sys, time, stat
-import tempfile
-import random
-import exceptions
-import errno
-import re
-import virtinst
-import app as koan
+import utils
+import virtinstall
 
-try:
-    import virtinst.DistroInstaller as DistroManager
-except:
-    # older virtinst, this is probably ok
-    # but we know we can't do Xen fullvirt installs
-    pass
-import traceback
-
-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,
-                  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,
-                  qemu_net_type=None):
-
-    if profile_data.has_key("file"):
-        raise koan.InfoException("Xen does not work with --image yet")
-
-    if fullvirt:
-        # FIXME: add error handling here to explain when it's not supported
-        guest = virtinst.FullVirtGuest(installer=virtinst.PXEInstaller())
-    else:
-        guest = virtinst.ParaVirtGuest()
-
-    extra = extra.replace("&","&amp;")
-
-    if not fullvirt:
-        guest.set_boot((profile_data["kernel_local"], 
profile_data["initrd_local"]))
-        # fullvirt OS's will get this from the PXE config (managed by Cobbler)
-        guest.extraargs = extra
-    else:
-        print "- fullvirt mode"
-        if profile_data.has_key("breed"):
-            breed = profile_data["breed"]
-            if breed != "other" and breed != "":
-                if breed in [ "debian", "suse", "redhat" ]:
-                    guest.set_os_type("linux")
-                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 ?
-                    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)
-
-    if not no_gfx:
-        guest.set_graphics("vnc")
-    else:
-        guest.set_graphics(False)
-
-    if uuid is not None:
-        guest.set_uuid(uuid)
-
-    for d in disks:
-        if d[1] != 0 or d[0].startswith("/dev"):
-            guest.disks.append(virtinst.XenDisk(d[0], size=d[1]))
-        else:
-            raise koan.InfoException("this virtualization type does not work 
without a disk image, set virt-size in Cobbler to non-zero")
-
-    counter = 0
-
-    if profile_data.has_key("interfaces"):
-
-        interfaces = profile_data["interfaces"].keys()
-        interfaces.sort()
-        counter = -1
-        vlanpattern = re.compile("[a-zA-Z0-9]+\.[0-9]+")
-
-        for iname in interfaces:
-            counter = counter + 1
-            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 not bridge:
-                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.XenNetworkInterface(macaddr=mac, 
bridge=intf_bridge)
-            guest.nics.append(nic_obj)
-            counter = counter + 1
-   
-    else:
-            # for --profile you just get one NIC, go define a system if you 
want more.
-            # FIXME: can mac still be sent on command line in this case?
-
-            if bridge is None:
-                profile_bridge = profile_data["virt_bridge"]
-            else:
-                profile_bridge = bridge
-
-            if profile_bridge == "":
-                raise koan.InfoException("virt-bridge setting is not defined 
in cobbler")
-
-            nic_obj = virtinst.XenNetworkInterface(macaddr=random_mac(), 
bridge=profile_bridge)
-            guest.nics.append(nic_obj)
-            
-        
-
-
-    guest.start_install()
-    
-    return "use virt-manager or reconnect with virsh console %s" % name 
-     
+def start_install(*args, **kwargs):
+    cmd = virtinstall.build_commandline("xen:///", *args, **kwargs)
+    utils.subprocess_call(cmd)
diff --git a/tests/koan/__init__.py b/tests/koan/__init__.py
index e69de29..370e90e 100644
--- a/tests/koan/__init__.py
+++ b/tests/koan/__init__.py
@@ -0,0 +1 @@
+import virtinstall
diff --git a/tests/koan/virtinstall.py b/tests/koan/virtinstall.py
new file mode 100644
index 0000000..cff0f2e
--- /dev/null
+++ b/tests/koan/virtinstall.py
@@ -0,0 +1,57 @@
+import unittest
+
+from koan.virtinstall import build_commandline
+
+class KoanVirtInstallTest(unittest.TestCase):
+    def testXenPVBasic(self):
+        cmd = build_commandline("xen:///",
+            name="foo",
+            ram=256,
+            uuid="ad6611b9-98e4-82c8-827f-051b6b6680d7",
+            vcpus=1,
+            bridge="br0",
+            disks=[("/tmp/foo1.img", 8), ("/dev/foo1", 0)],
+            profile_data={
+                "kernel_local" : "kernel",
+                "initrd_local" : "initrd",
+            },
+            extra="ks=http://example.com/ks.ks";)
+
+        self.assertEquals(cmd,
+            ("virt-install --connect xen:/// --name foo --ram 256 --vcpus 1 "
+             "--uuid ad6611b9-98e4-82c8-827f-051b6b6680d7 --vnc --paravirt "
+             "--boot 
kernel=kernel,initrd=initrd,kernel_args=ks=http://example.com/ks.ks "
+             "--disk path=/tmp/foo1.img,size=8 --disk path=/dev/foo1 "
+             "--network bridge=br0 "
+             "--wait 0 --noautoconsole "))
+
+    def testXenFVBasic(self):
+        cmd = build_commandline("xen:///",
+            name="foo",
+            ram=256,
+            vcpus=1,
+            disks=[("/dev/foo1", 0)],
+            fullvirt=True,
+            arch="x86_64",
+            bridge="br0,br1",
+            profile_data = {
+                "breed" : "redhat",
+                "os_version" : "fedora14",
+                "interfaces" : {
+                    "eth0": {
+                        "interface_type": "na",
+                        "mac_address": "11:22:33:44:55:66",
+                    }, "eth1": {
+                        "interface_type": "na",
+                        "mac_address": "11:22:33:33:22:11",
+                    }
+                }
+            })
+
+        self.assertEquals(cmd,
+            ("virt-install --connect xen:/// --name foo --ram 256 --vcpus 1 "
+             "--vnc --hvm --pxe --arch x86_64 "
+             "--os-variant fedora14 --disk path=/dev/foo1 "
+             "--network bridge=br0,mac=11:22:33:44:55:66 "
+             "--network bridge=br1,mac=11:22:33:33:22:11 "
+             "--wait 0 --noautoconsole "))
-- 
1.7.7.5

_______________________________________________
cobbler mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/cobbler

Reply via email to