diff --git a/cord-setup.yml b/cord-setup.yml
index c5c5ec1..c2fb8e0 100644
--- a/cord-setup.yml
+++ b/cord-setup.yml
@@ -32,6 +32,10 @@
     - python-keystoneclient
     - python-glanceclient
 
+  - name: Patch uvt-kvm
+    copy: src=files/usr/lib/python2.7/dist-packages/uvtool/libvirt/__init__.py
+      dest=/usr/lib/python2.7/dist-packages/uvtool/libvirt/__init__.py
+
   - name: Get juju-ansible git repo
     git: repo=https://github.com/cmars/juju-ansible.git
       dest=/usr/local/src/juju-ansible
diff --git a/files/usr/lib/python2.7/dist-packages/uvtool/libvirt/__init__.py b/files/usr/lib/python2.7/dist-packages/uvtool/libvirt/__init__.py
new file mode 100644
index 0000000..3c72a8d
--- /dev/null
+++ b/files/usr/lib/python2.7/dist-packages/uvtool/libvirt/__init__.py
@@ -0,0 +1,246 @@
+# Copyright (C) 2013 Canonical Ltd.
+# Author: Robie Basak <robie.basak@canonical.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import codecs
+import contextlib
+import itertools
+import os
+import shutil
+import subprocess
+import tempfile
+
+import libvirt
+from lxml import etree
+from lxml.builder import E
+
+LIBVIRT_DNSMASQ_LEASE_FILE = '/var/lib/libvirt/dnsmasq/default.leases'
+
+
+def get_libvirt_pool_object(libvirt_conn, pool_name):
+    try:
+        pool = libvirt_conn.storagePoolLookupByName(pool_name)
+    except libvirt.libvirtError:
+        raise RuntimeError("Cannot find pool %s." % repr(pool_name))
+    return pool
+
+
+def create_volume_from_fobj(new_volume_name, fobj, image_type='raw',
+        pool_name='default'):
+    """Create a new libvirt volume and populate it from a file-like object."""
+
+    compressed_fobj = tempfile.NamedTemporaryFile()
+    decompressed_fobj = tempfile.NamedTemporaryFile()
+    with contextlib.closing(compressed_fobj):
+        with contextlib.closing(decompressed_fobj):
+            shutil.copyfileobj(fobj, compressed_fobj)
+            compressed_fobj.flush()
+            compressed_fobj.seek(0)  # is this necessary?
+            subprocess.check_call(
+                [
+                    'qemu-img', 'convert', '-f', image_type, '-O', image_type,
+                    compressed_fobj.name, decompressed_fobj.name
+                ],
+                shell=False, close_fds=False)
+            decompressed_fobj.seek(0)  # is this necessary?
+            return _create_volume_from_fobj_with_size(
+                new_volume_name=new_volume_name,
+                fobj=decompressed_fobj,
+                fobj_size=os.fstat(decompressed_fobj.fileno()).st_size,
+                image_type=image_type,
+                pool_name=pool_name
+            )
+
+
+def _create_volume_from_fobj_with_size(new_volume_name, fobj, fobj_size,
+        image_type, pool_name):
+    conn = libvirt.open('qemu:///system')
+    pool = get_libvirt_pool_object(conn, pool_name)
+
+    if image_type == 'raw':
+        extra = [E.allocation(str(fobj_size)), E.capacity(str(fobj_size))]
+    elif image_type == 'qcow2':
+        extra = [E.capacity('0')]
+    else:
+        raise NotImplementedError("Unknown image type %r." % image_type)
+
+    new_vol = E.volume(
+        E.name(new_volume_name),
+        E.target(E.format(type=image_type)),
+        *extra
+        )
+    vol = pool.createXML(etree.tostring(new_vol), 0)
+
+    try:
+        stream = conn.newStream(0)
+        vol.upload(stream, 0, fobj_size, 0)
+
+        def handler(stream_ignored, size, opaque_ignored):
+            return fobj.read(size)
+
+        try:
+            stream.sendAll(handler, None)
+        except Exception as e:
+            try:
+                # This unexpectedly raises an exception even on a normal call,
+                # so ignore it.
+                stream.abort()
+            except:
+                pass
+            raise e
+        stream.finish()
+    except:
+        vol.delete(flags=0)
+        raise
+
+    return vol
+
+
+def volume_names_in_pool(pool_name='default'):
+    conn = libvirt.open('qemu:///system')
+    pool = get_libvirt_pool_object(conn, pool_name)
+    return pool.listVolumes()
+
+
+def delete_volume_by_name(volume_name, pool_name='default'):
+    conn = libvirt.open('qemu:///system')
+    pool = get_libvirt_pool_object(conn, pool_name)
+    volume = pool.storageVolLookupByName(volume_name)
+    volume.delete(flags=0)
+
+
+def have_volume_by_name(volume_name, pool_name='default'):
+    conn = libvirt.open('qemu:///system')
+    pool = get_libvirt_pool_object(conn, pool_name)
+    try:
+        volume = pool.storageVolLookupByName(volume_name)
+    except libvirt.libvirtError:
+        return False
+    else:
+        return True
+
+
+def _get_all_domains(conn=None):
+    if conn is None:
+        conn = libvirt.open('qemu:///system')
+
+    # libvirt in Precise doesn't seem to have a binding for
+    # virConnectListAllDomains, and it seems that we must enumerate
+    # defined-by-not-running and running instances separately and in different
+    # ways.
+
+    for domain_id in conn.listDomainsID():
+        yield conn.lookupByID(domain_id)
+
+    for domain_name in conn.listDefinedDomains():
+        yield conn.lookupByName(domain_name)
+
+
+def _domain_element_to_volume_paths(element):
+    assert element.tag == 'domain'
+    return (
+        source.get('file')
+        for source in element.xpath(
+            "/domain/devices/disk[@type='file']/source[@file]"
+        )
+    )
+
+
+def _domain_volume_paths(domain):
+    volume_paths = set()
+
+    for flags in [0, libvirt.VIR_DOMAIN_XML_INACTIVE]:
+        element = etree.fromstring(domain.XMLDesc(flags))
+        volume_paths.update(_domain_element_to_volume_paths(element))
+
+    return frozenset(volume_paths)
+
+
+def _volume_element_to_volume_paths(element):
+    assert element.tag == 'volume'
+    return itertools.chain(
+        (path.text for path in element.xpath('/volume/target/path')),
+        (path.text for path in element.xpath('/volume/backingStore/path')),
+    )
+
+
+def _volume_volume_paths(volume):
+    # Volumes can depend on other volumes ("backing stores"), so return all
+    # paths a volume needs to function, including the top level one.
+    volume_paths = set()
+
+    element = etree.fromstring(volume.XMLDesc(0))
+    volume_paths.update(_volume_element_to_volume_paths(element))
+
+    return frozenset(volume_paths)
+
+
+def _get_all_domain_volume_paths(conn=None):
+    if conn is None:
+        conn = libvirt.open('qemu:///system')
+
+    all_volume_paths = set()
+    for domain in _get_all_domains(conn):
+        for path in _domain_volume_paths(domain):
+            try:
+                volume = conn.storageVolLookupByKey(path)
+            except libvirt.libvirtError:
+                # ignore a lookup failure, since if a volume doesn't exist,
+                # it isn't reasonable to consider what backing volumes it may
+                # have
+                continue
+            all_volume_paths.update(_volume_volume_paths(volume))
+
+    return frozenset(all_volume_paths)
+
+
+def get_all_domain_volume_names(conn=None, filter_by_dir=None):
+    # Limitation: filter_by_dir must currently end in a '/' and be the
+    # canonical path as libvirt returns it. Ideally I'd filter by pool instead,
+    # but the libvirt API appears to not provide any method to find what pool a
+    # volume is in when looked up by key.
+    if conn is None:
+        conn = libvirt.open('qemu:///system')
+
+    for path in _get_all_domain_volume_paths(conn=conn):
+        volume = conn.storageVolLookupByKey(path)
+        if filter_by_dir and not volume.path().startswith(filter_by_dir):
+            continue
+        yield volume.name()
+
+
+def get_domain_macs(domain_name, conn=None):
+    if conn is None:
+        conn = libvirt.open('qemu:///system')
+
+    domain = conn.lookupByName(domain_name)
+    xml = etree.fromstring(domain.XMLDesc(0))
+    for mac in xml.xpath(
+            "/domain/devices/interface[@type='network' or @type='bridge']/mac[@address]"):
+        yield mac.get('address')
+
+
+def mac_to_ip(mac):
+    canonical_mac = mac.lower()
+    with codecs.open(LIBVIRT_DNSMASQ_LEASE_FILE, 'r') as f:
+        for line in f:
+            fields = line.split()
+            if len(fields) > 1 and fields[1].lower() == canonical_mac:
+                return fields[2]
+        return None
