[PATCH] Port utility functions to Solaris

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



# HG changeset patch
# User john.levon@xxxxxxx
# Date 1228851891 28800
# Node ID 29d8886362e2993eaf26cf8d4e948b2de4b8d9ec
# Parent  3a48e2d3594b3e7e1d24147f3325ab6024557504
Port utility functions to Solaris

Create _util.py for private details of the implementation, along with a
shim for back compatibility.

Port the utilities to Solaris.

Signed-off-by: John Levon <john.levon@xxxxxxx>

diff --git a/virtinst/CloneManager.py b/virtinst/CloneManager.py
--- a/virtinst/CloneManager.py
+++ b/virtinst/CloneManager.py
@@ -23,7 +23,7 @@ import libxml2
 import libxml2
 import logging
 import urlgrabber.progress as progress
-import util
+import _util
 import libvirt
 import Guest
 from VirtualDisk import VirtualDisk
@@ -263,7 +263,7 @@ class CloneDesign(object):
             node[0].setContent(self._clone_uuid)
         else:
             while 1:
-                uuid = util.uuidToString(util.randomUUID())
+                uuid = _util.uuidToString(_util.randomUUID())
                 if self._check_uuid(uuid) == True:
                     continue
                 else:
@@ -278,7 +278,7 @@ class CloneDesign(object):
                 node[0].setContent(self._clone_mac[i-1])
             except Exception:
                 while 1:
-                    mac = util.randomMAC(typ)
+                    mac = _util.randomMAC(typ)
                     dummy, msg = self._check_mac(mac)
                     if msg is not None:
                         continue
@@ -396,7 +396,7 @@ class CloneDesign(object):
         for i in lst:
             mode = os.stat(i)[stat.ST_MODE]
             if stat.S_ISBLK(mode):
-                size.append(util.blkdev_size(i))
+                size.append(_util.blkdev_size(i))
                 typ.append(False)
             elif stat.S_ISREG(mode):
                 size.append(os.path.getsize(i))
@@ -450,7 +450,7 @@ class CloneDesign(object):
                 continue
             mode = os.stat(i)[stat.ST_MODE]
             if stat.S_ISBLK(mode):
-                size.append(util.blkdev_size(i))
+                size.append(_util.blkdev_size(i))
                 typ.append(False)
             elif stat.S_ISREG(mode):
                 size.append(os.path.getsize(i))
diff --git a/virtinst/DistroManager.py b/virtinst/DistroManager.py
--- a/virtinst/DistroManager.py
+++ b/virtinst/DistroManager.py
@@ -22,7 +22,7 @@
 
 import logging
 import os
-import util
+import _util
 import Guest
 from VirtualDisk import VirtualDisk
 from virtinst import _virtinst as _
@@ -158,7 +158,7 @@ class DistroInstaller(Guest.Installer):
             logging.debug("DistroInstaller location is a (poolname, volname)"
                           " tuple")
         elif os.path.exists(os.path.abspath(val)) \
-             and (not self.conn or not util.is_uri_remote(self.conn.getURI())):
+             and (not self.conn or not _util.is_uri_remote(self.conn.getURI())):
             val = os.path.abspath(val)
             logging.debug("DistroInstaller location is a local "
                           "file/path: %s" % val)
@@ -178,8 +178,8 @@ class DistroInstaller(Guest.Installer):
         elif (val.startswith("http://";) or val.startswith("ftp://";) or
               val.startswith("nfs:")):
             logging.debug("DistroInstaller location is a network source.")
-        elif self.conn and util.is_storage_capable(self.conn) and \
-             util.is_uri_remote(self.conn.getURI()):
+        elif self.conn and _util.is_storage_capable(self.conn) and \
+             _util.is_uri_remote(self.conn.getURI()):
             # If conn is specified, pass the path to a VirtualDisk object
             # and see what comes back
             try:
@@ -193,7 +193,7 @@ class DistroInstaller(Guest.Installer):
                                "or FTP network install source, or an existing "
                                "local file/device"))
 
-        if val.startswith("nfs:") and not util.privileged_user():
+        if val.startswith("nfs:") and not _util.privileged_user():
             raise ValueError(_("NFS installations are only supported as root"))
 
         self._location = val
diff --git a/virtinst/FullVirtGuest.py b/virtinst/FullVirtGuest.py
--- a/virtinst/FullVirtGuest.py
+++ b/virtinst/FullVirtGuest.py
@@ -20,7 +20,7 @@
 # MA 02110-1301 USA.
 
 import os
-import util
+import _util
 import DistroManager
 import logging
 import time
@@ -38,7 +38,8 @@ class FullVirtGuest(Guest):
             installer = DistroManager.DistroInstaller(type = type, os_type = "hvm")
         Guest.__init__(self, type, connection, hypervisorURI, installer)
         self.disknode = "hd"
-        self.features = { "acpi": None, "pae": util.is_pae_capable(), "apic": None }
+        self.features = { "acpi": None, "pae":
+            _util.is_pae_capable(connection), "apic": None }
         if arch is None:
             arch = platform.machine()
         self.arch = arch
diff --git a/virtinst/Guest.py b/virtinst/Guest.py
--- a/virtinst/Guest.py
+++ b/virtinst/Guest.py
@@ -26,7 +26,7 @@ import re
 import re
 import libxml2
 import urlgrabber.progress as progress
-import util
+import _util
 import libvirt
 import platform
 import __builtin__
