Merge lp:~vishvananda/nova/lp824433 into lp:~hudson-openstack/nova/milestone-proposed

Proposed by Vish Ishaya
Status: Merged
Approved by: Vish Ishaya
Approved revision: 1530
Merged at revision: 1182
Proposed branch: lp:~vishvananda/nova/lp824433
Merge into: lp:~hudson-openstack/nova/milestone-proposed
Diff against target: 173 lines (+84/-44)
2 files modified
nova/tests/test_libvirt.py (+71/-33)
nova/virt/libvirt/connection.py (+13/-11)
To merge this branch: bzr merge lp:~vishvananda/nova/lp824433
Reviewer Review Type Date Requested Status
OpenStack release team Pending
Review via email: mp+76092@code.launchpad.net

Description of the change

Fixes the handling of snapshotting in libvirt driver to actually use the proper image type instead of using raw for everything. Also cleans up an unneeded flag. Based on doude's initial work.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/tests/test_libvirt.py'
2--- nova/tests/test_libvirt.py 2011-09-16 17:36:43 +0000
3+++ nova/tests/test_libvirt.py 2011-09-19 20:04:46 +0000
4@@ -340,39 +340,77 @@
5 instance_data = dict(self.test_instance)
6 self._check_xml_and_container(instance_data)
7
8- def test_snapshot(self):
9- if not self.lazy_load_library_exists():
10- return
11-
12- self.flags(image_service='nova.image.fake.FakeImageService')
13-
14- # Start test
15- image_service = utils.import_object(FLAGS.image_service)
16-
17- # Assuming that base image already exists in image_service
18- instance_ref = db.instance_create(self.context, self.test_instance)
19- properties = {'instance_id': instance_ref['id'],
20- 'user_id': str(self.context.user_id)}
21- snapshot_name = 'test-snap'
22- sent_meta = {'name': snapshot_name, 'is_public': False,
23- 'status': 'creating', 'properties': properties}
24- # Create new image. It will be updated in snapshot method
25- # To work with it from snapshot, the single image_service is needed
26- recv_meta = image_service.create(context, sent_meta)
27-
28- self.mox.StubOutWithMock(connection.LibvirtConnection, '_conn')
29- connection.LibvirtConnection._conn.lookupByName = self.fake_lookup
30- self.mox.StubOutWithMock(connection.utils, 'execute')
31- connection.utils.execute = self.fake_execute
32-
33- self.mox.ReplayAll()
34-
35- conn = connection.LibvirtConnection(False)
36- conn.snapshot(self.context, instance_ref, recv_meta['id'])
37-
38- snapshot = image_service.show(context, recv_meta['id'])
39- self.assertEquals(snapshot['properties']['image_state'], 'available')
40- self.assertEquals(snapshot['status'], 'active')
41+ def test_snapshot_in_raw_format(self):
42+ if not self.lazy_load_library_exists():
43+ return
44+
45+ self.flags(image_service='nova.image.fake.FakeImageService')
46+
47+ # Start test
48+ image_service = utils.import_object(FLAGS.image_service)
49+
50+ # Assuming that base image already exists in image_service
51+ instance_ref = db.instance_create(self.context, self.test_instance)
52+ properties = {'instance_id': instance_ref['id'],
53+ 'user_id': str(self.context.user_id)}
54+ snapshot_name = 'test-snap'
55+ sent_meta = {'name': snapshot_name, 'is_public': False,
56+ 'status': 'creating', 'properties': properties}
57+ # Create new image. It will be updated in snapshot method
58+ # To work with it from snapshot, the single image_service is needed
59+ recv_meta = image_service.create(context, sent_meta)
60+
61+ self.mox.StubOutWithMock(connection.LibvirtConnection, '_conn')
62+ connection.LibvirtConnection._conn.lookupByName = self.fake_lookup
63+ self.mox.StubOutWithMock(connection.utils, 'execute')
64+ connection.utils.execute = self.fake_execute
65+
66+ self.mox.ReplayAll()
67+
68+ conn = connection.LibvirtConnection(False)
69+ conn.snapshot(self.context, instance_ref, recv_meta['id'])
70+
71+ snapshot = image_service.show(context, recv_meta['id'])
72+ self.assertEquals(snapshot['properties']['image_state'], 'available')
73+ self.assertEquals(snapshot['status'], 'active')
74+ self.assertEquals(snapshot['disk_format'], 'raw')
75+ self.assertEquals(snapshot['name'], snapshot_name)
76+
77+ def test_snapshot_in_qcow2_format(self):
78+ if not self.lazy_load_library_exists():
79+ return
80+
81+ self.flags(image_service='nova.image.fake.FakeImageService')
82+ self.flags(snapshot_image_format='qcow2')
83+
84+ # Start test
85+ image_service = utils.import_object(FLAGS.image_service)
86+
87+ # Assuming that base image already exists in image_service
88+ instance_ref = db.instance_create(self.context, self.test_instance)
89+ properties = {'instance_id': instance_ref['id'],
90+ 'user_id': str(self.context.user_id)}
91+ snapshot_name = 'test-snap'
92+ sent_meta = {'name': snapshot_name, 'is_public': False,
93+ 'status': 'creating', 'properties': properties}
94+ # Create new image. It will be updated in snapshot method
95+ # To work with it from snapshot, the single image_service is needed
96+ recv_meta = image_service.create(context, sent_meta)
97+
98+ self.mox.StubOutWithMock(connection.LibvirtConnection, '_conn')
99+ connection.LibvirtConnection._conn.lookupByName = self.fake_lookup
100+ self.mox.StubOutWithMock(connection.utils, 'execute')
101+ connection.utils.execute = self.fake_execute
102+
103+ self.mox.ReplayAll()
104+
105+ conn = connection.LibvirtConnection(False)
106+ conn.snapshot(self.context, instance_ref, recv_meta['id'])
107+
108+ snapshot = image_service.show(context, recv_meta['id'])
109+ self.assertEquals(snapshot['properties']['image_state'], 'available')
110+ self.assertEquals(snapshot['status'], 'active')
111+ self.assertEquals(snapshot['disk_format'], 'qcow2')
112 self.assertEquals(snapshot['name'], snapshot_name)
113
114 def test_snapshot_no_image_architecture(self):
115
116=== modified file 'nova/virt/libvirt/connection.py'
117--- nova/virt/libvirt/connection.py 2011-09-18 19:24:46 +0000
118+++ nova/virt/libvirt/connection.py 2011-09-19 20:04:46 +0000
119@@ -125,8 +125,10 @@
120 'Define block migration behavior.')
121 flags.DEFINE_integer('live_migration_bandwidth', 0,
122 'Define live migration behavior')
123-flags.DEFINE_string('qemu_img', 'qemu-img',
124- 'binary to use for qemu-img commands')
125+flags.DEFINE_string('snapshot_image_format', None,
126+ 'Snapshot image format (valid options are : '
127+ 'raw, qcow2, vmdk, vdi).'
128+ 'Defaults to same as source image')
129 flags.DEFINE_string('libvirt_vif_type', 'bridge',
130 'Type of VIF to create.')
131 flags.DEFINE_string('libvirt_vif_driver',
132@@ -391,10 +393,7 @@
133 def snapshot(self, context, instance, image_href):
134 """Create snapshot from a running VM instance.
135
136- This command only works with qemu 0.14+, the qemu_img flag is
137- provided so that a locally compiled binary of qemu-img can be used
138- to support this command.
139-
140+ This command only works with qemu 0.14+
141 """
142 virt_dom = self._lookup_by_name(instance['name'])
143
144@@ -420,8 +419,11 @@
145 arch = base['properties']['architecture']
146 metadata['properties']['architecture'] = arch
147
148- if 'disk_format' in base:
149- metadata['disk_format'] = base['disk_format']
150+ source_format = base.get('disk_format') or 'raw'
151+ image_format = FLAGS.snapshot_image_format or source_format
152+ if FLAGS.use_cow_images:
153+ source_format = 'qcow2'
154+ metadata['disk_format'] = image_format
155
156 if 'container_format' in base:
157 metadata['container_format'] = base['container_format']
158@@ -444,12 +446,12 @@
159 # Export the snapshot to a raw image
160 temp_dir = tempfile.mkdtemp()
161 out_path = os.path.join(temp_dir, snapshot_name)
162- qemu_img_cmd = (FLAGS.qemu_img,
163+ qemu_img_cmd = ('qemu-img',
164 'convert',
165 '-f',
166- 'qcow2',
167+ source_format,
168 '-O',
169- 'raw',
170+ image_format,
171 '-s',
172 snapshot_name,
173 disk_path,

Subscribers

People subscribed via source and target branches