diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-03-12 20:10:59 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-03-12 20:10:59 +0000 |
| commit | 641b68b0ad756196fb3ebc89ffd03c29a1d01cd4 (patch) | |
| tree | a5bdbb3ef1d2aaeb2dd1c9aa6c69d4ce850f17b8 | |
| parent | b057ab60a39eb8dfa6604d6f207625c29df6cd70 (diff) | |
| parent | 7dbf9c7de23623223ef60c0566d9330797c5f87e (diff) | |
| download | nova-641b68b0ad756196fb3ebc89ffd03c29a1d01cd4.tar.gz nova-641b68b0ad756196fb3ebc89ffd03c29a1d01cd4.tar.xz nova-641b68b0ad756196fb3ebc89ffd03c29a1d01cd4.zip | |
Merge "Make snapshots with qemu-img instead of libvirt"
| -rwxr-xr-x | nova/rootwrap/compute.py | 4 | ||||
| -rw-r--r-- | nova/tests/fake_libvirt_utils.py | 8 | ||||
| -rw-r--r-- | nova/tests/test_libvirt.py | 10 | ||||
| -rw-r--r-- | nova/virt/libvirt/connection.py | 35 | ||||
| -rw-r--r-- | nova/virt/libvirt/utils.py | 48 |
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, |
