summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-03-12 20:10:59 +0000
committerGerrit Code Review <review@openstack.org>2012-03-12 20:10:59 +0000
commit641b68b0ad756196fb3ebc89ffd03c29a1d01cd4 (patch)
treea5bdbb3ef1d2aaeb2dd1c9aa6c69d4ce850f17b8
parentb057ab60a39eb8dfa6604d6f207625c29df6cd70 (diff)
parent7dbf9c7de23623223ef60c0566d9330797c5f87e (diff)
downloadnova-641b68b0ad756196fb3ebc89ffd03c29a1d01cd4.tar.gz
nova-641b68b0ad756196fb3ebc89ffd03c29a1d01cd4.tar.xz
nova-641b68b0ad756196fb3ebc89ffd03c29a1d01cd4.zip
Merge "Make snapshots with qemu-img instead of libvirt"
-rwxr-xr-xnova/rootwrap/compute.py4
-rw-r--r--nova/tests/fake_libvirt_utils.py8
-rw-r--r--nova/tests/test_libvirt.py10
-rw-r--r--nova/virt/libvirt/connection.py35
-rw-r--r--nova/virt/libvirt/utils.py48
5 files changed, 74 insertions, 31 deletions
diff --git a/nova/rootwrap/compute.py b/nova/rootwrap/compute.py
index 7488b2120..3da9f46c0 100755
--- a/nova/rootwrap/compute.py
+++ b/nova/rootwrap/compute.py
@@ -179,6 +179,10 @@ filterlist = [
# nova/virt/xenapi/vm_utils.py: 'mkfs'
filters.CommandFilter("/sbin/mkfs", "root"),
+ # nova/virt/libvirt/utils.py: 'qemu-img'
+ filters.CommandFilter("/usr/bin/qemu-img", "root"),
+
# nova/virt/libvirt/connection.py:
filters.ReadFileFilter("/etc/iscsi/initiatorname.iscsi"),
+
]
diff --git a/nova/tests/fake_libvirt_utils.py b/nova/tests/fake_libvirt_utils.py
index 726e28a1d..bdd24e4bd 100644
--- a/nova/tests/fake_libvirt_utils.py
+++ b/nova/tests/fake_libvirt_utils.py
@@ -61,6 +61,14 @@ def chown(path, owner):
pass
+def create_snapshot(disk_path, snapshot_name):
+ pass
+
+
+def delete_snapshot(disk_path, snapshot_name):
+ pass
+
+
def extract_snapshot(disk_path, source_fmt, snapshot_name, out_path, dest_fmt):
files[out_path] = ''
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index 8e7b69b84..527961c93 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -98,8 +98,14 @@ class FakeVirtDomain(object):
def name(self):
return "fake-domain %s" % self
- def snapshotCreateXML(self, *args):
- return FakeVirDomainSnapshot(self)
+ def info(self):
+ return [power_state.RUNNING, None, None, None, None]
+
+ def create(self):
+ pass
+
+ def managedSave(self, *args):
+ pass
def createWithFlags(self, launch_flags):
pass
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index 9d1713106..9be1f9c62 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -616,21 +616,20 @@ class LibvirtConnection(driver.ComputeDriver):
if 'container_format' in base:
metadata['container_format'] = base['container_format']
- # Make the snapshot
- snapshot_name = uuid.uuid4().hex
- snapshot_xml = """
- <domainsnapshot>
- <name>%s</name>
- </domainsnapshot>
- """ % snapshot_name
- snapshot_ptr = virt_dom.snapshotCreateXML(snapshot_xml, 0)
-
# Find the disk
xml_desc = virt_dom.XMLDesc(0)
domain = ElementTree.fromstring(xml_desc)
source = domain.find('devices/disk/source')
disk_path = source.get('file')
+ snapshot_name = uuid.uuid4().hex
+
+ (state, _max_mem, _mem, _cpus, _t) = virt_dom.info()
+ if state == power_state.RUNNING:
+ virt_dom.managedSave(0)
+ # Make the snapshot
+ libvirt_utils.create_snapshot(disk_path, snapshot_name)
+
# Export the snapshot to a raw image
with utils.tempdir() as tmpdir:
try:
@@ -638,15 +637,17 @@ class LibvirtConnection(driver.ComputeDriver):
libvirt_utils.extract_snapshot(disk_path, source_format,
snapshot_name, out_path,
image_format)
- # Upload that image to the image service
- with libvirt_utils.file_open(out_path) as image_file:
- image_service.update(context,
- image_href,
- metadata,
- image_file)
-
finally:
- snapshot_ptr.delete(0)
+ libvirt_utils.delete_snapshot(disk_path, snapshot_name)
+ if state == power_state.RUNNING:
+ virt_dom.create()
+
+ # Upload that image to the image service
+ with libvirt_utils.file_open(out_path) as image_file:
+ image_service.update(context,
+ image_href,
+ metadata,
+ image_file)
@exception.wrap_exception()
def reboot(self, instance, network_info, reboot_type='SOFT'):
diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py
index 329f76eb1..0eec1db1a 100644
--- a/nova/virt/libvirt/utils.py
+++ b/nova/virt/libvirt/utils.py
@@ -24,17 +24,11 @@ import random
from nova import exception
from nova import flags
-from nova.openstack.common import cfg
from nova import utils
from nova.virt import images
-qemu_img_opt = cfg.StrOpt('qemu_img',
- default='qemu-img',
- help='binary to use for qemu-img commands')
-
FLAGS = flags.FLAGS
-FLAGS.register_opt(qemu_img_opt)
def execute(*args, **kwargs):
@@ -63,7 +57,7 @@ def create_image(disk_format, path, size):
for megabytes, 'g' for gigabytes, 't' for terabytes). If no
prefix is given, it will be interpreted as bytes.
"""
- execute(FLAGS.qemu_img, 'create', '-f', disk_format, path, size)
+ execute('qemu-img', 'create', '-f', disk_format, path, size)
def create_cow_image(backing_file, path):
@@ -74,7 +68,7 @@ def create_cow_image(backing_file, path):
:param backing_file: Existing image on which to base the COW image
:param path: Desired location of the COW image
"""
- execute(FLAGS.qemu_img, 'create', '-f', 'qcow2', '-o',
+ execute('qemu-img', 'create', '-f', 'qcow2', '-o',
'cluster_size=2M,backing_file=%s' % backing_file, path)
@@ -85,7 +79,7 @@ def get_disk_size(path):
:returns: Size (in bytes) of the given disk image as it would be seen
by a virtual machine.
"""
- out, err = execute(FLAGS.qemu_img, 'info', path)
+ out, err = execute('qemu-img', 'info', path)
size = [i.split('(')[1].split()[0] for i in out.split('\n')
if i.strip().find('virtual size') >= 0]
return int(size[0])
@@ -97,7 +91,7 @@ def get_disk_backing_file(path):
:param path: Path to the disk image
:returns: a path to the image's backing store
"""
- out, err = execute(FLAGS.qemu_img, 'info', path)
+ out, err = execute('qemu-img', 'info', path)
backing_file = [i.split('actual path:')[1].strip()[:-1]
for i in out.split('\n') if 0 <= i.find('backing file')]
if backing_file:
@@ -168,7 +162,37 @@ def chown(path, owner):
:param path: File or directory whose ownership to change
:param owner: Desired new owner (given as uid or username)
"""
- utils.execute('chown', owner, path, run_as_root=True)
+ execute('chown', owner, path, run_as_root=True)
+
+
+def create_snapshot(disk_path, snapshot_name):
+ """Create a snapshot in a disk image
+
+ :param disk_path: Path to disk image
+ :param snapshot_name: Name of snapshot in disk image
+ """
+ qemu_img_cmd = ('qemu-img',
+ 'snapshot',
+ '-c',
+ snapshot_name,
+ disk_path)
+ # NOTE(vish): libvirt changes ownership of images
+ execute(*qemu_img_cmd, run_as_root=True)
+
+
+def delete_snapshot(disk_path, snapshot_name):
+ """Create a snapshot in a disk image
+
+ :param disk_path: Path to disk image
+ :param snapshot_name: Name of snapshot in disk image
+ """
+ qemu_img_cmd = ('qemu-img',
+ 'snapshot',
+ '-d',
+ snapshot_name,
+ disk_path)
+ # NOTE(vish): libvirt changes ownership of images
+ execute(*qemu_img_cmd, run_as_root=True)
def extract_snapshot(disk_path, source_fmt, snapshot_name, out_path, dest_fmt):
@@ -178,7 +202,7 @@ def extract_snapshot(disk_path, source_fmt, snapshot_name, out_path, dest_fmt):
:param snapshot_name: Name of snapshot in disk image
:param out_path: Desired path of extracted snapshot
"""
- qemu_img_cmd = (FLAGS.qemu_img,
+ qemu_img_cmd = ('qemu-img',
'convert',
'-f',
source_fmt,