@@ -131,7 +131,7 @@ class VirtualNetworkInterface(VirtualDev
                 logging.warn("conflict_net: Failed to lookup domain %d" % name)
 
         # get the Host's NIC MACaddress
-        hostdevs = util.get_host_network_devices()
+        hostdevs = _util.get_host_network_devices()
 
         if self.countMACaddr(vms) > 0:
             return (True, _("The MAC address you entered is already in use by another active virtual machine."))
@@ -145,7 +145,7 @@ class VirtualNetworkInterface(VirtualDev
     def setup(self, conn):
         if self.macaddr is None:
             while 1:
-                self.macaddr = util.randomMAC(type=conn.getType().lower())
+                self.macaddr = _util.randomMAC(type=conn.getType().lower())
                 if self.is_conflict_net(conn)[1] is not None:
                     continue
                 else:
@@ -159,7 +159,7 @@ class VirtualNetworkInterface(VirtualDev
                     raise RuntimeError(msg)
 
         if not self.bridge and self.type == "bridge":
-            self.bridge = util.default_bridge()
+            self.bridge = _util.default_bridge()
 
     def get_xml_config(self):
         src_xml = ""
@@ -192,7 +192,7 @@ class VirtualNetworkInterface(VirtualDev
             try:
                 for mac in ctx.xpathEval("/domain/devices/interface/mac"):
                     macaddr = mac.xpathEval("attribute::address")[0].content
-                    if macaddr and util.compareMAC(self.macaddr, macaddr) == 0:
+                    if macaddr and _util.compareMAC(self.macaddr, macaddr) == 0:
                         count += 1
             finally:
                 if ctx is not None:
@@ -250,7 +250,7 @@ class VirtualGraphics(object):
         return self._keymap
     def set_keymap(self, val):
         if not val:
-            val = util.default_keymap()
+            val = _util.default_keymap()
         if not val or type(val) != type("string"):
             raise ValueError, _("Keymap must be a string")
         if len(val) > 16:
@@ -352,7 +352,7 @@ class Installer(object):
             return '/var/tmp'
         if self.type == "xen" and os.path.exists(XEN_SCRATCH):
             return XEN_SCRATCH
-        if util.privileged_user() and os.path.exists(LIBVIRT_SCRATCH):
+        if _util.privileged_user() and os.path.exists(LIBVIRT_SCRATCH):
             return LIBVIRT_SCRATCH
         else:
             return os.path.expanduser("~/.virtinst/boot")
@@ -407,7 +407,7 @@ class Installer(object):
                            conn=None, kernel=None, bootdev=None):
         osblob = ""
         if not isinstall and not ishvm:
-            return "<bootloader>%s</bootloader>" % util.pygrub_path(conn)
+            return "<bootloader>%s</bootloader>" % _util.pygrub_path(conn)
 
         osblob = "<os>\n"
 
@@ -425,9 +425,9 @@ class Installer(object):
             osblob += "    <loader>%s</loader>\n" % loader
 
         if isinstall and kernel and kernel["kernel"]:
-            osblob += "    <kernel>%s</kernel>\n"   % util.xml_escape(kernel["kernel"])
-            osblob += "    <initrd>%s</initrd>\n"   % util.xml_escape(kernel["initrd"])
-            osblob += "    <cmdline>%s</cmdline>\n" % util.xml_escape(kernel["extraargs"])
+            osblob += "    <kernel>%s</kernel>\n"   % _util.xml_escape(kernel["kernel"])
+            osblob += "    <initrd>%s</initrd>\n"   % _util.xml_escape(kernel["initrd"])
+            osblob += "    <cmdline>%s</cmdline>\n" % _util.xml_escape(kernel["extraargs"])
         elif bootdev is not None:
             osblob += "    <boot dev='%s'/>\n" % bootdev
 
@@ -466,7 +466,7 @@ class Installer(object):
         @type L{Guest}
         """
 
-        if util.is_uri_remote(guest.conn.getURI()):
+        if _util.is_uri_remote(guest.conn.getURI()):
             # XXX: Use block peek for this?
             return True
 
@@ -479,7 +479,7 @@ class Installer(object):
             fd = os.open(guest.disks[0].path, os.O_RDONLY)
         except OSError, (err, msg):
             logging.debug("Failed to open guest disk: %s" % msg)
-            if err == errno.EACCES and not util.privileged_user():
+            if err == errno.EACCES and not _util.privileged_user():
                 return True # non root might not have access to block devices
             else:
                 raise
@@ -624,7 +624,7 @@ class Guest(object):
     def get_vcpus(self):
         return self._vcpus
     def set_vcpus(self, val):
-        maxvcpus = util.get_max_vcpus(self.conn, self.type)
+        maxvcpus = _util.get_max_vcpus(self.conn, self.type)
         if type(val) is not int or val < 1:
             raise ValueError, _("Number of vcpus must be a postive integer.")
         if val > maxvcpus:
@@ -642,7 +642,7 @@ class Guest(object):
         if re.match("^[0-9,-]*$", val) is None:
             raise ValueError, _("cpuset can only contain numeric, ',', or '-' characters")
 
-        pcpus = util.get_phy_cpus(self.conn)
+        pcpus = _util.get_phy_cpus(self.conn)
         for c in val.split(','):
             if c.find('-') != -1:
                 (x, y) = c.split('-')
@@ -1061,7 +1061,7 @@ class Guest(object):
     def _set_defaults(self):
         if self.uuid is None:
             while 1:
-                self.uuid = util.uuidToString(util.randomUUID())
+                self.uuid = _util.uuidToString(_util.randomUUID())
                 try:
                     if self.conn.lookupByUUIDString(self.uuid) is not None:
                         continue
diff --git a/virtinst/ImageManager.py b/virtinst/ImageManager.py
--- a/virtinst/ImageManager.py
+++ b/virtinst/ImageManager.py
@@ -23,7 +23,7 @@ import CapabilitiesParser as Cap
 import CapabilitiesParser as Cap
 from VirtualDisk import VirtualDisk
 import os
-import util
+import _util
 from virtinst import _virtinst as _
 
 class ImageInstallerException(Exception):
@@ -101,7 +101,7 @@ class ImageInstaller(Guest.Installer):
             d = VirtualDisk(p, s,
                             device = device,
                             type = VirtualDisk.TYPE_FILE)
-            if self.boot_caps.type == "xen" and util.is_blktap_capable():
+            if self.boot_caps.type == "xen" and _util.is_blktap_capable():
                 d.driver_name = VirtualDisk.DRIVER_TAP
             d.target = m.target
 
@@ -127,9 +127,9 @@ class ImageInstaller(Guest.Installer):
         if loader:
             osblob += "    <loader>%s</loader>\n" % loader
         if self.boot_caps.kernel:
-            osblob += "    <kernel>%s</kernel>\n"   % util.xml_escape(self._abspath(self.boot_caps.kernel))
-            osblob += "    <initrd>%s</initrd>\n"   % util.xml_escape(self._abspath(self.boot_caps.initrd))
-            osblob += "    <cmdline>%s</cmdline>\n" % util.xml_escape(self.boot_caps.cmdline)
+            osblob += "    <kernel>%s</kernel>\n"   % _util.xml_escape(self._abspath(self.boot_caps.kernel))
+            osblob += "    <initrd>%s</initrd>\n"   % _util.xml_escape(self._abspath(self.boot_caps.initrd))
+            osblob += "    <cmdline>%s</cmdline>\n" % _util.xml_escape(self.boot_caps.cmdline)
             osblob += "  </os>"
         elif hvm:
             if self.boot_caps.bootdev:
@@ -137,7 +137,7 @@ class ImageInstaller(Guest.Installer):
             osblob += "  </os>"
         elif self.boot_caps.loader == "pygrub" or (self.boot_caps.loader is None and self.boot_caps.type == "xen"):
             osblob += "  </os>\n"
-            osblob += "  <bootloader>%s</bootloader>" % util.pygrub_path(conn)
+            osblob += "  <bootloader>%s</bootloader>" % _util.pygrub_path(conn)
 
         return osblob
 
diff --git a/virtinst/Storage.py b/virtinst/Storage.py
--- a/virtinst/Storage.py
+++ b/virtinst/Storage.py
@@ -52,7 +52,7 @@ import logging
 import logging
 from xml.sax.saxutils import escape
 
-import util
+import _util
 from virtinst import _virtinst as _
 
 DEFAULT_DEV_TARGET = "/dev"
@@ -112,7 +112,7 @@ class StorageObject(object):
     def set_conn(self, val):
         if not isinstance(val, libvirt.virConnect):
             raise ValueError(_("'conn' must be a libvirt connection object."))
-        if not util.is_storage_capable(val):
+        if not _util.is_storage_capable(val):
             raise ValueError(_("Passed connection is not libvirt storage "
                                "capable"))
         self._conn = val
@@ -278,7 +278,7 @@ class StoragePool(StorageObject):
         self._source_path = None
         if not uuid:
             self._uuid = None
-        self._random_uuid = util.uuidToString(util.randomUUID())
+        self._random_uuid = _util.uuidToString(_util.randomUUID())
 
     # Properties used by all pools
     def get_type(self):
@@ -705,7 +705,7 @@ class StorageVolume(StorageObject):
         pool_object = StorageVolume.lookup_pool_by_name(pool_object=pool_object,
                                                         pool_name=pool_name,
                                                         conn=conn)
-        return StoragePool.get_volume_for_pool(util.get_xml_path(pool_object.XMLDesc(0), "/pool/@type"))
+        return StoragePool.get_volume_for_pool(_util.get_xml_path(pool_object.XMLDesc(0), "/pool/@type"))
     get_volume_for_pool = staticmethod(get_volume_for_pool)
 
     def find_free_name(name, pool_object=None, pool_name=None, conn=None,
@@ -756,7 +756,7 @@ class StorageVolume(StorageObject):
         if pool_name is not None and pool_object is None:
             if conn is None:
                 raise ValueError(_("'conn' must be specified with 'pool_name'"))
-            if not util.is_storage_capable(conn):
+            if not _util.is_storage_capable(conn):
                 raise ValueError(_("Connection does not support storage "
                                    "management."))
             try:
diff --git a/virtinst/VirtualDevice.py b/virtinst/VirtualDevice.py
--- a/virtinst/VirtualDevice.py
+++ b/virtinst/VirtualDevice.py
@@ -22,7 +22,7 @@ import libvirt
 import libvirt
 
 import CapabilitiesParser
-import util
+import _util
 from virtinst import _virtinst as _
 
 class VirtualDevice(object):
@@ -45,7 +45,7 @@ class VirtualDevice(object):
 
         self.__remote = None
         if self.conn:
-            self.__remote = util.is_uri_remote(self.conn.getURI())
+            self.__remote = _util.is_uri_remote(self.conn.getURI())
 
         self._caps = None
         if self.conn:
diff --git a/virtinst/VirtualDisk.py b/virtinst/VirtualDisk.py
--- a/virtinst/VirtualDisk.py
+++ b/virtinst/VirtualDisk.py
@@ -24,7 +24,7 @@ import logging
 import logging
 import libvirt
 
-import util
+import _util
 import Storage
 from VirtualDevice import VirtualDevice
 from virtinst import _virtinst as _
@@ -302,7 +302,7 @@ class VirtualDisk(VirtualDevice):
                                "('poolname', 'volname')"))
         if not self.conn:
             raise ValueError(_("'volName' requires a passed connection."))
-        if not util.is_storage_capable(self.conn):
+        if not _util.is_storage_capable(self.conn):
             raise ValueError(_("Connection does not support storage lookup."))
         try:
             pool = self.conn.storagePoolLookupByName(name_tuple[0])
@@ -321,7 +321,7 @@ class VirtualDisk(VirtualDevice):
     def __check_if_path_managed(self):
         vol = None
         verr = None
-        pool = util.lookup_pool_by_path(self.conn,
+        pool = _util.lookup_pool_by_path(self.conn,
                                         os.path.dirname(self.path))
         if pool:
             try:
@@ -378,7 +378,7 @@ class VirtualDisk(VirtualDevice):
         # if no obj: if remote, error
         storage_capable = False
         if self.conn:
-            storage_capable = util.is_storage_capable(self.conn)
+            storage_capable = _util.is_storage_capable(self.conn)
         if not storage_capable and self._is_remote():
             raise ValueError, _("Connection doesn't support remote storage.")
 
@@ -528,7 +528,7 @@ class VirtualDisk(VirtualDevice):
         elif self.path:
             path = self.path
         if path:
-            path = util.xml_escape(path)
+            path = _util.xml_escape(path)
 
         ret = "    <disk type='%(type)s' device='%(device)s'>\n" % { "type": self.type, "device": self.device }
         if not(self.driver_name is None):
diff --git a/virtinst/_util.py b/virtinst/_util.py
new file mode 100644
--- /dev/null
+++ b/virtinst/_util.py
@@ -0,0 +1,543 @@
+#
+# Utility functions used for guest installation
+#
+# Copyright 2006  Red Hat, Inc.
+# Jeremy Katz <katzj@xxxxxxxxxx>
+#
+# 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 platform
+import random
+import os.path
+import re
+import libxml2
+import logging
+import subprocess
+from sys import stderr
+
+import libvirt
+from virtinst import _virtinst as _
+from virtinst import CapabilitiesParser
+
+
+KEYBOARD_DIR = "/etc/sysconfig/keyboard"
+XORG_CONF = "/etc/X11/xorg.conf"
+
+def default_route(nic = None):
+    if platform.system() == 'SunOS':
+        cmd = [ '/usr/bin/netstat', '-rn' ]
+        if nic:
+            cmd += [ '-I', nic ]
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE)
+        for line in proc.stdout.readlines():
+            vals = line.split()
+            if len(vals) > 1 and vals[0] == 'default':
+                return vals[1]
+        return None
+
+    route_file = "/proc/net/route"
+    d = file(route_file)
+
+    defn = 0
+    for line in d.xreadlines():
+        info = line.split()
+        if (len(info) != 11): # 11 = typical num of fields in the file
+            print >> stderr, _("Invalid line length while parsing %s.") %(route_file)
+            print >> stderr, _("Defaulting bridge to xenbr%d") % (defn)
+            break
+        try:
+            route = int(info[1],16)
+            if route == 0:
+                return info[0]
+        except ValueError:
+            continue
+    return None
+
+def default_nic():
+    """Return the default NIC to use, if one is specified."""
+
+    dev = ''
+
+    if platform.system() != 'SunOS':
+        return dev
+
+    # XXX: fails without PRIV_XVM_CONTROL
+    proc = subprocess.Popen(['/usr/lib/xen/bin/xenstore-read',
+        'device-misc/vif/default-nic'], stdout=subprocess.PIPE,
+        stderr=subprocess.PIPE)
+    out = proc.stdout.readlines()
+    if len(out) > 0:
+        dev = out[0].rstrip()
+
+    return dev
+
+def default_bridge():
+    if platform.system() == 'SunOS':
+        return default_nic()
+
+    rt = default_route()
+    if rt is None:
+        defn = None
+    else:
+        defn = int(rt[-1])
+
+    if defn is None:
+        return "xenbr0"
+    else:
+        return "xenbr%d"%(defn)
+
+def default_network(conn):
+    if platform.system() == 'SunOS':
+        return ["bridge", default_nic()]
+
+    dev = default_route()
+
+    if dev is not None and not is_uri_remote(conn.getURI()):
+        # New style peth0 == phys dev, eth0 == bridge, eth0 == default route
+        if os.path.exists("/sys/class/net/%s/bridge" % dev):
+            return ["bridge", dev]
+
+        # Old style, peth0 == phys dev, eth0 == netloop, xenbr0 == bridge,
+        # vif0.0 == netloop enslaved, eth0 == default route
+        defn = int(dev[-1])
+        if os.path.exists("/sys/class/net/peth%d/brport" % defn) and \
+           os.path.exists("/sys/class/net/xenbr%d/bridge" % defn):
+            return ["bridge", "xenbr%d" % defn]
+
+    return ["network", "default"]
+
+def default_connection():
+    if os.path.exists('/var/lib/xend'):
+        if os.path.exists('/dev/xen/evtchn'):
+            return 'xen' 
+        if os.path.exists("/proc/xen"):
+            return 'xen' 
+
+    if os.path.exists("/usr/bin/qemu") or \
+         os.path.exists("/usr/bin/qemu-kvm") or \
+         os.path.exists("/usr/bin/kvm") or \
+         os.path.exists("/usr/bin/xenner"):
+        if privileged_user():
+            return "qemu:///system"
+        else:
+            return "qemu:///session"
+    return None
+
+def get_cpu_flags():
+    if platform.system() == 'SunOS':
+        raise OSError("CPU flags not available")
+
+    f = open("/proc/cpuinfo")
+    lines = f.readlines()
+    f.close()
+    for line in lines:
+        if not line.startswith("flags"):
+            continue
+        # get the actual flags
+        flags = line[:-1].split(":", 1)[1]
+        # and split them
+        flst = flags.split(" ")
+        return flst
+    return []
+
+def is_pae_capable(conn=None):
+    """Determine if a machine is PAE capable or not."""
+    if not conn:
+        conn = libvirt.open('')
+    return "pae" in conn.getCapabilities()
+
+def is_blktap_capable():
+    if platform.system() == 'SunOS':
+        return False
+
+    f = open("/proc/modules")
+    lines = f.readlines()
+    f.close()
+    for line in lines:
+        if line.startswith("blktap ") or line.startswith("xenblktap "):
+            return True
+    return False
+
+def get_default_arch():
+    arch = os.uname()[4]
+    if arch == "x86_64":
+        return "x86_64"
+    return "i686"
+
+# this function is directly from xend/server/netif.py and is thus
+# available under the LGPL,
+# Copyright 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright 2005 XenSource Ltd
+def randomMAC(type = "xen"):
+    """Generate a random MAC address.
+
+    00-16-3E allocated to xensource
+    54-52-00 used by qemu/kvm
+
+    The OUI list is available at http://standards.ieee.org/regauth/oui/oui.txt.
+
+    The remaining 3 fields are random, with the first bit of the first
+    random field set 0.
+
+    >>> randomMAC().startswith("00:16:36")
+    True
+    >>> randomMAC("foobar").startswith("00:16:36")
+    True
+    >>> randomMAC("xen").startswith("00:16:36")
+    True
+    >>> randomMAC("qemu").startswith("54:52:00")
+    True
+
+    @return: MAC address string
+    """
+    ouis = { 'xen': [ 0x00, 0x16, 0x36 ], 'qemu': [ 0x54, 0x52, 0x00 ] }
+
+    try:
+        oui = ouis[type]
+    except KeyError:
+        oui = ouis['xen']
+
+    mac = oui + [
+            random.randint(0x00, 0x7f),
+            random.randint(0x00, 0xff),
+            random.randint(0x00, 0xff) ]
+    return ':'.join(map(lambda x: "%02x" % x, mac))
+
+# the following three functions are from xend/uuid.py and are thus
+# available under the LGPL,
+# Copyright 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright 2005 XenSource Ltd
+def randomUUID():
+    """Generate a random UUID."""
+
+    return [ random.randint(0, 255) for dummy in range(0, 16) ]
+
+def uuidToString(u):
+    return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2,
+                     "%02x" * 6]) % tuple(u)
+
+def uuidFromString(s):
+    s = s.replace('-', '')
+    return [ int(s[i : i + 2], 16) for i in range(0, 32, 2) ]
+
+# the following function quotes from python2.5/uuid.py
+def get_host_network_devices():
+    device = []
+    for dirname in ['', '/sbin/', '/usr/sbin']:
+        executable = os.path.join(dirname, "ifconfig")
+        if not os.path.exists(executable):
+            continue
+        try:
+            cmd = 'LC_ALL=C %s -a 2>/dev/null' % (executable)
+            pipe = os.popen(cmd)
+        except IOError:
+            continue
+        for line in pipe:
+            if line.find("encap:Ethernet") > 0:
+                words = line.lower().split()
+                for i in range(len(words)):
+                    if words[i] == "hwaddr":
+                        device.append(words)
+    return device
+
+def get_max_vcpus(conn, type=None):
+    """@conn libvirt connection to poll for max possible vcpus
+       @type optional guest type (kvm, etc.)"""
+    if type is None:
+        type = conn.getType()
+    try:
+        m = conn.getMaxVcpus(type.lower())
+    except libvirt.libvirtError:
+        m = 32
+    return m
+
+def get_phy_cpus(conn):
+    """Get number of physical CPUs."""
+    hostinfo = conn.getInfo()
+    pcpus = hostinfo[4] * hostinfo[5] * hostinfo[6] * hostinfo[7]
+    return pcpus
+
+def xml_escape(str):
+    """Replaces chars ' " < > & with xml safe counterparts"""
+    str = str.replace("&", "&amp;")
+    str = str.replace("'", "&apos;")
+    str = str.replace("\"", "&quot;")
+    str = str.replace("<", "&lt;")
+    str = str.replace(">", "&gt;")
+    return str
+ 
+def blkdev_size(path):
+    """Return the size of the block device.  We can't use os.stat() as
+    that returns zero on many platforms."""
+    fd = os.open(path, os.O_RDONLY)
+    # os.SEEK_END is not present on all systems
+    size = os.lseek(fd, 0, 2)
+    os.close(fd)
+    return size
+
+def compareMAC(p, q):
+    """Compare two MAC addresses"""
+    pa = p.split(":")
+    qa = q.split(":")
+
+    if len(pa) != len(qa):
+        if p > q:
+            return 1
+        else:
+            return -1
+
+    for i in xrange(len(pa)):
+        n = int(pa[i], 0x10) - int(qa[i], 0x10)
+        if n > 0:
+            return 1
+        elif n < 0:
+            return -1
+    return 0
+
+def _xorg_keymap():
+    """Look in /etc/X11/xorg.conf for the host machine's keymap, and attempt to
+       map it to a keymap supported by qemu"""
+
+    kt = None
+    try:
+        f = open(XORG_CONF, "r")
+    except IOError, e:
+        logging.debug('Could not open "%s": %s ' % (XORG_CONF, str(e)))
+    else:
+        keymap_re = re.compile(r'\s*Option\s+"XkbLayout"\s+"(?P<kt>[a-z-]+)"')
+        for line in f:
+            m = keymap_re.match(line)
+            if m:
+                kt = m.group('kt')
+                break
+        else:
+            logging.debug("Didn't find keymap in '%s'!" % XORG_CONF)
+        f.close()
+    return kt
+
+def default_keymap():
+    """Look in /etc/sysconfig for the host machine's keymap, and attempt to
+       map it to a keymap supported by qemu"""
+
+    # Set keymap to same as hosts
+    import keytable
+    keymap = "en-us"
+    kt = None
+    try:
+        f = open(KEYBOARD_DIR, "r")
+    except IOError, e:
+        logging.debug('Could not open "/etc/sysconfig/keyboard" ' + str(e))
+        kt = _xorg_keymap()
+    else:
+        while 1:
+            s = f.readline()
+            if s == "":
+                break
+            if re.search("KEYTABLE", s) != None or \
+               (re.search("KEYBOARD", s) != None and
+                re.search("KEYBOARDTYPE", s) == None):
+                if s.count('"'):
+                    delim = '"'
+                elif s.count('='):
+                    delim = '='
+                else:
+                    continue
+                kt = s.split(delim)[1].strip()
+        f.close()
+
+    if kt and keytable.keytable.has_key(kt.lower()):
+        keymap = keytable.keytable[kt]
+    else:
+        logging.debug("Didn't find keymap '%s' in keytable!" % kt)
+    return keymap
+
+def pygrub_path(conn=None):
+    """
+    Return the pygrub path for the current host, or connection if
+    available.
+    """
+    # FIXME: This should be removed/deprecated when capabilities are
+    #        fixed to provide bootloader info
+    if conn:
+        cap = CapabilitiesParser.parse(conn.getCapabilities())
+        if (cap.host.arch == "i86pc"):
+            return "/usr/lib/xen/bin/pygrub"
+        else:
+            return "/usr/bin/pygrub"
+
+    if platform.system() == "SunOS":
+        return "/usr/lib/xen/bin/pygrub"
+    return "/usr/bin/pygrub"
+
+def uri_split(uri):
+    """
+    Parse a libvirt hypervisor uri into it's individual parts
+    @returns: tuple of the form (scheme (ex. 'qemu', 'xen+ssh'), username,
+                                 hostname, path (ex. '/system'), query,
+                                 fragment)
+    """
+    def splitnetloc(url, start=0):
+        for c in '/?#': # the order is important!
+            delim = url.find(c, start)
+            if delim >= 0:
+                break
+        else:
+            delim = len(url)
+        return url[start:delim], url[delim:]
+
+    username = netloc = query = fragment = ''
+    i = uri.find(":")
+    if i > 0:
+        scheme, uri = uri[:i].lower(), uri[i+1:]
+        if uri[:2] == '//':
+            netloc, uri = splitnetloc(uri, 2)
+            offset = netloc.find("@")
+            if offset > 0:
+                username = netloc[0:offset]
+                netloc = netloc[offset+1:]
+        if '#' in uri:
+            uri, fragment = uri.split('#', 1)
+        if '?' in uri:
+            uri, query = uri.split('?', 1)
+    else:
+        scheme = uri.lower()
+    return scheme, username, netloc, uri, query, fragment
+
+
+def is_uri_remote(uri):
+    try:
+        split_uri = uri_split(uri)
+        netloc = split_uri[2]
+
+        if netloc == "":
+            return False
+        return True
+    except Exception, e:
+        logging.exception("Error parsing URI in is_remote: %s" % e)
+        return True
+
+def get_uri_hostname(uri):
+    try:
+        split_uri = uri_split(uri)
+        netloc = split_uri[2]
+
+        if netloc != "":
+            return netloc
+    except Exception, e:
+        logging.warning("Cannot parse URI %s: %s" % (uri, str(e)))
+    return "localhost"
+
+def get_uri_transport(uri):
+    try:
+        split_uri = uri_split(uri)
+        scheme = split_uri[0]
+        username = split_uri[1]
+
+        if scheme:
+            offset = scheme.index("+")
+            if offset > 0:
+                return [scheme[offset+1:], username]
+    except:
+        pass
+    return [None, None]
+
+def get_uri_driver(uri):
+    try:
+        split_uri = uri_split(uri)
+        scheme = split_uri[0]
+
+        if scheme:
+            offset = scheme.find("+")
+            if offset > 0:
+                return scheme[:offset]
+            return scheme
+    except Exception:
+        pass
+    return "xen"
+
+def is_storage_capable(conn):
+    """check if virConnectPtr passed has storage API support"""
+    if not conn:
+        return False
+    if not isinstance(conn, libvirt.virConnect):
+        raise ValueError(_("'conn' must be a virConnect instance."))
+    try:
+        if not dir(conn).count("listStoragePools"):
+            return False
+        conn.listStoragePools()
+    except libvirt.libvirtError, e:
+        if e.get_error_code() == libvirt.VIR_ERR_RPC or \
+           e.get_error_code() == libvirt.VIR_ERR_NO_SUPPORT:
+            return False
+    return True
+
+def get_xml_path(xml, path):
+    """return the xpath from the passed xml"""
+    doc = None
+    ctx = None
+    result = None
+    try:
+        doc = libxml2.parseDoc(xml)
+        ctx = doc.xpathNewContext()
+        ret = ctx.xpathEval(path)
+        val = None
+        if ret != None:
+            if type(ret) == list:
+                if len(ret) == 1:
+                    val = ret[0].content
+            else:
+                val = ret
+        result = val
+    finally:
+        if doc:
+            doc.freeDoc()
+        if ctx:
+            ctx.xpathFreeContext()
+    return result
+
+def lookup_pool_by_path(conn, path):
+    """
+    Return the first pool with matching matching target path.
+    return the first we find, active or inactive. This iterates over
+    all pools and dumps their xml, so it is NOT quick.
+    @return virStoragePool object if found, None otherwise
+    """
+    if not is_storage_capable(conn):
+        return None
+
+    pool_list = conn.listStoragePools() + conn.listDefinedStoragePools()
+    for name in pool_list:
+        pool = conn.storagePoolLookupByName(name)
+        xml_path = get_xml_path(pool.XMLDesc(0), "/pool/target/path")
+        if os.path.abspath(xml_path) == path:
+            return pool
+    return None
+
+def privileged_user():
+    """
+    Return true if the user is privileged enough.  On Linux, this
+    equates to being root.  On Solaris, it's more complicated, so we
+    just assume we're OK.
+    """
+    return os.uname()[0] == 'SunOS' or os.geteuid() == 0
+
+def _test():
+    import doctest
+    doctest.testmod()
+ 
+if __name__ == "__main__":
+    _test()
diff --git a/virtinst/cli.py b/virtinst/cli.py
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -26,7 +26,7 @@ from optparse import OptionValueError, O
 from optparse import OptionValueError, OptionParser
 
 import libvirt
-import util
+import _util
 from virtinst import CapabilitiesParser, VirtualNetworkInterface, \
                      VirtualGraphics, VirtualAudio
 from virtinst import _virtinst as _
@@ -118,7 +118,7 @@ def nice_exit():
 
 def getConnection(connect):
     if connect and connect.lower()[0:3] == "xen":
-        if not util.privileged_user():
+        if not _util.privileged_user():
             fail(_("Must be root to create Xen guests"))
     if connect is None:
         fail(_("Could not find usable default libvirt connection."))
@@ -298,8 +298,8 @@ def digest_networks(conn, macs, bridges,
     # With just one mac, create a default network if one is not
     # specified.
     if len(macs) == 1 and len(networks) == 0:
-        if util.privileged_user():
-            net = util.default_network(conn)
+        if _util.privileged_user():
+            net = _util.default_network(conn)
             networks.append(net[0] + ":" + net[1])
         else:
             networks.append("user")
@@ -316,8 +316,8 @@ def digest_networks(conn, macs, bridges,
     # Create extra networks up to the number of nics requested 
     if len(macs) < nics:
         for dummy in range(len(macs),nics):
-            if util.privileged_user():
-                net = util.default_network(conn)
+            if _util.privileged_user():
+                net = _util.default_network(conn)
                 networks.append(net[0] + ":" + net[1])
             else:
                 networks.append("user")
diff --git a/virtinst/util.py b/virtinst/util.py
--- a/virtinst/util.py
+++ b/virtinst/util.py
@@ -1,5 +1,3 @@
-#
-# Utility functions used for guest installation
 #
 # Copyright 2006  Red Hat, Inc.
 # Jeremy Katz <katzj@xxxxxxxxxx>
@@ -19,107 +17,60 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA 02110-1301 USA.
 
+#
+# WARNING: this file sadly forms part of the public API. Do not add
+# anything to this file! The file for internal utility functions is
+# _util.py
+#
+
 import platform
-import random
-import os.path
-import re
-import libxml2
-import logging
-from sys import stderr
+import os
 
-import libvirt
-from virtinst import _virtinst as _
-from virtinst import CapabilitiesParser
+from virtinst import _util
 
 
 KEYBOARD_DIR = "/etc/sysconfig/keyboard"
 XORG_CONF = "/etc/X11/xorg.conf"
 
-def default_route():
-    route_file = "/proc/net/route"
-    d = file(route_file)
+default_route = _util.default_route
+default_bridge = _util.default_bridge
+default_network = _util.default_network
+default_connection = _util.default_connection
+get_cpu_flags = _util.get_cpu_flags
+is_pae_capable = _util.is_pae_capable
+is_blktap_capable = _util.is_blktap_capable
+get_default_arch = _util.get_default_arch
+randomMAC = _util.randomMAC
+randomUUID = _util.randomUUID
+uuidToString = _util.uuidToString
+uuidFromString = _util.uuidFromString
+get_host_network_devices = _util.get_host_network_devices
+get_max_vcpus = _util.get_max_vcpus
+get_phy_cpus = _util.get_phy_cpus
+xml_escape = _util.xml_escape
+compareMAC = _util.compareMAC
+default_keymap = _util.default_keymap
+pygrub_path = _util.pygrub_path
+uri_split = _util.uri_split
+is_uri_remote = _util.is_uri_remote
+get_uri_hostname = _util.get_uri_hostname
+get_uri_transport = _util.get_uri_transport
+get_uri_driver = _util.get_uri_driver
+is_storage_capable = _util.is_storage_capable
+get_xml_path = _util.get_xml_path
+lookup_pool_by_path = _util.lookup_pool_by_path
+privileged_user = _util.privileged_user
 
-    defn = 0
-    for line in d.xreadlines():
-        info = line.split()
-        if (len(info) != 11): # 11 = typical num of fields in the file
-            print >> stderr, _("Invalid line length while parsing %s.") %(route_file)
-            print >> stderr, _("Defaulting bridge to xenbr%d") % (defn)
-            break
-        try:
-            route = int(info[1],16)
-            if route == 0:
-                return info[0]
-        except ValueError:
-            continue
-    return None
-
-# Legacy for compat only.
-def default_bridge():
-    rt = default_route()
-    if rt is None:
-        defn = None
-    else:
-        defn = int(rt[-1])
-
-    if defn is None:
-        return "xenbr0"
-    else:
-        return "xenbr%d"%(defn)
-
-def default_network(conn):
-    dev = default_route()
-
-    if dev is not None and not is_uri_remote(conn.getURI()):
-        # New style peth0 == phys dev, eth0 == bridge, eth0 == default route
-        if os.path.exists("/sys/class/net/%s/bridge" % dev):
-            return ["bridge", dev]
-
-        # Old style, peth0 == phys dev, eth0 == netloop, xenbr0 == bridge,
-        # vif0.0 == netloop enslaved, eth0 == default route
-        defn = int(dev[-1])
-        if os.path.exists("/sys/class/net/peth%d/brport" % defn) and \
-           os.path.exists("/sys/class/net/xenbr%d/bridge" % defn):
-            return ["bridge", "xenbr%d" % defn]
-
-    return ["network", "default"]
-
-def default_connection():
-    if os.path.exists("/var/lib/xend") and os.path.exists("/proc/xen"):
-        return "xen"
-    elif os.path.exists("/usr/bin/qemu") or \
-         os.path.exists("/usr/bin/qemu-kvm") or \
-         os.path.exists("/usr/bin/kvm") or \
-         os.path.exists("/usr/bin/xenner"):
-        if privileged_user():
-            return "qemu:///system"
-        else:
-            return "qemu:///session"
-    return None
-
-def get_cpu_flags():
-    f = open("/proc/cpuinfo")
-    lines = f.readlines()
-    f.close()
-    for line in lines:
-        if not line.startswith("flags"):
-            continue
-        # get the actual flags
-        flags = line[:-1].split(":", 1)[1]
-        # and split them
-        flst = flags.split(" ")
-        return flst
-    return []
-
-def is_pae_capable():
-    """Determine if a machine is PAE capable or not."""
-    flags = get_cpu_flags()
-    if "pae" in flags:
-        return True
-    return False
+def system(cmd):
+    st = os.system(cmd)
+    if os.WIFEXITED(st) and os.WEXITSTATUS(st) != 0:
+        raise OSError("Failed to run %s, exited with %d" % 
+                      (cmd, os.WEXITSTATUS(st)))
 
 def is_hvm_capable():
     """Determine if a machine is HVM capable or not."""
+    if platform.system() == 'SunOS':
+        raise OSError("CPU flags not available")
 
     caps = ""
     if os.path.exists("/sys/hypervisor/properties/capabilities"):
@@ -133,389 +84,3 @@ def is_kqemu_capable():
 
 def is_kvm_capable():
     return os.path.exists("/dev/kvm")
-
-def is_blktap_capable():
-    #return os.path.exists("/dev/xen/blktapctrl")
-    f = open("/proc/modules")
-    lines = f.readlines()
-    f.close()
-    for line in lines:
-        if line.startswith("blktap ") or line.startswith("xenblktap "):
-            return True
-    return False
-
-def get_default_arch():
-    arch = os.uname()[4]
-    if arch == "x86_64":
-        return "x86_64"
-    return "i686"
-
-# this function is directly from xend/server/netif.py and is thus
-# available under the LGPL,
-# Copyright 2004, 2005 Mike Wray <mike.wray@xxxxxx>
-# Copyright 2005 XenSource Ltd
-def randomMAC(type = "xen"):
-    """Generate a random MAC address.
-
-    00-16-3E allocated to xensource
-    54-52-00 used by qemu/kvm
-
-    The OUI list is available at http://standards.ieee.org/regauth/oui/oui.txt.
-
-    The remaining 3 fields are random, with the first bit of the first
-    random field set 0.
-
-    >>> randomMAC().startswith("00:16:36")
-    True
-    >>> randomMAC("foobar").startswith("00:16:36")
-    True
-    >>> randomMAC("xen").startswith("00:16:36")
-    True
-    >>> randomMAC("qemu").startswith("54:52:00")
-    True
-
-    @return: MAC address string
-    """
-    ouis = { 'xen': [ 0x00, 0x16, 0x36 ], 'qemu': [ 0x54, 0x52, 0x00 ] }
-
-    try:
-        oui = ouis[type]
-    except KeyError:
-        oui = ouis['xen']
-
-    mac = oui + [
-            random.randint(0x00, 0x7f),
-            random.randint(0x00, 0xff),
-            random.randint(0x00, 0xff) ]
-    return ':'.join(map(lambda x: "%02x" % x, mac))
-
-# the following three functions are from xend/uuid.py and are thus
-# available under the LGPL,
-# Copyright 2005 Mike Wray <mike.wray@xxxxxx>
-# Copyright 2005 XenSource Ltd
-def randomUUID():
-    """Generate a random UUID."""
-
-    return [ random.randint(0, 255) for dummy in range(0, 16) ]
-
-def uuidToString(u):
-    return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2,
-                     "%02x" * 6]) % tuple(u)
-
-def uuidFromString(s):
-    s = s.replace('-', '')
-    return [ int(s[i : i + 2], 16) for i in range(0, 32, 2) ]
-
-# the following function quotes from python2.5/uuid.py
-def get_host_network_devices():
-    device = []
-    for dirname in ['', '/sbin/', '/usr/sbin']:
-        executable = os.path.join(dirname, "ifconfig")
-        if not os.path.exists(executable):
-            continue
-        try:
-            cmd = 'LC_ALL=C %s -a 2>/dev/null' % (executable)
-            pipe = os.popen(cmd)
-        except IOError:
-            continue
-        for line in pipe:
-            if line.find("encap:Ethernet") > 0:
-                words = line.lower().split()
-                for i in range(len(words)):
-                    if words[i] == "hwaddr":
-                        device.append(words)
-    return device
-
-def get_max_vcpus(conn, type=None):
-    """@conn libvirt connection to poll for max possible vcpus
-       @type optional guest type (kvm, etc.)"""
-    if type is None:
-        type = conn.getType()
-    try:
-        m = conn.getMaxVcpus(type.lower())
-    except libvirt.libvirtError:
-        m = 32
-    return m
-
-def get_phy_cpus(conn):
-    """Get number of physical CPUs."""
-    hostinfo = conn.getInfo()
-    pcpus = hostinfo[4] * hostinfo[5] * hostinfo[6] * hostinfo[7]
-    return pcpus
-
-def system(cmd):
-    st = os.system(cmd)
-    if os.WIFEXITED(st) and os.WEXITSTATUS(st) != 0:
-        raise OSError("Failed to run %s, exited with %d" % 
-                      (cmd, os.WEXITSTATUS(st)))
-
-def xml_escape(str):
-    """Replaces chars ' " < > & with xml safe counterparts"""
-    str = str.replace("&", "&amp;")
-    str = str.replace("'", "&apos;")
-    str = str.replace("\"", "&quot;")
-    str = str.replace("<", "&lt;")
-    str = str.replace(">", "&gt;")
-    return str
- 
-def blkdev_size(path):
-    """Return the size of the block device.  We can't use os.stat() as
-    that returns zero on many platforms."""
-    fd = os.open(path, os.O_RDONLY)
-    # os.SEEK_END is not present on all systems
-    size = os.lseek(fd, 0, 2)
-    os.close(fd)
-    return size
-
-def compareMAC(p, q):
-    """Compare two MAC addresses"""
-    pa = p.split(":")
-    qa = q.split(":")
-
-    if len(pa) != len(qa):
-        if p > q:
-            return 1
-        else:
-            return -1
-
-    for i in xrange(len(pa)):
-        n = int(pa[i], 0x10) - int(qa[i], 0x10)
-        if n > 0:
-            return 1
-        elif n < 0:
-            return -1
-    return 0
-
-def _xorg_keymap():
-    """Look in /etc/X11/xorg.conf for the host machine's keymap, and attempt to
-       map it to a keymap supported by qemu"""
-
-    kt = None
-    try:
-        f = open(XORG_CONF, "r")
-    except IOError, e:
-        logging.debug('Could not open "%s": %s ' % (XORG_CONF, str(e)))
-    else:
-        keymap_re = re.compile(r'\s*Option\s+"XkbLayout"\s+"(?P<kt>[a-z-]+)"')
-        for line in f:
-            m = keymap_re.match(line)
-            if m:
-                kt = m.group('kt')
-                break
-        else:
-            logging.debug("Didn't find keymap in '%s'!" % XORG_CONF)
-        f.close()
-    return kt
-
-def default_keymap():
-    """Look in /etc/sysconfig for the host machine's keymap, and attempt to
-       map it to a keymap supported by qemu"""
-
-    # Set keymap to same as hosts
-    import keytable
-    keymap = "en-us"
-    kt = None
-    try:
-        f = open(KEYBOARD_DIR, "r")
-    except IOError, e:
-        logging.debug('Could not open "/etc/sysconfig/keyboard" ' + str(e))
-        kt = _xorg_keymap()
-    else:
-        while 1:
-            s = f.readline()
-            if s == "":
-                break
-            if re.search("KEYTABLE", s) != None or \
-               (re.search("KEYBOARD", s) != None and
-                re.search("KEYBOARDTYPE", s) == None):
-                if s.count('"'):
-                    delim = '"'
-                elif s.count('='):
-                    delim = '='
-                else:
-                    continue
-                kt = s.split(delim)[1].strip()
-        f.close()
-
-    if kt and keytable.keytable.has_key(kt.lower()):
-        keymap = keytable.keytable[kt]
-    else:
-        logging.debug("Didn't find keymap '%s' in keytable!" % kt)
-    return keymap
-
-def pygrub_path(conn=None):
-    """
-    Return the pygrub path for the current host, or connection if
-    available.
-    """
-    # FIXME: This should be removed/deprecated when capabilities are
-    #        fixed to provide bootloader info
-    if conn:
-        cap = CapabilitiesParser.parse(conn.getCapabilities())
-        if (cap.host.arch == "i86pc"):
-            return "/usr/lib/xen/bin/pygrub"
-        else:
-            return "/usr/bin/pygrub"
-
-    if platform.system() == "SunOS":
-        return "/usr/lib/xen/bin/pygrub"
-    return "/usr/bin/pygrub"
-
-def uri_split(uri):
-    """
-    Parse a libvirt hypervisor uri into it's individual parts
-    @returns: tuple of the form (scheme (ex. 'qemu', 'xen+ssh'), username,
-                                 hostname, path (ex. '/system'), query,
-                                 fragment)
-    """
-    def splitnetloc(url, start=0):
-        for c in '/?#': # the order is important!
-            delim = url.find(c, start)
-            if delim >= 0:
-                break
-        else:
-            delim = len(url)
-        return url[start:delim], url[delim:]
-
-    username = netloc = query = fragment = ''
-    i = uri.find(":")
-    if i > 0:
-        scheme, uri = uri[:i].lower(), uri[i+1:]
-        if uri[:2] == '//':
-            netloc, uri = splitnetloc(uri, 2)
-            offset = netloc.find("@")
-            if offset > 0:
-                username = netloc[0:offset]
-                netloc = netloc[offset+1:]
-        if '#' in uri:
-            uri, fragment = uri.split('#', 1)
-        if '?' in uri:
-            uri, query = uri.split('?', 1)
-    else:
-        scheme = uri.lower()
-    return scheme, username, netloc, uri, query, fragment
-
-
-def is_uri_remote(uri):
-    try:
-        split_uri = uri_split(uri)
-        netloc = split_uri[2]
-
-        if netloc == "":
-            return False
-        return True
-    except Exception, e:
-        logging.exception("Error parsing URI in is_remote: %s" % e)
-        return True
-
-def get_uri_hostname(uri):
-    try:
-        split_uri = uri_split(uri)
-        netloc = split_uri[2]
-
-        if netloc != "":
-            return netloc
-    except Exception, e:
-        logging.warning("Cannot parse URI %s: %s" % (uri, str(e)))
-    return "localhost"
-
-def get_uri_transport(uri):
-    try:
-        split_uri = uri_split(uri)
-        scheme = split_uri[0]
-        username = split_uri[1]
-
-        if scheme:
-            offset = scheme.index("+")
-            if offset > 0:
-                return [scheme[offset+1:], username]
-    except:
-        pass
-    return [None, None]
-
-def get_uri_driver(uri):
-    try:
-        split_uri = uri_split(uri)
-        scheme = split_uri[0]
-
-        if scheme:
-            offset = scheme.find("+")
-            if offset > 0:
-                return scheme[:offset]
-            return scheme
-    except Exception:
-        pass
-    return "xen"
-
-def is_storage_capable(conn):
-    """check if virConnectPtr passed has storage API support"""
-    if not conn:
-        return False
-    if not isinstance(conn, libvirt.virConnect):
-        raise ValueError(_("'conn' must be a virConnect instance."))
-    try:
-        if not dir(conn).count("listStoragePools"):
-            return False
-        conn.listStoragePools()
-    except libvirt.libvirtError, e:
-        if e.get_error_code() == libvirt.VIR_ERR_RPC or \
-           e.get_error_code() == libvirt.VIR_ERR_NO_SUPPORT:
-            return False
-    return True
-
-def get_xml_path(xml, path):
-    """return the xpath from the passed xml"""
-    doc = None
-    ctx = None
-    result = None
-    try:
-        doc = libxml2.parseDoc(xml)
-        ctx = doc.xpathNewContext()
-        ret = ctx.xpathEval(path)
-        val = None
-        if ret != None:
-            if type(ret) == list:
-                if len(ret) == 1:
-                    val = ret[0].content
-            else:
-                val = ret
-        result = val
-    finally:
-        if doc:
-            doc.freeDoc()
-        if ctx:
-            ctx.xpathFreeContext()
-    return result
-
-def lookup_pool_by_path(conn, path):
-    """
-    Return the first pool with matching matching target path.
-    return the first we find, active or inactive. This iterates over
-    all pools and dumps their xml, so it is NOT quick.
-    @return virStoragePool object if found, None otherwise
-    """
-    if not is_storage_capable(conn):
-        return None
-
-    pool_list = conn.listStoragePools() + conn.listDefinedStoragePools()
-    for name in pool_list:
-        pool = conn.storagePoolLookupByName(name)
-        xml_path = get_xml_path(pool.XMLDesc(0), "/pool/target/path")
-        if os.path.abspath(xml_path) == path:
-            return pool
-    return None
-
-def privileged_user():
-    """
-    Return true if the user is privileged enough.  On Linux, this
-    equates to being root.  On Solaris, it's more complicated, so we
-    just assume we're OK.
-    """
-    return os.uname()[0] == 'SunOS' or os.geteuid() == 0
-
-def _test():
-    import doctest
-    doctest.testmod()
- 
-if __name__ == "__main__":
-    _test()

_______________________________________________
et-mgmt-tools mailing list
et-mgmt-tools@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/et-mgmt-tools

[Index of Archives]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux