1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2010 OpenStack LLC
4
# Copyright 2012 University Of Minho
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may
7
# not use this file except in compliance with the License. You may obtain
8
# a copy of the License at
10
# http://www.apache.org/licenses/LICENSE-2.0
12
# Unless required by applicable law or agreed to in writing, software
13
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
# License for the specific language governing permissions and limitations
28
from lxml import etree
29
from xml.dom import minidom
31
from nova.api.ec2 import cloud
32
from nova.compute import instance_types
33
from nova.compute import power_state
34
from nova.compute import vm_mode
35
from nova.compute import vm_states
36
from nova import context
38
from nova import exception
39
from nova import flags
40
from nova.openstack.common import importutils
41
from nova.openstack.common import jsonutils
42
from nova.openstack.common import log as logging
44
from nova.tests import fake_libvirt_utils
45
from nova.tests import fake_network
46
import nova.tests.image.fake
47
from nova import utils
48
from nova.virt.disk import api as disk
49
from nova.virt import driver
50
from nova.virt import firewall as base_firewall
51
from nova.virt import images
52
from nova.virt.libvirt import config
53
from nova.virt.libvirt import driver as libvirt_driver
54
from nova.virt.libvirt import firewall
55
from nova.virt.libvirt import imagebackend
56
from nova.virt.libvirt import utils as libvirt_utils
57
from nova.virt.libvirt import volume
58
from nova.virt.libvirt import volume_nfs
59
from nova.volume import driver as volume_driver
65
import nova.tests.fakelibvirt as libvirt
66
libvirt_driver.libvirt = libvirt
70
LOG = logging.getLogger(__name__)
72
_fake_network_info = fake_network.fake_get_instance_nw_info
73
_fake_stub_out_get_nw_info = fake_network.stub_out_nw_api_get_instance_nw_info
74
_ipv4_like = fake_network.ipv4_like
77
def _concurrency(wait, done, target):
82
class FakeVirDomainSnapshot(object):
84
def __init__(self, dom=None):
87
def delete(self, flags):
91
class FakeVirtDomain(object):
93
def __init__(self, fake_xml=None):
95
self._fake_dom_xml = fake_xml
97
self._fake_dom_xml = """
101
<source file='filename'/>
108
return "fake-domain %s" % self
111
return [power_state.RUNNING, None, None, None, None]
116
def managedSave(self, *args):
119
def createWithFlags(self, launch_flags):
122
def XMLDesc(self, *args):
123
return self._fake_dom_xml
126
class LibvirtVolumeTestCase(test.TestCase):
129
super(LibvirtVolumeTestCase, self).setUp()
132
def fake_execute(*cmd, **kwargs):
133
self.executes.append(cmd)
136
self.stubs.Set(utils, 'execute', fake_execute)
138
class FakeLibvirtDriver(object):
139
def __init__(self, hyperv="QEMU"):
142
def get_hypervisor_type(self):
145
def get_all_block_devices(self):
148
self.fake_conn = FakeLibvirtDriver()
151
'initiator': 'fake_initiator',
155
def test_libvirt_volume_driver_serial(self):
156
vol_driver = volume_driver.VolumeDriver()
157
libvirt_driver = volume.LibvirtVolumeDriver(self.fake_conn)
158
name = 'volume-00000001'
159
vol = {'id': 1, 'name': name}
161
'driver_volume_type': 'fake',
163
'device_path': '/foo',
165
'serial': 'fake_serial',
168
conf = libvirt_driver.connect_volume(connection_info, mount_device)
169
tree = conf.format_dom()
170
self.assertEqual(tree.get('type'), 'block')
171
self.assertEqual(tree.find('./serial').text, 'fake_serial')
173
def test_libvirt_iscsi_driver(self):
174
# NOTE(vish) exists is to make driver assume connecting worked
175
self.stubs.Set(os.path, 'exists', lambda x: True)
176
vol_driver = volume_driver.ISCSIDriver()
177
libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn)
178
location = '10.0.2.15:3260'
179
name = 'volume-00000001'
180
iqn = 'iqn.2010-10.org.openstack:%s' % name
183
'provider_auth': None,
184
'provider_location': '%s,fake %s' % (location, iqn)}
185
connection_info = vol_driver.initialize_connection(vol, self.connr)
187
conf = libvirt_driver.connect_volume(connection_info, mount_device)
188
tree = conf.format_dom()
189
dev_str = '/dev/disk/by-path/ip-%s-iscsi-%s-lun-1' % (location, iqn)
190
self.assertEqual(tree.get('type'), 'block')
191
self.assertEqual(tree.find('./source').get('dev'), dev_str)
192
libvirt_driver.disconnect_volume(connection_info, mount_device)
193
connection_info = vol_driver.terminate_connection(vol, self.connr)
194
expected_commands = [('iscsiadm', '-m', 'node', '-T', iqn,
196
('iscsiadm', '-m', 'node', '-T', iqn,
197
'-p', location, '--login'),
198
('iscsiadm', '-m', 'node', '-T', iqn,
199
'-p', location, '--op', 'update',
200
'-n', 'node.startup', '-v', 'automatic'),
201
('iscsiadm', '-m', 'node', '-T', iqn,
202
'-p', location, '--op', 'update',
203
'-n', 'node.startup', '-v', 'manual'),
204
('iscsiadm', '-m', 'node', '-T', iqn,
205
'-p', location, '--logout'),
206
('iscsiadm', '-m', 'node', '-T', iqn,
207
'-p', location, '--op', 'delete')]
208
self.assertEqual(self.executes, expected_commands)
210
def test_libvirt_iscsi_driver_still_in_use(self):
211
# NOTE(vish) exists is to make driver assume connecting worked
212
self.stubs.Set(os.path, 'exists', lambda x: True)
213
vol_driver = volume_driver.ISCSIDriver()
214
libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn)
215
location = '10.0.2.15:3260'
216
name = 'volume-00000001'
217
iqn = 'iqn.2010-10.org.openstack:%s' % name
218
devs = ['/dev/disk/by-path/ip-%s-iscsi-%s-lun-1' % (location, iqn)]
219
self.stubs.Set(self.fake_conn, 'get_all_block_devices', lambda: devs)
222
'provider_auth': None,
223
'provider_location': '%s,fake %s' % (location, iqn)}
224
connection_info = vol_driver.initialize_connection(vol, self.connr)
226
conf = libvirt_driver.connect_volume(connection_info, mount_device)
227
tree = conf.format_dom()
228
dev_str = '/dev/disk/by-path/ip-%s-iscsi-%s-lun-1' % (location, iqn)
229
self.assertEqual(tree.get('type'), 'block')
230
self.assertEqual(tree.find('./source').get('dev'), dev_str)
231
libvirt_driver.disconnect_volume(connection_info, mount_device)
232
connection_info = vol_driver.terminate_connection(vol, self.connr)
233
expected_commands = [('iscsiadm', '-m', 'node', '-T', iqn,
235
('iscsiadm', '-m', 'node', '-T', iqn,
236
'-p', location, '--login'),
237
('iscsiadm', '-m', 'node', '-T', iqn,
238
'-p', location, '--op', 'update',
239
'-n', 'node.startup', '-v', 'automatic')]
240
self.assertEqual(self.executes, expected_commands)
242
def test_libvirt_sheepdog_driver(self):
243
vol_driver = volume_driver.SheepdogDriver()
244
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
245
name = 'volume-00000001'
246
vol = {'id': 1, 'name': name}
247
connection_info = vol_driver.initialize_connection(vol, self.connr)
249
conf = libvirt_driver.connect_volume(connection_info, mount_device)
250
tree = conf.format_dom()
251
self.assertEqual(tree.get('type'), 'network')
252
self.assertEqual(tree.find('./source').get('protocol'), 'sheepdog')
253
self.assertEqual(tree.find('./source').get('name'), name)
254
libvirt_driver.disconnect_volume(connection_info, mount_device)
255
connection_info = vol_driver.terminate_connection(vol, self.connr)
257
def test_libvirt_rbd_driver(self):
258
vol_driver = volume_driver.RBDDriver()
259
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
260
name = 'volume-00000001'
261
vol = {'id': 1, 'name': name}
262
connection_info = vol_driver.initialize_connection(vol, self.connr)
264
conf = libvirt_driver.connect_volume(connection_info, mount_device)
265
tree = conf.format_dom()
266
self.assertEqual(tree.get('type'), 'network')
267
self.assertEqual(tree.find('./source').get('protocol'), 'rbd')
268
rbd_name = '%s/%s' % (FLAGS.rbd_pool, name)
269
self.assertEqual(tree.find('./source').get('name'), rbd_name)
270
self.assertEqual(tree.find('./source/auth'), None)
271
libvirt_driver.disconnect_volume(connection_info, mount_device)
272
connection_info = vol_driver.terminate_connection(vol, self.connr)
274
def test_libvirt_rbd_driver_auth_enabled(self):
275
vol_driver = volume_driver.RBDDriver()
276
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
277
name = 'volume-00000001'
278
vol = {'id': 1, 'name': name}
279
connection_info = vol_driver.initialize_connection(vol, self.connr)
280
uuid = '875a8070-d0b9-4949-8b31-104d125c9a64'
283
connection_info['data']['auth_enabled'] = True
284
connection_info['data']['auth_username'] = user
285
connection_info['data']['secret_type'] = secret_type
286
connection_info['data']['secret_uuid'] = uuid
289
conf = libvirt_driver.connect_volume(connection_info, mount_device)
290
tree = conf.format_dom()
291
self.assertEqual(tree.get('type'), 'network')
292
self.assertEqual(tree.find('./source').get('protocol'), 'rbd')
293
rbd_name = '%s/%s' % (FLAGS.rbd_pool, name)
294
self.assertEqual(tree.find('./source').get('name'), rbd_name)
295
self.assertEqual(tree.find('./auth').get('username'), user)
296
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
297
self.assertEqual(tree.find('./auth/secret').get('uuid'), uuid)
298
libvirt_driver.disconnect_volume(connection_info, mount_device)
299
connection_info = vol_driver.terminate_connection(vol, self.connr)
301
def test_libvirt_rbd_driver_auth_disabled(self):
302
vol_driver = volume_driver.RBDDriver()
303
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
304
name = 'volume-00000001'
305
vol = {'id': 1, 'name': name}
306
connection_info = vol_driver.initialize_connection(vol, self.connr)
307
uuid = '875a8070-d0b9-4949-8b31-104d125c9a64'
310
connection_info['data']['auth_enabled'] = False
311
connection_info['data']['auth_username'] = user
312
connection_info['data']['secret_type'] = secret_type
313
connection_info['data']['secret_uuid'] = uuid
316
conf = libvirt_driver.connect_volume(connection_info, mount_device)
317
tree = conf.format_dom()
318
self.assertEqual(tree.get('type'), 'network')
319
self.assertEqual(tree.find('./source').get('protocol'), 'rbd')
320
rbd_name = '%s/%s' % (FLAGS.rbd_pool, name)
321
self.assertEqual(tree.find('./source').get('name'), rbd_name)
322
self.assertEqual(tree.find('./auth'), None)
323
libvirt_driver.disconnect_volume(connection_info, mount_device)
324
connection_info = vol_driver.terminate_connection(vol, self.connr)
326
def test_libvirt_lxc_volume(self):
327
self.stubs.Set(os.path, 'exists', lambda x: True)
328
vol_driver = volume_driver.ISCSIDriver()
329
libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn)
330
location = '10.0.2.15:3260'
331
name = 'volume-00000001'
332
iqn = 'iqn.2010-10.org.openstack:%s' % name
335
'provider_auth': None,
336
'provider_location': '%s,fake %s' % (location, iqn)}
337
connection_info = vol_driver.initialize_connection(vol, self.connr)
339
conf = libvirt_driver.connect_volume(connection_info, mount_device)
340
tree = conf.format_dom()
341
dev_str = '/dev/disk/by-path/ip-%s-iscsi-%s-lun-1' % (location, iqn)
342
self.assertEqual(tree.get('type'), 'block')
343
self.assertEqual(tree.find('./source').get('dev'), dev_str)
344
libvirt_driver.disconnect_volume(connection_info, mount_device)
345
connection_info = vol_driver.terminate_connection(vol, self.connr)
347
def test_libvirt_nfs_driver(self):
348
# NOTE(vish) exists is to make driver assume connecting worked
350
self.flags(nfs_mount_point_base=mnt_base)
352
libvirt_driver = volume_nfs.NfsVolumeDriver(self.fake_conn)
353
export_string = '192.168.1.1:/nfs/share1'
354
name = 'volume-00001'
355
export_mnt_base = os.path.join(mnt_base,
356
libvirt_driver.get_hash_str(export_string))
357
file_path = os.path.join(export_mnt_base, name)
359
connection_info = {'data': {'export': export_string, 'name': name}}
361
conf = libvirt_driver.connect_volume(connection_info, mount_device)
362
tree = conf.format_dom()
363
self.assertEqual(tree.get('type'), 'file')
364
self.assertEqual(tree.find('./source').get('file'), file_path)
365
libvirt_driver.disconnect_volume(connection_info, mount_device)
367
expected_commands = [
368
('stat', export_mnt_base),
369
('mount', '-t', 'nfs', export_string, export_mnt_base)]
370
self.assertEqual(self.executes, expected_commands)
373
class CacheConcurrencyTestCase(test.TestCase):
375
super(CacheConcurrencyTestCase, self).setUp()
376
self.flags(instances_path='nova.compute.manager')
378
# utils.synchronized() will create the lock_path for us if it
379
# doesn't already exist. It will also delete it when it's done,
380
# which can cause race conditions with the multiple threads we
381
# use for tests. So, create the path here so utils.synchronized()
382
# won't delete it out from under one of the threads.
383
self.lock_path = os.path.join(FLAGS.instances_path, 'locks')
384
utils.ensure_tree(self.lock_path)
386
def fake_exists(fname):
387
basedir = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name)
388
if fname == basedir or fname == self.lock_path:
392
def fake_execute(*args, **kwargs):
395
def fake_extend(image, size):
398
self.stubs.Set(os.path, 'exists', fake_exists)
399
self.stubs.Set(utils, 'execute', fake_execute)
400
self.stubs.Set(imagebackend.disk, 'extend', fake_extend)
401
imagebackend.libvirt_utils = fake_libvirt_utils
404
imagebackend.libvirt_utils = libvirt_utils
406
# Make sure the lock_path for this test is cleaned up
407
if os.path.exists(self.lock_path):
408
shutil.rmtree(self.lock_path)
410
super(CacheConcurrencyTestCase, self).tearDown()
412
def test_same_fname_concurrency(self):
413
"""Ensures that the same fname cache runs at a sequentially"""
414
backend = imagebackend.Backend(False)
415
wait1 = eventlet.event.Event()
416
done1 = eventlet.event.Event()
417
thr1 = eventlet.spawn(backend.image('instance', 'name').cache,
418
_concurrency, 'fname', None, wait=wait1, done=done1)
419
wait2 = eventlet.event.Event()
420
done2 = eventlet.event.Event()
421
thr2 = eventlet.spawn(backend.image('instance', 'name').cache,
422
_concurrency, 'fname', None, wait=wait2, done=done2)
426
self.assertFalse(done2.ready())
431
self.assertTrue(done2.ready())
432
# Wait on greenthreads to assert they didn't raise exceptions
437
def test_different_fname_concurrency(self):
438
"""Ensures that two different fname caches are concurrent"""
439
backend = imagebackend.Backend(False)
440
wait1 = eventlet.event.Event()
441
done1 = eventlet.event.Event()
442
thr1 = eventlet.spawn(backend.image('instance', 'name').cache,
443
_concurrency, 'fname2', None, wait=wait1, done=done1)
444
wait2 = eventlet.event.Event()
445
done2 = eventlet.event.Event()
446
thr2 = eventlet.spawn(backend.image('instance', 'name').cache,
447
_concurrency, 'fname1', None, wait=wait2, done=done2)
451
self.assertTrue(done2.ready())
455
# Wait on greenthreads to assert they didn't raise exceptions
461
class FakeVolumeDriver(object):
462
def __init__(self, *args, **kwargs):
465
def attach_volume(self, *args):
468
def detach_volume(self, *args):
471
def get_xml(self, *args):
475
class LibvirtConnTestCase(test.TestCase):
478
super(LibvirtConnTestCase, self).setUp()
479
self.flags(fake_call=True)
480
self.user_id = 'fake'
481
self.project_id = 'fake'
482
self.context = context.get_admin_context()
483
self.flags(instances_path='')
484
self.flags(libvirt_snapshots_directory='')
485
self.call_libvirt_dependant_setup = False
486
libvirt_driver.libvirt_utils = fake_libvirt_utils
488
def fake_extend(image, size):
491
self.stubs.Set(libvirt_driver.disk, 'extend', fake_extend)
493
nova.tests.image.fake.stub_out_image_service(self.stubs)
496
libvirt_driver.libvirt_utils = libvirt_utils
497
nova.tests.image.fake.FakeImageService_reset()
498
super(LibvirtConnTestCase, self).tearDown()
500
test_instance = {'memory_kb': '1024000',
501
'basepath': '/some/path',
502
'bridge_name': 'br100',
504
'project_id': 'fake',
506
'image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
509
'instance_type_id': '5'} # m1.small
511
def create_fake_libvirt_mock(self, **kwargs):
512
"""Defining mocks for LibvirtDriver(libvirt is not used)."""
514
# A fake libvirt.virConnect
515
class FakeLibvirtDriver(object):
516
def defineXML(self, xml):
517
return FakeVirtDomain()
520
volume_driver = 'iscsi=nova.tests.test_libvirt.FakeVolumeDriver'
521
self.flags(libvirt_volume_drivers=[volume_driver])
522
fake = FakeLibvirtDriver()
523
# Customizing above fake if necessary
524
for key, val in kwargs.items():
525
fake.__setattr__(key, val)
527
self.flags(libvirt_vif_driver="nova.tests.fake_network.FakeVIFDriver")
529
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
530
libvirt_driver.LibvirtDriver._conn = fake
532
def fake_lookup(self, instance_name):
533
return FakeVirtDomain()
535
def fake_execute(self, *args):
536
open(args[-1], "a").close()
538
def create_service(self, **kwargs):
539
service_ref = {'host': kwargs.get('host', 'dummy'),
540
'binary': 'nova-compute',
543
'availability_zone': 'zone'}
545
return db.service_create(context.get_admin_context(), service_ref)
547
def test_get_connector(self):
548
initiator = 'fake.initiator.iqn'
552
self.flags(host=host)
554
conn = libvirt_driver.LibvirtDriver(True)
557
'initiator': initiator,
563
result = conn.get_volume_connector(volume)
564
self.assertDictMatch(expected, result)
566
def test_get_guest_config(self):
567
conn = libvirt_driver.LibvirtDriver(True)
568
instance_ref = db.instance_create(self.context, self.test_instance)
570
cfg = conn.get_guest_config(instance_ref,
571
_fake_network_info(self.stubs, 1),
573
self.assertEquals(cfg.acpi, True)
574
self.assertEquals(cfg.memory, 1024 * 1024 * 2)
575
self.assertEquals(cfg.vcpus, 1)
576
self.assertEquals(cfg.os_type, vm_mode.HVM)
577
self.assertEquals(cfg.os_boot_dev, "hd")
578
self.assertEquals(cfg.os_root, None)
579
self.assertEquals(len(cfg.devices), 7)
580
self.assertEquals(type(cfg.devices[0]),
581
config.LibvirtConfigGuestDisk)
582
self.assertEquals(type(cfg.devices[1]),
583
config.LibvirtConfigGuestDisk)
584
self.assertEquals(type(cfg.devices[2]),
585
config.LibvirtConfigGuestInterface)
586
self.assertEquals(type(cfg.devices[3]),
587
config.LibvirtConfigGuestSerial)
588
self.assertEquals(type(cfg.devices[4]),
589
config.LibvirtConfigGuestSerial)
590
self.assertEquals(type(cfg.devices[5]),
591
config.LibvirtConfigGuestInput)
592
self.assertEquals(type(cfg.devices[6]),
593
config.LibvirtConfigGuestGraphics)
595
self.assertEquals(type(cfg.clock),
596
config.LibvirtConfigGuestClock)
597
self.assertEquals(cfg.clock.offset, "utc")
598
self.assertEquals(len(cfg.clock.timers), 2)
599
self.assertEquals(type(cfg.clock.timers[0]),
600
config.LibvirtConfigGuestTimer)
601
self.assertEquals(type(cfg.clock.timers[1]),
602
config.LibvirtConfigGuestTimer)
603
self.assertEquals(cfg.clock.timers[0].name, "pit")
604
self.assertEquals(cfg.clock.timers[0].tickpolicy,
606
self.assertEquals(cfg.clock.timers[1].name, "rtc")
607
self.assertEquals(cfg.clock.timers[1].tickpolicy,
610
def test_get_guest_config_with_two_nics(self):
611
conn = libvirt_driver.LibvirtDriver(True)
612
instance_ref = db.instance_create(self.context, self.test_instance)
614
cfg = conn.get_guest_config(instance_ref,
615
_fake_network_info(self.stubs, 2),
617
self.assertEquals(cfg.acpi, True)
618
self.assertEquals(cfg.memory, 1024 * 1024 * 2)
619
self.assertEquals(cfg.vcpus, 1)
620
self.assertEquals(cfg.os_type, vm_mode.HVM)
621
self.assertEquals(cfg.os_boot_dev, "hd")
622
self.assertEquals(cfg.os_root, None)
623
self.assertEquals(len(cfg.devices), 8)
624
self.assertEquals(type(cfg.devices[0]),
625
config.LibvirtConfigGuestDisk)
626
self.assertEquals(type(cfg.devices[1]),
627
config.LibvirtConfigGuestDisk)
628
self.assertEquals(type(cfg.devices[2]),
629
config.LibvirtConfigGuestInterface)
630
self.assertEquals(type(cfg.devices[3]),
631
config.LibvirtConfigGuestInterface)
632
self.assertEquals(type(cfg.devices[4]),
633
config.LibvirtConfigGuestSerial)
634
self.assertEquals(type(cfg.devices[5]),
635
config.LibvirtConfigGuestSerial)
636
self.assertEquals(type(cfg.devices[6]),
637
config.LibvirtConfigGuestInput)
638
self.assertEquals(type(cfg.devices[7]),
639
config.LibvirtConfigGuestGraphics)
641
def test_get_guest_config_with_root_device_name(self):
642
self.flags(libvirt_type='uml')
643
conn = libvirt_driver.LibvirtDriver(True)
644
instance_ref = db.instance_create(self.context, self.test_instance)
646
cfg = conn.get_guest_config(instance_ref, [], None, None,
647
{'root_device_name': 'dev/vdb'})
648
self.assertEquals(cfg.acpi, False)
649
self.assertEquals(cfg.memory, 1024 * 1024 * 2)
650
self.assertEquals(cfg.vcpus, 1)
651
self.assertEquals(cfg.os_type, "uml")
652
self.assertEquals(cfg.os_boot_dev, None)
653
self.assertEquals(cfg.os_root, 'dev/vdb')
654
self.assertEquals(len(cfg.devices), 3)
655
self.assertEquals(type(cfg.devices[0]),
656
config.LibvirtConfigGuestDisk)
657
self.assertEquals(type(cfg.devices[1]),
658
config.LibvirtConfigGuestDisk)
659
self.assertEquals(type(cfg.devices[2]),
660
config.LibvirtConfigGuestConsole)
662
def test_get_guest_config_with_block_device(self):
663
conn = libvirt_driver.LibvirtDriver(True)
665
instance_ref = db.instance_create(self.context, self.test_instance)
666
conn_info = {'driver_volume_type': 'fake'}
667
info = {'block_device_mapping': [
668
{'connection_info': conn_info, 'mount_device': '/dev/vdc'},
669
{'connection_info': conn_info, 'mount_device': '/dev/vdd'}]}
671
cfg = conn.get_guest_config(instance_ref, [], None, None, info)
672
self.assertEquals(type(cfg.devices[2]),
673
config.LibvirtConfigGuestDisk)
674
self.assertEquals(cfg.devices[2].target_dev, 'vdc')
675
self.assertEquals(type(cfg.devices[3]),
676
config.LibvirtConfigGuestDisk)
677
self.assertEquals(cfg.devices[3].target_dev, 'vdd')
679
def test_get_guest_cpu_config_none(self):
680
self.flags(libvirt_cpu_mode="none")
681
conn = libvirt_driver.LibvirtDriver(True)
682
instance_ref = db.instance_create(self.context, self.test_instance)
684
conf = conn.get_guest_config(instance_ref,
685
_fake_network_info(self.stubs, 1),
687
self.assertEquals(conf.cpu, None)
689
def test_get_guest_cpu_config_default_kvm(self):
690
self.flags(libvirt_type="kvm",
691
libvirt_cpu_mode=None)
693
def get_lib_version_stub(self):
694
return (0 * 1000 * 1000) + (9 * 1000) + 11
696
self.stubs.Set(libvirt.virConnect,
698
get_lib_version_stub)
699
conn = libvirt_driver.LibvirtDriver(True)
700
instance_ref = db.instance_create(self.context, self.test_instance)
702
conf = conn.get_guest_config(instance_ref,
703
_fake_network_info(self.stubs, 1),
705
self.assertEquals(type(conf.cpu),
706
config.LibvirtConfigGuestCPU)
707
self.assertEquals(conf.cpu.mode, "host-model")
708
self.assertEquals(conf.cpu.model, None)
710
def test_get_guest_cpu_config_default_uml(self):
711
self.flags(libvirt_type="uml",
712
libvirt_cpu_mode=None)
714
conn = libvirt_driver.LibvirtDriver(True)
715
instance_ref = db.instance_create(self.context, self.test_instance)
717
conf = conn.get_guest_config(instance_ref,
718
_fake_network_info(self.stubs, 1),
720
self.assertEquals(conf.cpu, None)
722
def test_get_guest_cpu_config_default_lxc(self):
723
self.flags(libvirt_type="lxc",
724
libvirt_cpu_mode=None)
726
conn = libvirt_driver.LibvirtDriver(True)
727
instance_ref = db.instance_create(self.context, self.test_instance)
729
conf = conn.get_guest_config(instance_ref,
730
_fake_network_info(self.stubs, 1),
732
self.assertEquals(conf.cpu, None)
734
def test_get_guest_cpu_config_host_passthrough_new(self):
735
def get_lib_version_stub(self):
736
return (0 * 1000 * 1000) + (9 * 1000) + 11
738
self.stubs.Set(libvirt.virConnect,
740
get_lib_version_stub)
741
conn = libvirt_driver.LibvirtDriver(True)
742
instance_ref = db.instance_create(self.context, self.test_instance)
744
self.flags(libvirt_cpu_mode="host-passthrough")
745
conf = conn.get_guest_config(instance_ref,
746
_fake_network_info(self.stubs, 1),
748
self.assertEquals(type(conf.cpu),
749
config.LibvirtConfigGuestCPU)
750
self.assertEquals(conf.cpu.mode, "host-passthrough")
751
self.assertEquals(conf.cpu.model, None)
753
def test_get_guest_cpu_config_host_model_new(self):
754
def get_lib_version_stub(self):
755
return (0 * 1000 * 1000) + (9 * 1000) + 11
757
self.stubs.Set(libvirt.virConnect,
759
get_lib_version_stub)
760
conn = libvirt_driver.LibvirtDriver(True)
761
instance_ref = db.instance_create(self.context, self.test_instance)
763
self.flags(libvirt_cpu_mode="host-model")
764
conf = conn.get_guest_config(instance_ref,
765
_fake_network_info(self.stubs, 1),
767
self.assertEquals(type(conf.cpu),
768
config.LibvirtConfigGuestCPU)
769
self.assertEquals(conf.cpu.mode, "host-model")
770
self.assertEquals(conf.cpu.model, None)
772
def test_get_guest_cpu_config_custom_new(self):
773
def get_lib_version_stub(self):
774
return (0 * 1000 * 1000) + (9 * 1000) + 11
776
self.stubs.Set(libvirt.virConnect,
778
get_lib_version_stub)
779
conn = libvirt_driver.LibvirtDriver(True)
780
instance_ref = db.instance_create(self.context, self.test_instance)
782
self.flags(libvirt_cpu_mode="custom")
783
self.flags(libvirt_cpu_model="Penryn")
784
conf = conn.get_guest_config(instance_ref,
785
_fake_network_info(self.stubs, 1),
787
self.assertEquals(type(conf.cpu),
788
config.LibvirtConfigGuestCPU)
789
self.assertEquals(conf.cpu.mode, "custom")
790
self.assertEquals(conf.cpu.model, "Penryn")
792
def test_get_guest_cpu_config_host_passthrough_old(self):
793
def get_lib_version_stub(self):
794
return (0 * 1000 * 1000) + (9 * 1000) + 7
796
self.stubs.Set(libvirt.virConnect, "getLibVersion",
797
get_lib_version_stub)
798
conn = libvirt_driver.LibvirtDriver(True)
799
instance_ref = db.instance_create(self.context, self.test_instance)
801
self.flags(libvirt_cpu_mode="host-passthrough")
802
self.assertRaises(exception.NovaException,
803
conn.get_guest_config,
805
_fake_network_info(self.stubs, 1),
808
def test_get_guest_cpu_config_host_model_old(self):
809
def get_lib_version_stub(self):
810
return (0 * 1000 * 1000) + (9 * 1000) + 7
812
# Ensure we have a predictable host CPU
813
def get_host_capabilities_stub(self):
814
cpu = config.LibvirtConfigGuestCPU()
815
cpu.model = "Opteron_G4"
818
caps = config.LibvirtConfigCaps()
819
caps.host = config.LibvirtConfigCapsHost()
823
self.stubs.Set(libvirt.virConnect,
825
get_lib_version_stub)
826
self.stubs.Set(libvirt_driver.LibvirtDriver,
827
"get_host_capabilities",
828
get_host_capabilities_stub)
829
conn = libvirt_driver.LibvirtDriver(True)
830
instance_ref = db.instance_create(self.context, self.test_instance)
832
self.flags(libvirt_cpu_mode="host-model")
833
conf = conn.get_guest_config(instance_ref,
834
_fake_network_info(self.stubs, 1),
836
self.assertEquals(type(conf.cpu),
837
config.LibvirtConfigGuestCPU)
838
self.assertEquals(conf.cpu.mode, None)
839
self.assertEquals(conf.cpu.model, "Opteron_G4")
840
self.assertEquals(conf.cpu.vendor, "AMD")
842
def test_get_guest_cpu_config_custom_old(self):
843
def get_lib_version_stub(self):
844
return (0 * 1000 * 1000) + (9 * 1000) + 7
846
self.stubs.Set(libvirt.virConnect,
848
get_lib_version_stub)
849
conn = libvirt_driver.LibvirtDriver(True)
850
instance_ref = db.instance_create(self.context, self.test_instance)
852
self.flags(libvirt_cpu_mode="custom")
853
self.flags(libvirt_cpu_model="Penryn")
854
conf = conn.get_guest_config(instance_ref,
855
_fake_network_info(self.stubs, 1),
857
self.assertEquals(type(conf.cpu),
858
config.LibvirtConfigGuestCPU)
859
self.assertEquals(conf.cpu.mode, None)
860
self.assertEquals(conf.cpu.model, "Penryn")
862
def test_xml_and_uri_no_ramdisk_no_kernel(self):
863
instance_data = dict(self.test_instance)
864
self._check_xml_and_uri(instance_data,
865
expect_kernel=False, expect_ramdisk=False)
867
def test_xml_and_uri_no_ramdisk_no_kernel_xen_hvm(self):
868
instance_data = dict(self.test_instance)
869
instance_data.update({'vm_mode': vm_mode.HVM})
870
self._check_xml_and_uri(instance_data, expect_kernel=False,
871
expect_ramdisk=False, expect_xen_hvm=True)
873
def test_xml_and_uri_no_ramdisk_no_kernel_xen_pv(self):
874
instance_data = dict(self.test_instance)
875
instance_data.update({'vm_mode': vm_mode.XEN})
876
self._check_xml_and_uri(instance_data, expect_kernel=False,
877
expect_ramdisk=False, expect_xen_hvm=False,
880
def test_xml_and_uri_no_ramdisk(self):
881
instance_data = dict(self.test_instance)
882
instance_data['kernel_id'] = 'aki-deadbeef'
883
self._check_xml_and_uri(instance_data,
884
expect_kernel=True, expect_ramdisk=False)
886
def test_xml_and_uri_no_kernel(self):
887
instance_data = dict(self.test_instance)
888
instance_data['ramdisk_id'] = 'ari-deadbeef'
889
self._check_xml_and_uri(instance_data,
890
expect_kernel=False, expect_ramdisk=False)
892
def test_xml_and_uri(self):
893
instance_data = dict(self.test_instance)
894
instance_data['ramdisk_id'] = 'ari-deadbeef'
895
instance_data['kernel_id'] = 'aki-deadbeef'
896
self._check_xml_and_uri(instance_data,
897
expect_kernel=True, expect_ramdisk=True)
899
def test_xml_and_uri_rescue(self):
900
instance_data = dict(self.test_instance)
901
instance_data['ramdisk_id'] = 'ari-deadbeef'
902
instance_data['kernel_id'] = 'aki-deadbeef'
903
self._check_xml_and_uri(instance_data, expect_kernel=True,
904
expect_ramdisk=True, rescue=instance_data)
906
def test_xml_and_uri_rescue_no_kernel_no_ramdisk(self):
907
instance_data = dict(self.test_instance)
908
self._check_xml_and_uri(instance_data, expect_kernel=False,
909
expect_ramdisk=False, rescue=instance_data)
911
def test_xml_and_uri_rescue_no_kernel(self):
912
instance_data = dict(self.test_instance)
913
instance_data['ramdisk_id'] = 'aki-deadbeef'
914
self._check_xml_and_uri(instance_data, expect_kernel=False,
915
expect_ramdisk=True, rescue=instance_data)
917
def test_xml_and_uri_rescue_no_ramdisk(self):
918
instance_data = dict(self.test_instance)
919
instance_data['kernel_id'] = 'aki-deadbeef'
920
self._check_xml_and_uri(instance_data, expect_kernel=True,
921
expect_ramdisk=False, rescue=instance_data)
923
def test_xml_uuid(self):
924
instance_data = dict(self.test_instance)
925
self._check_xml_and_uuid(instance_data)
927
def test_lxc_container_and_uri(self):
928
instance_data = dict(self.test_instance)
929
self._check_xml_and_container(instance_data)
931
def test_xml_disk_prefix(self):
932
instance_data = dict(self.test_instance)
933
self._check_xml_and_disk_prefix(instance_data)
935
def test_xml_disk_driver(self):
936
instance_data = dict(self.test_instance)
937
self._check_xml_and_disk_driver(instance_data)
939
def test_xml_disk_bus_virtio(self):
940
self._check_xml_and_disk_bus({"disk_format": "raw"},
942
(("disk", "virtio", "vda"),))
944
def test_xml_disk_bus_ide(self):
945
self._check_xml_and_disk_bus({"disk_format": "iso"},
947
(("cdrom", "ide", "hda"),))
949
def test_xml_disk_bus_ide_and_virtio(self):
950
swap = {'device_name': '/dev/vdc',
952
ephemerals = [{'num': 0,
953
'virtual_name': 'ephemeral0',
954
'device_name': '/dev/vdb',
956
block_device_info = {
958
'ephemerals': ephemerals}
960
self._check_xml_and_disk_bus({"disk_format": "iso"},
962
(("cdrom", "ide", "hda"),
963
("disk", "virtio", "vdb"),
964
("disk", "virtio", "vdc")))
966
def test_list_instances(self):
967
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
968
libvirt_driver.LibvirtDriver._conn.lookupByID = self.fake_lookup
969
libvirt_driver.LibvirtDriver._conn.numOfDomains = lambda: 2
970
libvirt_driver.LibvirtDriver._conn.listDomainsID = lambda: [0, 1]
973
conn = libvirt_driver.LibvirtDriver(False)
974
instances = conn.list_instances()
975
# Only one should be listed, since domain with ID 0 must be skiped
976
self.assertEquals(len(instances), 1)
978
def test_list_instances_when_instance_deleted(self):
980
def fake_lookup(instance_name):
981
raise libvirt.libvirtError("we deleted an instance!")
983
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
984
libvirt_driver.LibvirtDriver._conn.lookupByID = fake_lookup
985
libvirt_driver.LibvirtDriver._conn.numOfDomains = lambda: 1
986
libvirt_driver.LibvirtDriver._conn.listDomainsID = lambda: [0, 1]
989
conn = libvirt_driver.LibvirtDriver(False)
990
instances = conn.list_instances()
991
# None should be listed, since we fake deleted the last one
992
self.assertEquals(len(instances), 0)
994
def test_get_all_block_devices(self):
996
# NOTE(vish): id 0 is skipped
1002
<source file='filename'/>
1005
<source dev='/path/to/dev/1'/>
1014
<source file='filename'/>
1023
<source file='filename'/>
1026
<source dev='/path/to/dev/3'/>
1033
def fake_lookup(id):
1034
return FakeVirtDomain(xml[id])
1036
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
1037
libvirt_driver.LibvirtDriver._conn.numOfDomains = lambda: 4
1038
libvirt_driver.LibvirtDriver._conn.listDomainsID = lambda: range(4)
1039
libvirt_driver.LibvirtDriver._conn.lookupByID = fake_lookup
1041
self.mox.ReplayAll()
1042
conn = libvirt_driver.LibvirtDriver(False)
1043
devices = conn.get_all_block_devices()
1044
self.assertEqual(devices, ['/path/to/dev/1', '/path/to/dev/3'])
1046
def test_get_disks(self):
1048
# NOTE(vish): id 0 is skipped
1054
<source file='filename'/>
1055
<target dev='vda' bus='virtio'/>
1058
<source dev='/path/to/dev/1'/>
1059
<target dev='vdb' bus='virtio'/>
1068
<source file='filename'/>
1069
<target dev='vda' bus='virtio'/>
1078
<source file='filename'/>
1079
<target dev='vda' bus='virtio'/>
1082
<source dev='/path/to/dev/3'/>
1083
<target dev='vdb' bus='virtio'/>
1090
def fake_lookup(id):
1091
return FakeVirtDomain(xml[id])
1093
def fake_lookup_name(name):
1094
return FakeVirtDomain(xml[1])
1096
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
1097
libvirt_driver.LibvirtDriver._conn.numOfDomains = lambda: 4
1098
libvirt_driver.LibvirtDriver._conn.listDomainsID = lambda: range(4)
1099
libvirt_driver.LibvirtDriver._conn.lookupByID = fake_lookup
1100
libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
1102
self.mox.ReplayAll()
1103
conn = libvirt_driver.LibvirtDriver(False)
1104
devices = conn.get_disks(conn.list_instances()[0])
1105
self.assertEqual(devices, ['vda', 'vdb'])
1107
def test_snapshot_in_ami_format(self):
1108
self.flags(libvirt_snapshots_directory='./')
1111
image_service = nova.tests.image.fake.FakeImageService()
1113
# Assign different image_ref from nova/images/fakes for testing ami
1114
test_instance = copy.deepcopy(self.test_instance)
1115
test_instance["image_ref"] = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
1117
# Assuming that base image already exists in image_service
1118
instance_ref = db.instance_create(self.context, test_instance)
1119
properties = {'instance_id': instance_ref['id'],
1120
'user_id': str(self.context.user_id)}
1121
snapshot_name = 'test-snap'
1122
sent_meta = {'name': snapshot_name, 'is_public': False,
1123
'status': 'creating', 'properties': properties}
1124
# Create new image. It will be updated in snapshot method
1125
# To work with it from snapshot, the single image_service is needed
1126
recv_meta = image_service.create(context, sent_meta)
1128
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
1129
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
1130
self.mox.StubOutWithMock(libvirt_driver.utils, 'execute')
1131
libvirt_driver.utils.execute = self.fake_execute
1133
self.mox.ReplayAll()
1135
conn = libvirt_driver.LibvirtDriver(False)
1136
conn.snapshot(self.context, instance_ref, recv_meta['id'])
1138
snapshot = image_service.show(context, recv_meta['id'])
1139
self.assertEquals(snapshot['properties']['image_state'], 'available')
1140
self.assertEquals(snapshot['status'], 'active')
1141
self.assertEquals(snapshot['disk_format'], 'ami')
1142
self.assertEquals(snapshot['name'], snapshot_name)
1144
def test_snapshot_in_raw_format(self):
1145
self.flags(libvirt_snapshots_directory='./')
1148
image_service = nova.tests.image.fake.FakeImageService()
1150
# Assuming that base image already exists in image_service
1151
instance_ref = db.instance_create(self.context, self.test_instance)
1152
properties = {'instance_id': instance_ref['id'],
1153
'user_id': str(self.context.user_id)}
1154
snapshot_name = 'test-snap'
1155
sent_meta = {'name': snapshot_name, 'is_public': False,
1156
'status': 'creating', 'properties': properties}
1157
# Create new image. It will be updated in snapshot method
1158
# To work with it from snapshot, the single image_service is needed
1159
recv_meta = image_service.create(context, sent_meta)
1161
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
1162
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
1163
self.mox.StubOutWithMock(libvirt_driver.utils, 'execute')
1164
libvirt_driver.utils.execute = self.fake_execute
1166
self.mox.ReplayAll()
1168
conn = libvirt_driver.LibvirtDriver(False)
1169
conn.snapshot(self.context, instance_ref, recv_meta['id'])
1171
snapshot = image_service.show(context, recv_meta['id'])
1172
self.assertEquals(snapshot['properties']['image_state'], 'available')
1173
self.assertEquals(snapshot['status'], 'active')
1174
self.assertEquals(snapshot['disk_format'], 'raw')
1175
self.assertEquals(snapshot['name'], snapshot_name)
1177
def test_snapshot_in_qcow2_format(self):
1178
self.flags(snapshot_image_format='qcow2',
1179
libvirt_snapshots_directory='./')
1182
image_service = nova.tests.image.fake.FakeImageService()
1184
# Assuming that base image already exists in image_service
1185
instance_ref = db.instance_create(self.context, self.test_instance)
1186
properties = {'instance_id': instance_ref['id'],
1187
'user_id': str(self.context.user_id)}
1188
snapshot_name = 'test-snap'
1189
sent_meta = {'name': snapshot_name, 'is_public': False,
1190
'status': 'creating', 'properties': properties}
1191
# Create new image. It will be updated in snapshot method
1192
# To work with it from snapshot, the single image_service is needed
1193
recv_meta = image_service.create(context, sent_meta)
1195
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
1196
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
1197
self.mox.StubOutWithMock(libvirt_driver.utils, 'execute')
1198
libvirt_driver.utils.execute = self.fake_execute
1200
self.mox.ReplayAll()
1202
conn = libvirt_driver.LibvirtDriver(False)
1203
conn.snapshot(self.context, instance_ref, recv_meta['id'])
1205
snapshot = image_service.show(context, recv_meta['id'])
1206
self.assertEquals(snapshot['properties']['image_state'], 'available')
1207
self.assertEquals(snapshot['status'], 'active')
1208
self.assertEquals(snapshot['disk_format'], 'qcow2')
1209
self.assertEquals(snapshot['name'], snapshot_name)
1211
def test_snapshot_no_image_architecture(self):
1212
self.flags(libvirt_snapshots_directory='./')
1215
image_service = nova.tests.image.fake.FakeImageService()
1217
# Assign different image_ref from nova/images/fakes for
1218
# testing different base image
1219
test_instance = copy.deepcopy(self.test_instance)
1220
test_instance["image_ref"] = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1222
# Assuming that base image already exists in image_service
1223
instance_ref = db.instance_create(self.context, test_instance)
1224
properties = {'instance_id': instance_ref['id'],
1225
'user_id': str(self.context.user_id)}
1226
snapshot_name = 'test-snap'
1227
sent_meta = {'name': snapshot_name, 'is_public': False,
1228
'status': 'creating', 'properties': properties}
1229
# Create new image. It will be updated in snapshot method
1230
# To work with it from snapshot, the single image_service is needed
1231
recv_meta = image_service.create(context, sent_meta)
1233
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
1234
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
1235
self.mox.StubOutWithMock(libvirt_driver.utils, 'execute')
1236
libvirt_driver.utils.execute = self.fake_execute
1238
self.mox.ReplayAll()
1240
conn = libvirt_driver.LibvirtDriver(False)
1241
conn.snapshot(self.context, instance_ref, recv_meta['id'])
1243
snapshot = image_service.show(context, recv_meta['id'])
1244
self.assertEquals(snapshot['properties']['image_state'], 'available')
1245
self.assertEquals(snapshot['status'], 'active')
1246
self.assertEquals(snapshot['name'], snapshot_name)
1248
def test_snapshot_no_original_image(self):
1249
self.flags(libvirt_snapshots_directory='./')
1252
image_service = nova.tests.image.fake.FakeImageService()
1254
# Assign a non-existent image
1255
test_instance = copy.deepcopy(self.test_instance)
1256
test_instance["image_ref"] = '661122aa-1234-dede-fefe-babababababa'
1258
instance_ref = db.instance_create(self.context, test_instance)
1259
properties = {'instance_id': instance_ref['id'],
1260
'user_id': str(self.context.user_id)}
1261
snapshot_name = 'test-snap'
1262
sent_meta = {'name': snapshot_name, 'is_public': False,
1263
'status': 'creating', 'properties': properties}
1264
recv_meta = image_service.create(context, sent_meta)
1266
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
1267
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
1268
self.mox.StubOutWithMock(libvirt_driver.utils, 'execute')
1269
libvirt_driver.utils.execute = self.fake_execute
1271
self.mox.ReplayAll()
1273
conn = libvirt_driver.LibvirtDriver(False)
1274
conn.snapshot(self.context, instance_ref, recv_meta['id'])
1276
snapshot = image_service.show(context, recv_meta['id'])
1277
self.assertEquals(snapshot['properties']['image_state'], 'available')
1278
self.assertEquals(snapshot['status'], 'active')
1279
self.assertEquals(snapshot['name'], snapshot_name)
1281
def test_attach_invalid_volume_type(self):
1282
self.create_fake_libvirt_mock()
1283
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
1284
self.mox.ReplayAll()
1285
conn = libvirt_driver.LibvirtDriver(False)
1286
self.assertRaises(exception.VolumeDriverNotFound,
1288
{"driver_volume_type": "badtype"},
1292
def test_multi_nic(self):
1293
instance_data = dict(self.test_instance)
1294
network_info = _fake_network_info(self.stubs, 2)
1295
conn = libvirt_driver.LibvirtDriver(True)
1296
instance_ref = db.instance_create(self.context, instance_data)
1297
xml = conn.to_xml(instance_ref, network_info, None, False)
1298
tree = etree.fromstring(xml)
1299
interfaces = tree.findall("./devices/interface")
1300
self.assertEquals(len(interfaces), 2)
1301
parameters = interfaces[0].findall('./filterref/parameter')
1302
self.assertEquals(interfaces[0].get('type'), 'bridge')
1303
self.assertEquals(parameters[0].get('name'), 'IP')
1304
self.assertTrue(_ipv4_like(parameters[0].get('value'), '192.168'))
1306
def _check_xml_and_container(self, instance):
1307
user_context = context.RequestContext(self.user_id,
1309
instance_ref = db.instance_create(user_context, instance)
1311
self.flags(libvirt_type='lxc')
1312
conn = libvirt_driver.LibvirtDriver(True)
1314
self.assertEquals(conn.uri, 'lxc:///')
1316
network_info = _fake_network_info(self.stubs, 1)
1317
xml = conn.to_xml(instance_ref, network_info)
1318
tree = etree.fromstring(xml)
1321
(lambda t: t.find('.').get('type'), 'lxc'),
1322
(lambda t: t.find('./os/type').text, 'exe'),
1323
(lambda t: t.find('./devices/filesystem/target').get('dir'), '/')]
1325
for i, (check, expected_result) in enumerate(check):
1326
self.assertEqual(check(tree),
1328
'%s failed common check %d' % (xml, i))
1330
target = tree.find('./devices/filesystem/source').get('dir')
1331
self.assertTrue(len(target) > 0)
1333
def _check_xml_and_disk_prefix(self, instance):
1334
user_context = context.RequestContext(self.user_id,
1336
instance_ref = db.instance_create(user_context, instance)
1340
(lambda t: t.find('.').get('type'), 'qemu'),
1341
(lambda t: t.find('./devices/disk/target').get('dev'), 'vda')],
1343
(lambda t: t.find('.').get('type'), 'xen'),
1344
(lambda t: t.find('./devices/disk/target').get('dev'), 'sda')],
1346
(lambda t: t.find('.').get('type'), 'kvm'),
1347
(lambda t: t.find('./devices/disk/target').get('dev'), 'vda')],
1349
(lambda t: t.find('.').get('type'), 'uml'),
1350
(lambda t: t.find('./devices/disk/target').get('dev'), 'ubda')]
1353
for (libvirt_type, checks) in type_disk_map.iteritems():
1354
self.flags(libvirt_type=libvirt_type)
1355
conn = libvirt_driver.LibvirtDriver(True)
1357
network_info = _fake_network_info(self.stubs, 1)
1358
xml = conn.to_xml(instance_ref, network_info)
1359
tree = etree.fromstring(xml)
1361
for i, (check, expected_result) in enumerate(checks):
1362
self.assertEqual(check(tree),
1364
'%s != %s failed check %d' %
1365
(check(tree), expected_result, i))
1367
def _check_xml_and_disk_driver(self, image_meta):
1369
directio_supported = True
1371
def os_open_stub(path, flags, *args, **kwargs):
1372
if flags & os.O_DIRECT:
1373
if not directio_supported:
1374
raise OSError(errno.EINVAL,
1375
'%s: %s' % (os.strerror(errno.EINVAL), path))
1376
flags &= ~os.O_DIRECT
1377
return os_open(path, flags, *args, **kwargs)
1379
self.stubs.Set(os, 'open', os_open_stub)
1381
def connection_supports_direct_io_stub(*args, **kwargs):
1382
return directio_supported
1384
self.stubs.Set(libvirt_driver.LibvirtDriver,
1385
'_supports_direct_io', connection_supports_direct_io_stub)
1387
user_context = context.RequestContext(self.user_id, self.project_id)
1388
instance_ref = db.instance_create(user_context, self.test_instance)
1389
network_info = _fake_network_info(self.stubs, 1)
1391
xml = libvirt_driver.LibvirtDriver(True).to_xml(instance_ref,
1394
tree = etree.fromstring(xml)
1395
disks = tree.findall('./devices/disk/driver')
1397
self.assertEqual(disk.get("cache"), "none")
1399
directio_supported = False
1401
# The O_DIRECT availability is cached on first use in
1402
# LibvirtDriver, hence we re-create it here
1403
xml = libvirt_driver.LibvirtDriver(True).to_xml(instance_ref,
1406
tree = etree.fromstring(xml)
1407
disks = tree.findall('./devices/disk/driver')
1409
self.assertEqual(disk.get("cache"), "writethrough")
1411
def _check_xml_and_disk_bus(self, image_meta,
1412
block_device_info, wantConfig):
1413
user_context = context.RequestContext(self.user_id, self.project_id)
1414
instance_ref = db.instance_create(user_context, self.test_instance)
1415
network_info = _fake_network_info(self.stubs, 1)
1417
xml = libvirt_driver.LibvirtDriver(True).to_xml(
1421
block_device_info=block_device_info)
1422
tree = etree.fromstring(xml)
1424
got_disks = tree.findall('./devices/disk')
1425
got_disk_targets = tree.findall('./devices/disk/target')
1426
for i in range(len(wantConfig)):
1427
want_device_type = wantConfig[i][0]
1428
want_device_bus = wantConfig[i][1]
1429
want_device_dev = wantConfig[i][2]
1431
got_device_type = got_disks[i].get('device')
1432
got_device_bus = got_disk_targets[i].get('bus')
1433
got_device_dev = got_disk_targets[i].get('dev')
1435
self.assertEqual(got_device_type, want_device_type)
1436
self.assertEqual(got_device_bus, want_device_bus)
1437
self.assertEqual(got_device_dev, want_device_dev)
1439
def _check_xml_and_uuid(self, image_meta):
1440
user_context = context.RequestContext(self.user_id, self.project_id)
1441
instance_ref = db.instance_create(user_context, self.test_instance)
1442
network_info = _fake_network_info(self.stubs, 1)
1444
xml = libvirt_driver.LibvirtDriver(True).to_xml(instance_ref,
1447
tree = etree.fromstring(xml)
1448
self.assertEqual(tree.find('./uuid').text,
1449
instance_ref['uuid'])
1451
def _check_xml_and_uri(self, instance, expect_ramdisk, expect_kernel,
1452
rescue=None, expect_xen_hvm=False, xen_only=False):
1453
user_context = context.RequestContext(self.user_id, self.project_id)
1454
instance_ref = db.instance_create(user_context, instance)
1455
network_ref = db.project_get_networks(context.get_admin_context(),
1458
type_uri_map = {'qemu': ('qemu:///system',
1459
[(lambda t: t.find('.').get('type'), 'qemu'),
1460
(lambda t: t.find('./os/type').text,
1462
(lambda t: t.find('./devices/emulator'), None)]),
1463
'kvm': ('qemu:///system',
1464
[(lambda t: t.find('.').get('type'), 'kvm'),
1465
(lambda t: t.find('./os/type').text,
1467
(lambda t: t.find('./devices/emulator'), None)]),
1468
'uml': ('uml:///system',
1469
[(lambda t: t.find('.').get('type'), 'uml'),
1470
(lambda t: t.find('./os/type').text,
1473
[(lambda t: t.find('.').get('type'), 'xen'),
1474
(lambda t: t.find('./os/type').text,
1477
if expect_xen_hvm or xen_only:
1478
hypervisors_to_check = ['xen']
1480
hypervisors_to_check = ['qemu', 'kvm', 'xen']
1484
type_uri_map['xen'] = ('xen:///',
1485
[(lambda t: t.find('.').get('type'),
1487
(lambda t: t.find('./os/type').text,
1490
for hypervisor_type in hypervisors_to_check:
1491
check_list = type_uri_map[hypervisor_type][1]
1498
check = (lambda t: t.find('./os/kernel').text.split(
1499
'/')[1], 'kernel' + suffix)
1501
check = (lambda t: t.find('./os/kernel'), None)
1502
check_list.append(check)
1504
# Hypervisors that only support vm_mode.HVM should
1505
# not produce configuration that results in kernel
1507
if not expect_kernel and hypervisor_type in ['qemu', 'kvm']:
1508
check = (lambda t: t.find('./os/root'), None)
1509
check_list.append(check)
1510
check = (lambda t: t.find('./os/cmdline'), None)
1511
check_list.append(check)
1514
check = (lambda t: t.find('./os/initrd').text.split(
1515
'/')[1], 'ramdisk' + suffix)
1517
check = (lambda t: t.find('./os/initrd'), None)
1518
check_list.append(check)
1520
if hypervisor_type in ['qemu', 'kvm']:
1521
check = (lambda t: t.findall('./devices/serial')[0].get(
1523
check_list.append(check)
1524
check = (lambda t: t.findall('./devices/serial')[1].get(
1526
check_list.append(check)
1527
check = (lambda t: t.findall('./devices/serial/source')[0].get(
1528
'path').split('/')[1], 'console.log')
1529
check_list.append(check)
1531
check = (lambda t: t.find('./devices/console').get(
1533
check_list.append(check)
1535
parameter = './devices/interface/filterref/parameter'
1537
(lambda t: t.find('.').tag, 'domain'),
1538
(lambda t: t.find(parameter).get('name'), 'IP'),
1539
(lambda t: _ipv4_like(t.find(parameter).get('value'), '192.168'),
1541
(lambda t: t.find('./memory').text, '2097152')]
1544
(lambda t: t.findall('./devices/disk/source')[0].get(
1545
'file').split('/')[1], 'disk.rescue'),
1546
(lambda t: t.findall('./devices/disk/source')[1].get(
1547
'file').split('/')[1], 'disk')]
1549
common_checks += [(lambda t: t.findall(
1550
'./devices/disk/source')[0].get('file').split('/')[1],
1552
common_checks += [(lambda t: t.findall(
1553
'./devices/disk/source')[1].get('file').split('/')[1],
1556
for (libvirt_type, (expected_uri, checks)) in type_uri_map.iteritems():
1557
self.flags(libvirt_type=libvirt_type)
1558
conn = libvirt_driver.LibvirtDriver(True)
1560
self.assertEquals(conn.uri, expected_uri)
1562
network_info = _fake_network_info(self.stubs, 1)
1563
xml = conn.to_xml(instance_ref, network_info, None, rescue)
1564
tree = etree.fromstring(xml)
1565
for i, (check, expected_result) in enumerate(checks):
1566
self.assertEqual(check(tree),
1568
'%s != %s failed check %d' %
1569
(check(tree), expected_result, i))
1571
for i, (check, expected_result) in enumerate(common_checks):
1572
self.assertEqual(check(tree),
1574
'%s != %s failed common check %d' %
1575
(check(tree), expected_result, i))
1577
# This test is supposed to make sure we don't
1578
# override a specifically set uri
1580
# Deliberately not just assigning this string to FLAGS.libvirt_uri and
1581
# checking against that later on. This way we make sure the
1582
# implementation doesn't fiddle around with the FLAGS.
1583
testuri = 'something completely different'
1584
self.flags(libvirt_uri=testuri)
1585
for (libvirt_type, (expected_uri, checks)) in type_uri_map.iteritems():
1586
self.flags(libvirt_type=libvirt_type)
1587
conn = libvirt_driver.LibvirtDriver(True)
1588
self.assertEquals(conn.uri, testuri)
1589
db.instance_destroy(user_context, instance_ref['uuid'])
1591
def test_ensure_filtering_rules_for_instance_timeout(self):
1592
"""ensure_filtering_fules_for_instance() finishes with timeout."""
1594
def fake_none(self, *args):
1597
def fake_raise(self):
1598
raise libvirt.libvirtError('ERR')
1600
class FakeTime(object):
1607
fake_timer = FakeTime()
1609
# _fake_network_info must be called before create_fake_libvirt_mock(),
1610
# as _fake_network_info calls importutils.import_class() and
1611
# create_fake_libvirt_mock() mocks importutils.import_class().
1612
network_info = _fake_network_info(self.stubs, 1)
1613
self.create_fake_libvirt_mock()
1614
instance_ref = db.instance_create(self.context, self.test_instance)
1617
self.mox.ReplayAll()
1619
conn = libvirt_driver.LibvirtDriver(False)
1620
self.stubs.Set(conn.firewall_driver,
1621
'setup_basic_filtering',
1623
self.stubs.Set(conn.firewall_driver,
1624
'prepare_instance_filter',
1626
self.stubs.Set(conn.firewall_driver,
1627
'instance_filter_exists',
1629
conn.ensure_filtering_rules_for_instance(instance_ref,
1631
time_module=fake_timer)
1632
except exception.NovaException, e:
1633
msg = ('The firewall filter for %s does not exist' %
1634
instance_ref['name'])
1635
c1 = (0 <= str(e).find(msg))
1638
self.assertEqual(29, fake_timer.counter, "Didn't wait the expected "
1641
db.instance_destroy(self.context, instance_ref['uuid'])
1643
def test_check_can_live_migrate_dest_all_pass_with_block_migration(self):
1644
instance_ref = db.instance_create(self.context, self.test_instance)
1645
dest = "fake_host_2"
1646
src = instance_ref['host']
1647
conn = libvirt_driver.LibvirtDriver(False)
1649
self.mox.StubOutWithMock(conn, '_get_compute_info')
1650
self.mox.StubOutWithMock(conn, '_create_shared_storage_test_file')
1651
self.mox.StubOutWithMock(conn, '_compare_cpu')
1653
conn._get_compute_info(self.context, FLAGS.host).AndReturn(
1654
{'disk_available_least': 400})
1656
conn._get_compute_info(self.context,
1657
src).AndReturn({'cpu_info': "asdf"})
1658
conn._compare_cpu("asdf")
1660
# mounted_on_same_shared_storage
1662
conn._create_shared_storage_test_file().AndReturn(filename)
1664
self.mox.ReplayAll()
1665
return_value = conn.check_can_live_migrate_destination(self.context,
1667
self.assertDictMatch(return_value,
1668
{"filename": "file",
1669
'disk_available_mb': 409600,
1670
"disk_over_commit": False,
1671
"block_migration": True})
1673
def test_check_can_live_migrate_dest_all_pass_no_block_migration(self):
1674
instance_ref = db.instance_create(self.context, self.test_instance)
1675
dest = "fake_host_2"
1676
src = instance_ref['host']
1677
conn = libvirt_driver.LibvirtDriver(False)
1679
self.mox.StubOutWithMock(conn, '_get_compute_info')
1680
self.mox.StubOutWithMock(conn, '_create_shared_storage_test_file')
1681
self.mox.StubOutWithMock(conn, '_compare_cpu')
1684
conn._get_compute_info(self.context,
1685
src).AndReturn({'cpu_info': "asdf"})
1686
conn._compare_cpu("asdf")
1688
# mounted_on_same_shared_storage
1690
conn._create_shared_storage_test_file().AndReturn(filename)
1692
self.mox.ReplayAll()
1693
return_value = conn.check_can_live_migrate_destination(self.context,
1694
instance_ref, False)
1695
self.assertDictMatch(return_value,
1696
{"filename": "file",
1697
"block_migration": False,
1698
"disk_over_commit": False,
1699
"disk_available_mb": None})
1701
def test_check_can_live_migrate_dest_incompatible_cpu_raises(self):
1702
instance_ref = db.instance_create(self.context, self.test_instance)
1703
dest = "fake_host_2"
1704
src = instance_ref['host']
1705
conn = libvirt_driver.LibvirtDriver(False)
1707
self.mox.StubOutWithMock(conn, '_get_compute_info')
1708
self.mox.StubOutWithMock(conn, '_compare_cpu')
1710
conn._get_compute_info(self.context, src).AndReturn(
1711
{'cpu_info': "asdf"})
1712
conn._compare_cpu("asdf").AndRaise(exception.InvalidCPUInfo)
1714
self.mox.ReplayAll()
1715
self.assertRaises(exception.InvalidCPUInfo,
1716
conn.check_can_live_migrate_destination,
1717
self.context, instance_ref, False)
1719
def test_check_can_live_migrate_dest_cleanup_works_correctly(self):
1720
instance_ref = db.instance_create(self.context, self.test_instance)
1721
dest_check_data = {"filename": "file",
1722
"block_migration": True,
1723
"disk_over_commit": False,
1724
"disk_available_mb": 1024}
1725
conn = libvirt_driver.LibvirtDriver(False)
1727
self.mox.StubOutWithMock(conn, '_cleanup_shared_storage_test_file')
1728
conn._cleanup_shared_storage_test_file("file")
1730
self.mox.ReplayAll()
1731
conn.check_can_live_migrate_destination_cleanup(self.context,
1734
def test_check_can_live_migrate_source_works_correctly(self):
1735
instance_ref = db.instance_create(self.context, self.test_instance)
1736
dest_check_data = {"filename": "file",
1737
"block_migration": True,
1738
"disk_over_commit": False,
1739
"disk_available_mb": 1024}
1740
conn = libvirt_driver.LibvirtDriver(False)
1742
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
1743
conn._check_shared_storage_test_file("file").AndReturn(False)
1745
self.mox.StubOutWithMock(conn, "_assert_dest_node_has_enough_disk")
1746
conn._assert_dest_node_has_enough_disk(self.context, instance_ref,
1747
dest_check_data['disk_available_mb'],
1750
self.mox.ReplayAll()
1751
conn.check_can_live_migrate_source(self.context, instance_ref,
1754
def test_check_can_live_migrate_dest_fail_shared_storage_with_blockm(self):
1755
instance_ref = db.instance_create(self.context, self.test_instance)
1756
dest_check_data = {"filename": "file",
1757
"block_migration": True,
1758
"disk_over_commit": False,
1759
'disk_available_mb': 1024}
1760
conn = libvirt_driver.LibvirtDriver(False)
1762
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
1763
conn._check_shared_storage_test_file("file").AndReturn(True)
1765
self.mox.ReplayAll()
1766
self.assertRaises(exception.InvalidLocalStorage,
1767
conn.check_can_live_migrate_source,
1768
self.context, instance_ref, dest_check_data)
1770
def test_check_can_live_migrate_no_shared_storage_no_blck_mig_raises(self):
1771
instance_ref = db.instance_create(self.context, self.test_instance)
1772
dest_check_data = {"filename": "file",
1773
"block_migration": False,
1774
"disk_over_commit": False,
1775
'disk_available_mb': 1024}
1776
conn = libvirt_driver.LibvirtDriver(False)
1778
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
1779
conn._check_shared_storage_test_file("file").AndReturn(False)
1781
self.mox.ReplayAll()
1782
self.assertRaises(exception.InvalidSharedStorage,
1783
conn.check_can_live_migrate_source,
1784
self.context, instance_ref, dest_check_data)
1786
def test_check_can_live_migrate_source_with_dest_not_enough_disk(self):
1787
instance_ref = db.instance_create(self.context, self.test_instance)
1788
dest = "fake_host_2"
1789
src = instance_ref['host']
1790
conn = libvirt_driver.LibvirtDriver(False)
1792
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
1793
conn._check_shared_storage_test_file("file").AndReturn(False)
1795
self.mox.StubOutWithMock(conn, "get_instance_disk_info")
1796
conn.get_instance_disk_info(instance_ref["name"]).AndReturn(
1797
'[{"virt_disk_size":2}]')
1799
dest_check_data = {"filename": "file",
1800
"disk_available_mb": 0,
1801
"block_migration": True,
1802
"disk_over_commit": False}
1803
self.mox.ReplayAll()
1804
self.assertRaises(exception.MigrationError,
1805
conn.check_can_live_migrate_source,
1806
self.context, instance_ref, dest_check_data)
1808
def test_live_migration_raises_exception(self):
1809
"""Confirms recover method is called when exceptions are raised."""
1811
self.compute = importutils.import_object(FLAGS.compute_manager)
1812
instance_dict = {'host': 'fake',
1813
'power_state': power_state.RUNNING,
1814
'vm_state': vm_states.ACTIVE}
1815
instance_ref = db.instance_create(self.context, self.test_instance)
1816
instance_ref = db.instance_update(self.context, instance_ref['uuid'],
1818
vol_dict = {'status': 'migrating', 'size': 1}
1819
volume_ref = db.volume_create(self.context, vol_dict)
1820
db.volume_attached(self.context,
1822
instance_ref['uuid'],
1826
vdmock = self.mox.CreateMock(libvirt.virDomain)
1827
self.mox.StubOutWithMock(vdmock, "migrateToURI")
1828
_bandwidth = FLAGS.live_migration_bandwidth
1829
vdmock.migrateToURI(FLAGS.live_migration_uri % 'dest',
1832
_bandwidth).AndRaise(libvirt.libvirtError('ERR'))
1834
def fake_lookup(instance_name):
1835
if instance_name == instance_ref.name:
1838
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
1839
self.mox.StubOutWithMock(self.compute, "_rollback_live_migration")
1840
self.compute._rollback_live_migration(self.context, instance_ref,
1844
self.mox.ReplayAll()
1845
conn = libvirt_driver.LibvirtDriver(False)
1846
self.assertRaises(libvirt.libvirtError,
1847
conn._live_migration,
1848
self.context, instance_ref, 'dest', False,
1849
self.compute._rollback_live_migration)
1851
instance_ref = db.instance_get(self.context, instance_ref['id'])
1852
self.assertTrue(instance_ref['vm_state'] == vm_states.ACTIVE)
1853
self.assertTrue(instance_ref['power_state'] == power_state.RUNNING)
1854
volume_ref = db.volume_get(self.context, volume_ref['id'])
1855
self.assertTrue(volume_ref['status'] == 'in-use')
1857
db.volume_destroy(self.context, volume_ref['id'])
1858
db.instance_destroy(self.context, instance_ref['uuid'])
1860
def test_pre_live_migration_works_correctly_mocked(self):
1862
vol = {'block_device_mapping': [
1863
{'connection_info': 'dummy', 'mount_device': '/dev/sda'},
1864
{'connection_info': 'dummy', 'mount_device': '/dev/sdb'}]}
1865
conn = libvirt_driver.LibvirtDriver(False)
1867
class FakeNetworkInfo():
1868
def fixed_ips(self):
1869
return ["test_ip_addr"]
1871
inst_ref = {'id': 'foo'}
1872
c = context.get_admin_context()
1873
nw_info = FakeNetworkInfo()
1876
self.mox.StubOutWithMock(driver, "block_device_info_get_mapping")
1877
driver.block_device_info_get_mapping(vol
1878
).AndReturn(vol['block_device_mapping'])
1879
self.mox.StubOutWithMock(conn, "volume_driver_method")
1880
for v in vol['block_device_mapping']:
1881
conn.volume_driver_method('connect_volume',
1882
v['connection_info'],
1883
v['mount_device'].rpartition("/")[2])
1884
self.mox.StubOutWithMock(conn, 'plug_vifs')
1885
conn.plug_vifs(mox.IsA(inst_ref), nw_info)
1887
self.mox.ReplayAll()
1888
result = conn.pre_live_migration(c, inst_ref, vol, nw_info)
1889
self.assertEqual(result, None)
1891
def test_pre_block_migration_works_correctly(self):
1892
# Replace instances_path since this testcase creates tmpfile
1893
with utils.tempdir() as tmpdir:
1894
self.flags(instances_path=tmpdir)
1897
instance_ref = db.instance_create(self.context, self.test_instance)
1898
dummy_info = [{'path': '%s/disk' % tmpdir,
1899
'disk_size': 10737418240,
1901
'backing_file': ''},
1902
{'backing_file': 'otherdisk_1234567',
1903
'path': '%s/otherdisk' % tmpdir,
1904
'virt_disk_size': 10737418240}]
1905
dummyjson = json.dumps(dummy_info)
1907
# qemu-img should be mockd since test environment might not have
1909
self.mox.StubOutWithMock(imagebackend.Image, 'cache')
1910
imagebackend.Image.cache(context=mox.IgnoreArg(),
1911
fetch_func=mox.IgnoreArg(),
1912
filename='otherdisk',
1916
user_id=None).AndReturn(None)
1917
self.mox.ReplayAll()
1919
conn = libvirt_driver.LibvirtDriver(False)
1920
conn.pre_block_migration(self.context, instance_ref,
1923
self.assertTrue(os.path.exists('%s/%s/' %
1924
(tmpdir, instance_ref.name)))
1926
db.instance_destroy(self.context, instance_ref['uuid'])
1928
def test_get_instance_disk_info_works_correctly(self):
1930
instance_ref = db.instance_create(self.context, self.test_instance)
1931
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
1933
"<disk type='file'><driver name='qemu' type='raw'/>"
1934
"<source file='/test/disk'/>"
1935
"<target dev='vda' bus='virtio'/></disk>"
1936
"<disk type='file'><driver name='qemu' type='qcow2'/>"
1937
"<source file='/test/disk.local'/>"
1938
"<target dev='vdb' bus='virtio'/></disk>"
1939
"</devices></domain>")
1942
vdmock = self.mox.CreateMock(libvirt.virDomain)
1943
self.mox.StubOutWithMock(vdmock, "XMLDesc")
1944
vdmock.XMLDesc(0).AndReturn(dummyxml)
1946
def fake_lookup(instance_name):
1947
if instance_name == instance_ref.name:
1949
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
1951
GB = 1024 * 1024 * 1024
1952
fake_libvirt_utils.disk_sizes['/test/disk'] = 10 * GB
1953
fake_libvirt_utils.disk_sizes['/test/disk.local'] = 20 * GB
1954
fake_libvirt_utils.disk_backing_files['/test/disk.local'] = 'file'
1956
self.mox.StubOutWithMock(os.path, "getsize")
1957
os.path.getsize('/test/disk').AndReturn((10737418240))
1958
os.path.getsize('/test/disk.local').AndReturn((21474836480))
1960
ret = ("image: /test/disk\n"
1961
"file format: raw\n"
1962
"virtual size: 20G (21474836480 bytes)\n"
1964
"cluster_size: 2097152\n"
1965
"backing file: /test/dummy (actual path: /backing/file)\n")
1967
self.mox.StubOutWithMock(utils, "execute")
1968
utils.execute('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
1969
'/test/disk.local').AndReturn((ret, ''))
1971
self.mox.ReplayAll()
1972
conn = libvirt_driver.LibvirtDriver(False)
1973
info = conn.get_instance_disk_info(instance_ref.name)
1974
info = jsonutils.loads(info)
1975
self.assertEquals(info[0]['type'], 'raw')
1976
self.assertEquals(info[0]['path'], '/test/disk')
1977
self.assertEquals(info[0]['disk_size'], 10737418240)
1978
self.assertEquals(info[0]['backing_file'], "")
1979
self.assertEquals(info[1]['type'], 'qcow2')
1980
self.assertEquals(info[1]['path'], '/test/disk.local')
1981
self.assertEquals(info[1]['virt_disk_size'], 21474836480)
1982
self.assertEquals(info[1]['backing_file'], "file")
1984
db.instance_destroy(self.context, instance_ref['uuid'])
1986
def test_spawn_with_network_info(self):
1988
def fake_none(self, instance):
1991
# _fake_network_info must be called before create_fake_libvirt_mock(),
1992
# as _fake_network_info calls importutils.import_class() and
1993
# create_fake_libvirt_mock() mocks importutils.import_class().
1994
network_info = _fake_network_info(self.stubs, 1)
1995
self.create_fake_libvirt_mock()
1997
instance_ref = self.test_instance
1998
instance_ref['image_ref'] = 123456 # we send an int to test sha1 call
1999
instance = db.instance_create(self.context, instance_ref)
2002
self.mox.ReplayAll()
2003
conn = libvirt_driver.LibvirtDriver(False)
2004
self.stubs.Set(conn.firewall_driver,
2005
'setup_basic_filtering',
2007
self.stubs.Set(conn.firewall_driver,
2008
'prepare_instance_filter',
2012
conn.spawn(self.context, instance, None, [], 'herp',
2013
network_info=network_info)
2014
except Exception, e:
2015
# assert that no exception is raised due to sha1 receiving an int
2016
self.assertEqual(-1, unicode(e).find('must be string or buffer'
2018
self.assertNotIn('Unexpected method call', unicode(e))
2020
path = os.path.join(FLAGS.instances_path, instance.name)
2021
if os.path.isdir(path):
2024
path = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name)
2025
if os.path.isdir(path):
2026
shutil.rmtree(os.path.join(FLAGS.instances_path,
2027
FLAGS.base_dir_name))
2029
def test_get_console_output_file(self):
2031
with utils.tempdir() as tmpdir:
2032
self.flags(instances_path=tmpdir)
2034
instance_ref = self.test_instance
2035
instance_ref['image_ref'] = 123456
2036
instance = db.instance_create(self.context, instance_ref)
2038
console_dir = (os.path.join(tmpdir, instance['name']))
2039
os.mkdir(console_dir)
2040
console_log = '%s/console.log' % (console_dir)
2041
f = open(console_log, "w")
2048
<source file='filename'/>
2050
<console type='file'>
2058
def fake_lookup(id):
2059
return FakeVirtDomain(fake_dom_xml)
2061
self.create_fake_libvirt_mock()
2062
libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup
2063
libvirt_driver.libvirt_utils = fake_libvirt_utils
2065
conn = libvirt_driver.LibvirtDriver(False)
2066
output = conn.get_console_output(instance)
2067
self.assertEquals("foo", output)
2069
def test_get_console_output_pty(self):
2071
with utils.tempdir() as tmpdir:
2072
self.flags(instances_path=tmpdir)
2074
instance_ref = self.test_instance
2075
instance_ref['image_ref'] = 123456
2076
instance = db.instance_create(self.context, instance_ref)
2078
console_dir = (os.path.join(tmpdir, instance['name']))
2079
os.mkdir(console_dir)
2080
pty_file = '%s/fake_pty' % (console_dir)
2081
f = open(pty_file, "w")
2088
<source file='filename'/>
2090
<console type='pty'>
2098
def fake_lookup(id):
2099
return FakeVirtDomain(fake_dom_xml)
2101
def _fake_flush(self, fake_pty):
2102
with open(fake_pty, 'r') as fp:
2105
self.create_fake_libvirt_mock()
2106
libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup
2107
libvirt_driver.LibvirtDriver._flush_libvirt_console = _fake_flush
2108
libvirt_driver.libvirt_utils = fake_libvirt_utils
2110
conn = libvirt_driver.LibvirtDriver(False)
2111
output = conn.get_console_output(instance)
2112
self.assertEquals("foo", output)
2114
def test_get_host_ip_addr(self):
2115
conn = libvirt_driver.LibvirtDriver(False)
2116
ip = conn.get_host_ip_addr()
2117
self.assertEquals(ip, FLAGS.my_ip)
2119
def test_broken_connection(self):
2120
for (error, domain) in (
2121
(libvirt.VIR_ERR_SYSTEM_ERROR, libvirt.VIR_FROM_REMOTE),
2122
(libvirt.VIR_ERR_SYSTEM_ERROR, libvirt.VIR_FROM_RPC)):
2124
conn = libvirt_driver.LibvirtDriver(False)
2126
self.mox.StubOutWithMock(conn, "_wrapped_conn")
2127
self.mox.StubOutWithMock(conn._wrapped_conn, "getCapabilities")
2128
self.mox.StubOutWithMock(libvirt.libvirtError, "get_error_code")
2129
self.mox.StubOutWithMock(libvirt.libvirtError, "get_error_domain")
2131
conn._wrapped_conn.getCapabilities().AndRaise(
2132
libvirt.libvirtError("fake failure"))
2134
libvirt.libvirtError.get_error_code().AndReturn(error)
2135
libvirt.libvirtError.get_error_domain().AndReturn(domain)
2137
self.mox.ReplayAll()
2139
self.assertFalse(conn._test_connection())
2141
self.mox.UnsetStubs()
2143
def test_volume_in_mapping(self):
2144
conn = libvirt_driver.LibvirtDriver(False)
2145
swap = {'device_name': '/dev/sdb',
2147
ephemerals = [{'num': 0,
2148
'virtual_name': 'ephemeral0',
2149
'device_name': '/dev/sdc1',
2152
'virtual_name': 'ephemeral2',
2153
'device_name': '/dev/sdd',
2155
block_device_mapping = [{'mount_device': '/dev/sde',
2156
'device_path': 'fake_device'},
2157
{'mount_device': '/dev/sdf',
2158
'device_path': 'fake_device'}]
2159
block_device_info = {
2160
'root_device_name': '/dev/sda',
2162
'ephemerals': ephemerals,
2163
'block_device_mapping': block_device_mapping}
2165
def _assert_volume_in_mapping(device_name, true_or_false):
2166
self.assertEquals(conn._volume_in_mapping(device_name,
2170
_assert_volume_in_mapping('sda', False)
2171
_assert_volume_in_mapping('sdb', True)
2172
_assert_volume_in_mapping('sdc1', True)
2173
_assert_volume_in_mapping('sdd', True)
2174
_assert_volume_in_mapping('sde', True)
2175
_assert_volume_in_mapping('sdf', True)
2176
_assert_volume_in_mapping('sdg', False)
2177
_assert_volume_in_mapping('sdh1', False)
2179
def test_immediate_delete(self):
2180
def fake_lookup_by_name(instance_name):
2181
raise exception.InstanceNotFound()
2183
conn = libvirt_driver.LibvirtDriver(False)
2184
self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name)
2186
instance = db.instance_create(self.context, self.test_instance)
2187
conn.destroy(instance, {})
2189
def test_destroy_undefines(self):
2190
mock = self.mox.CreateMock(libvirt.virDomain)
2192
mock.undefineFlags(1).AndReturn(1)
2194
self.mox.ReplayAll()
2196
def fake_lookup_by_name(instance_name):
2199
def fake_get_info(instance_name):
2200
return {'state': power_state.SHUTDOWN}
2202
conn = libvirt_driver.LibvirtDriver(False)
2203
self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name)
2204
self.stubs.Set(conn, 'get_info', fake_get_info)
2205
instance = {"name": "instancename", "id": "instanceid",
2206
"uuid": "875a8070-d0b9-4949-8b31-104d125c9a64"}
2207
conn.destroy(instance, [])
2209
def test_destroy_undefines_no_undefine_flags(self):
2210
mock = self.mox.CreateMock(libvirt.virDomain)
2212
mock.undefineFlags(1).AndRaise(libvirt.libvirtError('Err'))
2215
self.mox.ReplayAll()
2217
def fake_lookup_by_name(instance_name):
2220
def fake_get_info(instance_name):
2221
return {'state': power_state.SHUTDOWN}
2223
conn = libvirt_driver.LibvirtDriver(False)
2224
self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name)
2225
self.stubs.Set(conn, 'get_info', fake_get_info)
2226
instance = {"name": "instancename", "id": "instanceid",
2227
"uuid": "875a8070-d0b9-4949-8b31-104d125c9a64"}
2228
conn.destroy(instance, [])
2230
def test_destroy_undefines_no_attribute_with_managed_save(self):
2231
mock = self.mox.CreateMock(libvirt.virDomain)
2233
mock.undefineFlags(1).AndRaise(AttributeError())
2234
mock.hasManagedSaveImage(0).AndReturn(True)
2235
mock.managedSaveRemove(0)
2238
self.mox.ReplayAll()
2240
def fake_lookup_by_name(instance_name):
2243
def fake_get_info(instance_name):
2244
return {'state': power_state.SHUTDOWN}
2246
conn = libvirt_driver.LibvirtDriver(False)
2247
self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name)
2248
self.stubs.Set(conn, 'get_info', fake_get_info)
2249
instance = {"name": "instancename", "id": "instanceid",
2250
"uuid": "875a8070-d0b9-4949-8b31-104d125c9a64"}
2251
conn.destroy(instance, [])
2253
def test_destroy_undefines_no_attribute_no_managed_save(self):
2254
mock = self.mox.CreateMock(libvirt.virDomain)
2256
mock.undefineFlags(1).AndRaise(AttributeError())
2257
mock.hasManagedSaveImage(0).AndRaise(AttributeError())
2260
self.mox.ReplayAll()
2262
def fake_lookup_by_name(instance_name):
2265
def fake_get_info(instance_name):
2266
return {'state': power_state.SHUTDOWN}
2268
conn = libvirt_driver.LibvirtDriver(False)
2269
self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name)
2270
self.stubs.Set(conn, 'get_info', fake_get_info)
2271
instance = {"name": "instancename", "id": "instanceid",
2272
"uuid": "875a8070-d0b9-4949-8b31-104d125c9a64"}
2273
conn.destroy(instance, [])
2275
def test_private_destroy_not_found(self):
2276
mock = self.mox.CreateMock(libvirt.virDomain)
2278
self.mox.ReplayAll()
2280
def fake_lookup_by_name(instance_name):
2283
def fake_get_info(instance_name):
2284
raise exception.InstanceNotFound()
2286
conn = libvirt_driver.LibvirtDriver(False)
2287
self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name)
2288
self.stubs.Set(conn, 'get_info', fake_get_info)
2289
instance = {"name": "instancename", "id": "instanceid",
2290
"uuid": "875a8070-d0b9-4949-8b31-104d125c9a64"}
2291
# NOTE(vish): verifies destory doesn't raise if the instance disappears
2292
conn._destroy(instance)
2294
def test_available_least_handles_missing(self):
2295
"""Ensure destroy calls managedSaveRemove for saved instance"""
2296
conn = libvirt_driver.LibvirtDriver(False)
2298
def list_instances():
2300
self.stubs.Set(conn, 'list_instances', list_instances)
2302
def get_info(instance_name):
2303
raise exception.InstanceNotFound()
2304
self.stubs.Set(conn, 'get_instance_disk_info', get_info)
2306
result = conn.get_disk_available_least()
2307
space = fake_libvirt_utils.get_fs_info(FLAGS.instances_path)['free']
2308
self.assertEqual(result, space / 1024 ** 3)
2310
def test_cpu_info(self):
2311
conn = libvirt_driver.LibvirtDriver(True)
2313
def get_host_capabilities_stub(self):
2314
cpu = config.LibvirtConfigCPU()
2315
cpu.model = "Opteron_G4"
2323
cpu.add_feature(config.LibvirtConfigCPUFeature("extapic"))
2324
cpu.add_feature(config.LibvirtConfigCPUFeature("3dnow"))
2326
caps = config.LibvirtConfigCaps()
2327
caps.host = config.LibvirtConfigCapsHost()
2330
guest = config.LibvirtConfigGuest()
2331
guest.ostype = vm_mode.HVM
2332
guest.arch = "x86_64"
2333
guest.domtype = ["kvm"]
2334
caps.guests.append(guest)
2336
guest = config.LibvirtConfigGuest()
2337
guest.ostype = vm_mode.HVM
2339
guest.domtype = ["kvm"]
2340
caps.guests.append(guest)
2344
self.stubs.Set(libvirt_driver.LibvirtDriver,
2345
'get_host_capabilities',
2346
get_host_capabilities_stub)
2348
want = {"vendor": "AMD",
2349
"features": ["extapic", "3dnow"],
2350
"model": "Opteron_G4",
2352
"topology": {"cores": 2, "threads": 1, "sockets": 4}}
2353
got = jsonutils.loads(conn.get_cpu_info())
2354
self.assertEqual(want, got)
2356
def test_diagnostic_vcpus_exception(self):
2361
<source file='filename'/>
2362
<target dev='vda' bus='virtio'/>
2365
<source dev='/path/to/dev/1'/>
2366
<target dev='vdb' bus='virtio'/>
2368
<interface type='network'>
2369
<mac address='52:54:00:a4:38:38'/>
2370
<source network='default'/>
2371
<target dev='vnet0'/>
2377
class DiagFakeDomain(FakeVirtDomain):
2380
super(DiagFakeDomain, self).__init__(fake_xml=xml)
2383
raise libvirt.libvirtError('vcpus missing')
2385
def blockStats(self, path):
2386
return (169L, 688640L, 0L, 0L, -1L)
2388
def interfaceStats(self, path):
2389
return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
2391
def memoryStats(self):
2392
return {'actual': 220160L, 'rss': 200164L}
2394
def maxMemory(self):
2397
def fake_lookup_name(name):
2398
return DiagFakeDomain()
2400
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2401
libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2403
conn = libvirt_driver.LibvirtDriver(False)
2404
actual = conn.get_diagnostics({"name": "testvirt"})
2405
expect = {'vda_read': 688640L,
2406
'vda_read_req': 169L,
2408
'vda_write_req': 0L,
2410
'vdb_read': 688640L,
2411
'vdb_read_req': 169L,
2413
'vdb_write_req': 0L,
2416
'memory-actual': 220160L,
2417
'memory-rss': 200164L,
2419
'vnet0_rx_drop': 0L,
2420
'vnet0_rx_errors': 0L,
2421
'vnet0_rx_packets': 82L,
2423
'vnet0_tx_drop': 0L,
2424
'vnet0_tx_errors': 0L,
2425
'vnet0_tx_packets': 0L,
2427
self.assertEqual(actual, expect)
2429
def test_diagnostic_blockstats_exception(self):
2434
<source file='filename'/>
2435
<target dev='vda' bus='virtio'/>
2438
<source dev='/path/to/dev/1'/>
2439
<target dev='vdb' bus='virtio'/>
2441
<interface type='network'>
2442
<mac address='52:54:00:a4:38:38'/>
2443
<source network='default'/>
2444
<target dev='vnet0'/>
2450
class DiagFakeDomain(FakeVirtDomain):
2453
super(DiagFakeDomain, self).__init__(fake_xml=xml)
2456
return ([(0, 1, 15340000000L, 0),
2457
(1, 1, 1640000000L, 0),
2458
(2, 1, 3040000000L, 0),
2459
(3, 1, 1420000000L, 0)],
2465
def blockStats(self, path):
2466
raise libvirt.libvirtError('blockStats missing')
2468
def interfaceStats(self, path):
2469
return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
2471
def memoryStats(self):
2472
return {'actual': 220160L, 'rss': 200164L}
2474
def maxMemory(self):
2477
def fake_lookup_name(name):
2478
return DiagFakeDomain()
2480
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2481
libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2483
conn = libvirt_driver.LibvirtDriver(False)
2484
actual = conn.get_diagnostics({"name": "testvirt"})
2485
expect = {'cpu0_time': 15340000000L,
2486
'cpu1_time': 1640000000L,
2487
'cpu2_time': 3040000000L,
2488
'cpu3_time': 1420000000L,
2490
'memory-actual': 220160L,
2491
'memory-rss': 200164L,
2493
'vnet0_rx_drop': 0L,
2494
'vnet0_rx_errors': 0L,
2495
'vnet0_rx_packets': 82L,
2497
'vnet0_tx_drop': 0L,
2498
'vnet0_tx_errors': 0L,
2499
'vnet0_tx_packets': 0L,
2501
self.assertEqual(actual, expect)
2503
def test_diagnostic_interfacestats_exception(self):
2508
<source file='filename'/>
2509
<target dev='vda' bus='virtio'/>
2512
<source dev='/path/to/dev/1'/>
2513
<target dev='vdb' bus='virtio'/>
2515
<interface type='network'>
2516
<mac address='52:54:00:a4:38:38'/>
2517
<source network='default'/>
2518
<target dev='vnet0'/>
2524
class DiagFakeDomain(FakeVirtDomain):
2527
super(DiagFakeDomain, self).__init__(fake_xml=xml)
2530
return ([(0, 1, 15340000000L, 0),
2531
(1, 1, 1640000000L, 0),
2532
(2, 1, 3040000000L, 0),
2533
(3, 1, 1420000000L, 0)],
2539
def blockStats(self, path):
2540
return (169L, 688640L, 0L, 0L, -1L)
2542
def interfaceStats(self, path):
2543
raise libvirt.libvirtError('interfaceStat missing')
2545
def memoryStats(self):
2546
return {'actual': 220160L, 'rss': 200164L}
2548
def maxMemory(self):
2551
def fake_lookup_name(name):
2552
return DiagFakeDomain()
2554
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2555
libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2557
conn = libvirt_driver.LibvirtDriver(False)
2558
actual = conn.get_diagnostics({"name": "testvirt"})
2559
expect = {'cpu0_time': 15340000000L,
2560
'cpu1_time': 1640000000L,
2561
'cpu2_time': 3040000000L,
2562
'cpu3_time': 1420000000L,
2563
'vda_read': 688640L,
2564
'vda_read_req': 169L,
2566
'vda_write_req': 0L,
2568
'vdb_read': 688640L,
2569
'vdb_read_req': 169L,
2571
'vdb_write_req': 0L,
2574
'memory-actual': 220160L,
2575
'memory-rss': 200164L,
2577
self.assertEqual(actual, expect)
2579
def test_diagnostic_memorystats_exception(self):
2584
<source file='filename'/>
2585
<target dev='vda' bus='virtio'/>
2588
<source dev='/path/to/dev/1'/>
2589
<target dev='vdb' bus='virtio'/>
2591
<interface type='network'>
2592
<mac address='52:54:00:a4:38:38'/>
2593
<source network='default'/>
2594
<target dev='vnet0'/>
2600
class DiagFakeDomain(FakeVirtDomain):
2603
super(DiagFakeDomain, self).__init__(fake_xml=xml)
2606
return ([(0, 1, 15340000000L, 0),
2607
(1, 1, 1640000000L, 0),
2608
(2, 1, 3040000000L, 0),
2609
(3, 1, 1420000000L, 0)],
2615
def blockStats(self, path):
2616
return (169L, 688640L, 0L, 0L, -1L)
2618
def interfaceStats(self, path):
2619
return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
2621
def memoryStats(self):
2622
raise libvirt.libvirtError('memoryStats missing')
2624
def maxMemory(self):
2627
def fake_lookup_name(name):
2628
return DiagFakeDomain()
2630
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2631
libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2633
conn = libvirt_driver.LibvirtDriver(False)
2634
actual = conn.get_diagnostics({"name": "testvirt"})
2635
expect = {'cpu0_time': 15340000000L,
2636
'cpu1_time': 1640000000L,
2637
'cpu2_time': 3040000000L,
2638
'cpu3_time': 1420000000L,
2639
'vda_read': 688640L,
2640
'vda_read_req': 169L,
2642
'vda_write_req': 0L,
2644
'vdb_read': 688640L,
2645
'vdb_read_req': 169L,
2647
'vdb_write_req': 0L,
2651
'vnet0_rx_drop': 0L,
2652
'vnet0_rx_errors': 0L,
2653
'vnet0_rx_packets': 82L,
2655
'vnet0_tx_drop': 0L,
2656
'vnet0_tx_errors': 0L,
2657
'vnet0_tx_packets': 0L,
2659
self.assertEqual(actual, expect)
2661
def test_diagnostic_full(self):
2666
<source file='filename'/>
2667
<target dev='vda' bus='virtio'/>
2670
<source dev='/path/to/dev/1'/>
2671
<target dev='vdb' bus='virtio'/>
2673
<interface type='network'>
2674
<mac address='52:54:00:a4:38:38'/>
2675
<source network='default'/>
2676
<target dev='vnet0'/>
2682
class DiagFakeDomain(FakeVirtDomain):
2685
super(DiagFakeDomain, self).__init__(fake_xml=xml)
2688
return ([(0, 1, 15340000000L, 0),
2689
(1, 1, 1640000000L, 0),
2690
(2, 1, 3040000000L, 0),
2691
(3, 1, 1420000000L, 0)],
2697
def blockStats(self, path):
2698
return (169L, 688640L, 0L, 0L, -1L)
2700
def interfaceStats(self, path):
2701
return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
2703
def memoryStats(self):
2704
return {'actual': 220160L, 'rss': 200164L}
2706
def maxMemory(self):
2709
def fake_lookup_name(name):
2710
return DiagFakeDomain()
2712
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2713
libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2715
conn = libvirt_driver.LibvirtDriver(False)
2716
actual = conn.get_diagnostics({"name": "testvirt"})
2717
expect = {'cpu0_time': 15340000000L,
2718
'cpu1_time': 1640000000L,
2719
'cpu2_time': 3040000000L,
2720
'cpu3_time': 1420000000L,
2721
'vda_read': 688640L,
2722
'vda_read_req': 169L,
2724
'vda_write_req': 0L,
2726
'vdb_read': 688640L,
2727
'vdb_read_req': 169L,
2729
'vdb_write_req': 0L,
2732
'memory-actual': 220160L,
2733
'memory-rss': 200164L,
2735
'vnet0_rx_drop': 0L,
2736
'vnet0_rx_errors': 0L,
2737
'vnet0_rx_packets': 82L,
2739
'vnet0_tx_drop': 0L,
2740
'vnet0_tx_errors': 0L,
2741
'vnet0_tx_packets': 0L,
2743
self.assertEqual(actual, expect)
2745
def test_get_instance_capabilities(self):
2746
conn = libvirt_driver.LibvirtDriver(True)
2748
def get_host_capabilities_stub(self):
2749
caps = config.LibvirtConfigCaps()
2751
guest = config.LibvirtConfigGuest()
2752
guest.ostype = 'hvm'
2753
guest.arch = 'x86_64'
2754
guest.domtype = ['kvm', 'qemu']
2755
caps.guests.append(guest)
2757
guest = config.LibvirtConfigGuest()
2758
guest.ostype = 'hvm'
2760
guest.domtype = ['kvm']
2761
caps.guests.append(guest)
2765
self.stubs.Set(libvirt_driver.LibvirtDriver,
2766
'get_host_capabilities',
2767
get_host_capabilities_stub)
2769
want = [('x86_64', 'kvm', 'hvm'),
2770
('x86_64', 'qemu', 'hvm'),
2771
('i686', 'kvm', 'hvm')]
2772
got = conn.get_instance_capabilities()
2773
self.assertEqual(want, got)
2776
class HostStateTestCase(test.TestCase):
2778
cpu_info = ('{"vendor": "Intel", "model": "pentium", "arch": "i686", '
2779
'"features": ["ssse3", "monitor", "pni", "sse2", "sse", '
2780
'"fxsr", "clflush", "pse36", "pat", "cmov", "mca", "pge", '
2781
'"mtrr", "sep", "apic"], '
2782
'"topology": {"cores": "1", "threads": "1", "sockets": "1"}}')
2783
instance_caps = [("x86_64", "kvm", "hvm"), ("i686", "kvm", "hvm")]
2785
class FakeConnection(object):
2786
"""Fake connection object"""
2788
def get_vcpu_total(self):
2791
def get_vcpu_used(self):
2794
def get_cpu_info(self):
2795
return HostStateTestCase.cpu_info
2797
def get_local_gb_total(self):
2800
def get_local_gb_used(self):
2803
def get_memory_mb_total(self):
2806
def get_memory_mb_used(self):
2809
def get_hypervisor_type(self):
2812
def get_hypervisor_version(self):
2815
def get_hypervisor_hostname(self):
2818
def get_host_uptime(self):
2819
return ('10:01:16 up 1:36, 6 users, '
2820
'load average: 0.21, 0.16, 0.19')
2822
def get_disk_available_least(self):
2825
def get_instance_capabilities(self):
2826
return HostStateTestCase.instance_caps
2828
def test_update_status(self):
2829
self.mox.StubOutWithMock(libvirt_driver, 'LibvirtDriver')
2830
libvirt_driver.LibvirtDriver(True).AndReturn(self.FakeConnection())
2832
self.mox.ReplayAll()
2833
hs = libvirt_driver.HostState(True)
2835
self.assertEquals(stats["vcpus"], 1)
2836
self.assertEquals(stats["vcpus_used"], 0)
2837
self.assertEquals(stats["cpu_info"],
2838
{"vendor": "Intel", "model": "pentium", "arch": "i686",
2839
"features": ["ssse3", "monitor", "pni", "sse2", "sse",
2840
"fxsr", "clflush", "pse36", "pat", "cmov",
2841
"mca", "pge", "mtrr", "sep", "apic"],
2842
"topology": {"cores": "1", "threads": "1", "sockets": "1"}
2844
self.assertEquals(stats["disk_total"], 100)
2845
self.assertEquals(stats["disk_used"], 20)
2846
self.assertEquals(stats["disk_available"], 80)
2847
self.assertEquals(stats["host_memory_total"], 497)
2848
self.assertEquals(stats["host_memory_free"], 409)
2849
self.assertEquals(stats["hypervisor_type"], 'QEMU')
2850
self.assertEquals(stats["hypervisor_version"], 13091)
2851
self.assertEquals(stats["hypervisor_hostname"], 'compute1')
2854
class NWFilterFakes:
2858
def nwfilterLookupByName(self, name):
2859
if name in self.filters:
2860
return self.filters[name]
2861
raise libvirt.libvirtError('Filter Not Found')
2863
def filterDefineXMLMock(self, xml):
2864
class FakeNWFilterInternal:
2865
def __init__(self, parent, name):
2867
self.parent = parent
2870
del self.parent.filters[self.name]
2872
tree = etree.fromstring(xml)
2873
name = tree.get('name')
2874
if name not in self.filters:
2875
self.filters[name] = FakeNWFilterInternal(self, name)
2879
class IptablesFirewallTestCase(test.TestCase):
2881
super(IptablesFirewallTestCase, self).setUp()
2883
self.user_id = 'fake'
2884
self.project_id = 'fake'
2885
self.context = context.RequestContext(self.user_id, self.project_id)
2887
class FakeLibvirtDriver(object):
2888
def nwfilterDefineXML(*args, **kwargs):
2889
"""setup_basic_rules in nwfilter calls this."""
2891
self.fake_libvirt_connection = FakeLibvirtDriver()
2892
self.fw = firewall.IptablesFirewallDriver(
2893
get_connection=lambda: self.fake_libvirt_connection)
2896
'# Generated by iptables-save v1.4.10 on Sat Feb 19 00:03:19 2011',
2898
':PREROUTING ACCEPT [1170:189210]',
2899
':INPUT ACCEPT [844:71028]',
2900
':OUTPUT ACCEPT [5149:405186]',
2901
':POSTROUTING ACCEPT [5063:386098]',
2905
'# Generated by iptables-save v1.4.4 on Mon Dec 6 11:54:13 2010',
2907
':INPUT ACCEPT [969615:281627771]',
2908
':FORWARD ACCEPT [0:0]',
2909
':OUTPUT ACCEPT [915599:63811649]',
2910
':nova-block-ipv4 - [0:0]',
2911
'[0:0] -A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT ',
2912
'[0:0] -A FORWARD -d 192.168.122.0/24 -o virbr0 -m state --state RELATED'
2913
',ESTABLISHED -j ACCEPT ',
2914
'[0:0] -A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT ',
2915
'[0:0] -A FORWARD -i virbr0 -o virbr0 -j ACCEPT ',
2916
'[0:0] -A FORWARD -o virbr0 -j REJECT '
2917
'--reject-with icmp-port-unreachable ',
2918
'[0:0] -A FORWARD -i virbr0 -j REJECT '
2919
'--reject-with icmp-port-unreachable ',
2921
'# Completed on Mon Dec 6 11:54:13 2010',
2924
in6_filter_rules = [
2925
'# Generated by ip6tables-save v1.4.4 on Tue Jan 18 23:47:56 2011',
2927
':INPUT ACCEPT [349155:75810423]',
2928
':FORWARD ACCEPT [0:0]',
2929
':OUTPUT ACCEPT [349256:75777230]',
2931
'# Completed on Tue Jan 18 23:47:56 2011',
2934
def _create_instance_ref(self):
2935
return db.instance_create(self.context,
2937
'project_id': 'fake',
2938
'instance_type_id': 1})
2940
def test_static_filters(self):
2941
instance_ref = self._create_instance_ref()
2942
src_instance_ref = self._create_instance_ref()
2944
admin_ctxt = context.get_admin_context()
2945
secgroup = db.security_group_create(admin_ctxt,
2947
'project_id': 'fake',
2948
'name': 'testgroup',
2949
'description': 'test group'})
2951
src_secgroup = db.security_group_create(admin_ctxt,
2953
'project_id': 'fake',
2954
'name': 'testsourcegroup',
2955
'description': 'src group'})
2957
db.security_group_rule_create(admin_ctxt,
2958
{'parent_group_id': secgroup['id'],
2962
'cidr': '192.168.11.0/24'})
2964
db.security_group_rule_create(admin_ctxt,
2965
{'parent_group_id': secgroup['id'],
2969
'cidr': '192.168.11.0/24'})
2971
db.security_group_rule_create(admin_ctxt,
2972
{'parent_group_id': secgroup['id'],
2976
'cidr': '192.168.10.0/24'})
2978
db.security_group_rule_create(admin_ctxt,
2979
{'parent_group_id': secgroup['id'],
2983
'group_id': src_secgroup['id']})
2985
db.security_group_rule_create(admin_ctxt,
2986
{'parent_group_id': secgroup['id'],
2987
'group_id': src_secgroup['id']})
2989
db.instance_add_security_group(admin_ctxt, instance_ref['uuid'],
2991
db.instance_add_security_group(admin_ctxt, src_instance_ref['uuid'],
2993
instance_ref = db.instance_get(admin_ctxt, instance_ref['id'])
2994
src_instance_ref = db.instance_get(admin_ctxt, src_instance_ref['id'])
2996
# self.fw.add_instance(instance_ref)
2997
def fake_iptables_execute(*cmd, **kwargs):
2998
process_input = kwargs.get('process_input', None)
2999
if cmd == ('ip6tables-save', '-c', '-t', 'filter'):
3000
return '\n'.join(self.in6_filter_rules), None
3001
if cmd == ('iptables-save', '-c', '-t', 'filter'):
3002
return '\n'.join(self.in_filter_rules), None
3003
if cmd == ('iptables-save', '-c', '-t', 'nat'):
3004
return '\n'.join(self.in_nat_rules), None
3005
if cmd == ('iptables-restore', '-c',):
3006
lines = process_input.split('\n')
3007
if '*filter' in lines:
3008
self.out_rules = lines
3010
if cmd == ('ip6tables-restore', '-c',):
3011
lines = process_input.split('\n')
3012
if '*filter' in lines:
3013
self.out6_rules = lines
3017
network_model = _fake_network_info(self.stubs, 1, spectacular=True)
3019
from nova.network import linux_net
3020
linux_net.iptables_manager.execute = fake_iptables_execute
3022
_fake_stub_out_get_nw_info(self.stubs, lambda *a, **kw: network_model)
3024
network_info = network_model.legacy()
3025
self.fw.prepare_instance_filter(instance_ref, network_info)
3026
self.fw.apply_instance_filter(instance_ref, network_info)
3028
in_rules = filter(lambda l: not l.startswith('#'),
3029
self.in_filter_rules)
3030
for rule in in_rules:
3031
if not 'nova' in rule:
3032
self.assertTrue(rule in self.out_rules,
3033
'Rule went missing: %s' % rule)
3035
instance_chain = None
3036
for rule in self.out_rules:
3037
# This is pretty crude, but it'll do for now
3038
# last two octets change
3039
if re.search('-d 192.168.[0-9]{1,3}.[0-9]{1,3} -j', rule):
3040
instance_chain = rule.split(' ')[-1]
3042
self.assertTrue(instance_chain, "The instance chain wasn't added")
3044
security_group_chain = None
3045
for rule in self.out_rules:
3046
# This is pretty crude, but it'll do for now
3047
if '-A %s -j' % instance_chain in rule:
3048
security_group_chain = rule.split(' ')[-1]
3050
self.assertTrue(security_group_chain,
3051
"The security group chain wasn't added")
3053
regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p icmp '
3054
'-s 192.168.11.0/24')
3055
self.assertTrue(len(filter(regex.match, self.out_rules)) > 0,
3056
"ICMP acceptance rule wasn't added")
3058
regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p icmp -m icmp '
3059
'--icmp-type 8 -s 192.168.11.0/24')
3060
self.assertTrue(len(filter(regex.match, self.out_rules)) > 0,
3061
"ICMP Echo Request acceptance rule wasn't added")
3063
for ip in network_model.fixed_ips():
3064
if ip['version'] != 4:
3066
regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p tcp -m multiport '
3067
'--dports 80:81 -s %s' % ip['address'])
3068
self.assertTrue(len(filter(regex.match, self.out_rules)) > 0,
3069
"TCP port 80/81 acceptance rule wasn't added")
3070
regex = re.compile('\[0\:0\] -A .* -j ACCEPT -s '
3071
'%s' % ip['address'])
3072
self.assertTrue(len(filter(regex.match, self.out_rules)) > 0,
3073
"Protocol/port-less acceptance rule wasn't added")
3075
regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p tcp '
3076
'-m multiport --dports 80:81 -s 192.168.10.0/24')
3077
self.assertTrue(len(filter(regex.match, self.out_rules)) > 0,
3078
"TCP port 80/81 acceptance rule wasn't added")
3079
db.instance_destroy(admin_ctxt, instance_ref['uuid'])
3081
def test_filters_for_instance_with_ip_v6(self):
3082
self.flags(use_ipv6=True)
3083
network_info = _fake_network_info(self.stubs, 1)
3084
rulesv4, rulesv6 = self.fw._filters_for_instance("fake", network_info)
3085
self.assertEquals(len(rulesv4), 2)
3086
self.assertEquals(len(rulesv6), 1)
3088
def test_filters_for_instance_without_ip_v6(self):
3089
self.flags(use_ipv6=False)
3090
network_info = _fake_network_info(self.stubs, 1)
3091
rulesv4, rulesv6 = self.fw._filters_for_instance("fake", network_info)
3092
self.assertEquals(len(rulesv4), 2)
3093
self.assertEquals(len(rulesv6), 0)
3095
def test_multinic_iptables(self):
3096
ipv4_rules_per_addr = 1
3097
ipv4_addr_per_network = 2
3098
ipv6_rules_per_addr = 1
3099
ipv6_addr_per_network = 1
3101
instance_ref = self._create_instance_ref()
3102
network_info = _fake_network_info(self.stubs, networks_count,
3103
ipv4_addr_per_network)
3104
ipv4_len = len(self.fw.iptables.ipv4['filter'].rules)
3105
ipv6_len = len(self.fw.iptables.ipv6['filter'].rules)
3106
inst_ipv4, inst_ipv6 = self.fw.instance_rules(instance_ref,
3108
self.fw.prepare_instance_filter(instance_ref, network_info)
3109
ipv4 = self.fw.iptables.ipv4['filter'].rules
3110
ipv6 = self.fw.iptables.ipv6['filter'].rules
3111
ipv4_network_rules = len(ipv4) - len(inst_ipv4) - ipv4_len
3112
ipv6_network_rules = len(ipv6) - len(inst_ipv6) - ipv6_len
3113
self.assertEquals(ipv4_network_rules,
3114
ipv4_rules_per_addr * ipv4_addr_per_network * networks_count)
3115
self.assertEquals(ipv6_network_rules,
3116
ipv6_rules_per_addr * ipv6_addr_per_network * networks_count)
3118
def test_do_refresh_security_group_rules(self):
3119
instance_ref = self._create_instance_ref()
3120
self.mox.StubOutWithMock(self.fw,
3121
'add_filters_for_instance',
3122
use_mock_anything=True)
3123
self.fw.prepare_instance_filter(instance_ref, mox.IgnoreArg())
3124
self.fw.instances[instance_ref['id']] = instance_ref
3125
self.mox.ReplayAll()
3126
self.fw.do_refresh_security_group_rules("fake")
3128
def test_unfilter_instance_undefines_nwfilter(self):
3129
admin_ctxt = context.get_admin_context()
3131
fakefilter = NWFilterFakes()
3132
_xml_mock = fakefilter.filterDefineXMLMock
3133
self.fw.nwfilter._conn.nwfilterDefineXML = _xml_mock
3134
_lookup_name = fakefilter.nwfilterLookupByName
3135
self.fw.nwfilter._conn.nwfilterLookupByName = _lookup_name
3136
instance_ref = self._create_instance_ref()
3138
network_info = _fake_network_info(self.stubs, 1)
3139
self.fw.setup_basic_filtering(instance_ref, network_info)
3140
self.fw.prepare_instance_filter(instance_ref, network_info)
3141
self.fw.apply_instance_filter(instance_ref, network_info)
3142
original_filter_count = len(fakefilter.filters)
3143
self.fw.unfilter_instance(instance_ref, network_info)
3145
# should undefine just the instance filter
3146
self.assertEqual(original_filter_count - len(fakefilter.filters), 1)
3148
db.instance_destroy(admin_ctxt, instance_ref['uuid'])
3150
def test_provider_firewall_rules(self):
3151
# setup basic instance data
3152
instance_ref = self._create_instance_ref()
3153
# FRAGILE: peeks at how the firewall names chains
3154
chain_name = 'inst-%s' % instance_ref['id']
3156
# create a firewall via setup_basic_filtering like libvirt_conn.spawn
3157
# should have a chain with 0 rules
3158
network_info = _fake_network_info(self.stubs, 1)
3159
self.fw.setup_basic_filtering(instance_ref, network_info)
3160
self.assertTrue('provider' in self.fw.iptables.ipv4['filter'].chains)
3161
rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
3162
if rule.chain == 'provider']
3163
self.assertEqual(0, len(rules))
3165
admin_ctxt = context.get_admin_context()
3166
# add a rule and send the update message, check for 1 rule
3167
provider_fw0 = db.provider_fw_rule_create(admin_ctxt,
3169
'cidr': '10.99.99.99/32',
3172
self.fw.refresh_provider_fw_rules()
3173
rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
3174
if rule.chain == 'provider']
3175
self.assertEqual(1, len(rules))
3177
# Add another, refresh, and make sure number of rules goes to two
3178
provider_fw1 = db.provider_fw_rule_create(admin_ctxt,
3180
'cidr': '10.99.99.99/32',
3183
self.fw.refresh_provider_fw_rules()
3184
rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
3185
if rule.chain == 'provider']
3186
self.assertEqual(2, len(rules))
3188
# create the instance filter and make sure it has a jump rule
3189
self.fw.prepare_instance_filter(instance_ref, network_info)
3190
self.fw.apply_instance_filter(instance_ref, network_info)
3191
inst_rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
3192
if rule.chain == chain_name]
3193
jump_rules = [rule for rule in inst_rules if '-j' in rule.rule]
3195
# IptablesTable doesn't make rules unique internally
3196
for rule in jump_rules:
3197
if 'provider' in rule.rule and rule not in provjump_rules:
3198
provjump_rules.append(rule)
3199
self.assertEqual(1, len(provjump_rules))
3201
# remove a rule from the db, cast to compute to refresh rule
3202
db.provider_fw_rule_destroy(admin_ctxt, provider_fw1['id'])
3203
self.fw.refresh_provider_fw_rules()
3204
rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
3205
if rule.chain == 'provider']
3206
self.assertEqual(1, len(rules))
3209
class NWFilterTestCase(test.TestCase):
3211
super(NWFilterTestCase, self).setUp()
3216
self.user_id = 'fake'
3217
self.project_id = 'fake'
3218
self.context = context.RequestContext(self.user_id, self.project_id)
3220
self.fake_libvirt_connection = Mock()
3222
self.fw = firewall.NWFilterFirewall(
3223
lambda: self.fake_libvirt_connection)
3225
def test_cidr_rule_nwfilter_xml(self):
3226
cloud_controller = cloud.CloudController()
3227
cloud_controller.create_security_group(self.context,
3229
'test group description')
3230
cloud_controller.authorize_security_group_ingress(self.context,
3235
cidr_ip='0.0.0.0/0')
3237
security_group = db.security_group_get_by_name(self.context,
3240
self.teardown_security_group()
3242
def teardown_security_group(self):
3243
cloud_controller = cloud.CloudController()
3244
cloud_controller.delete_security_group(self.context, 'testgroup')
3246
def setup_and_return_security_group(self):
3247
cloud_controller = cloud.CloudController()
3248
cloud_controller.create_security_group(self.context,
3250
'test group description')
3251
cloud_controller.authorize_security_group_ingress(self.context,
3256
cidr_ip='0.0.0.0/0')
3258
return db.security_group_get_by_name(self.context, 'fake', 'testgroup')
3260
def _create_instance(self):
3261
return db.instance_create(self.context,
3263
'project_id': 'fake',
3264
'instance_type_id': 1})
3266
def _create_instance_type(self, params=None):
3267
"""Create a test instance"""
3271
context = self.context.elevated()
3273
inst['name'] = 'm1.small'
3274
inst['memory_mb'] = '1024'
3276
inst['root_gb'] = '10'
3277
inst['ephemeral_gb'] = '20'
3278
inst['flavorid'] = '1'
3279
inst['swap'] = '2048'
3280
inst['rxtx_factor'] = 1
3282
return db.instance_type_create(context, inst)['id']
3284
def test_creates_base_rule_first(self):
3285
# These come pre-defined by libvirt
3286
self.defined_filters = ['no-mac-spoofing',
3289
'allow-dhcp-server']
3291
self.recursive_depends = {}
3292
for f in self.defined_filters:
3293
self.recursive_depends[f] = []
3295
def _filterDefineXMLMock(xml):
3296
dom = minidom.parseString(xml)
3297
name = dom.firstChild.getAttribute('name')
3298
self.recursive_depends[name] = []
3299
for f in dom.getElementsByTagName('filterref'):
3300
ref = f.getAttribute('filter')
3301
self.assertTrue(ref in self.defined_filters,
3302
('%s referenced filter that does ' +
3303
'not yet exist: %s') % (name, ref))
3304
dependencies = [ref] + self.recursive_depends[ref]
3305
self.recursive_depends[name] += dependencies
3307
self.defined_filters.append(name)
3310
self.fake_libvirt_connection.nwfilterDefineXML = _filterDefineXMLMock
3312
instance_ref = self._create_instance()
3313
inst_id = instance_ref['id']
3314
inst_uuid = instance_ref['uuid']
3316
def _ensure_all_called(mac, allow_dhcp):
3317
instance_filter = 'nova-instance-%s-%s' % (instance_ref['name'],
3318
mac.translate(None, ':'))
3319
requiredlist = ['no-arp-spoofing', 'no-ip-spoofing',
3322
requiredlist.append('allow-dhcp-server')
3323
for required in requiredlist:
3324
self.assertTrue(required in
3325
self.recursive_depends[instance_filter],
3326
"Instance's filter does not include %s" %
3329
self.security_group = self.setup_and_return_security_group()
3331
db.instance_add_security_group(self.context, inst_uuid,
3332
self.security_group.id)
3333
instance = db.instance_get(self.context, inst_id)
3335
network_info = _fake_network_info(self.stubs, 1)
3336
# since there is one (network_info) there is one vif
3337
# pass this vif's mac to _ensure_all_called()
3338
# to set the instance_filter properly
3339
mac = network_info[0][1]['mac']
3341
self.fw.setup_basic_filtering(instance, network_info)
3343
for (network, mapping) in network_info:
3344
if mapping['dhcp_server']:
3347
_ensure_all_called(mac, allow_dhcp)
3348
db.instance_remove_security_group(self.context, inst_uuid,
3349
self.security_group.id)
3350
self.teardown_security_group()
3351
db.instance_destroy(context.get_admin_context(), instance_ref['uuid'])
3353
def test_unfilter_instance_undefines_nwfilters(self):
3354
admin_ctxt = context.get_admin_context()
3356
fakefilter = NWFilterFakes()
3357
self.fw._conn.nwfilterDefineXML = fakefilter.filterDefineXMLMock
3358
self.fw._conn.nwfilterLookupByName = fakefilter.nwfilterLookupByName
3360
instance_ref = self._create_instance()
3361
inst_id = instance_ref['id']
3362
inst_uuid = instance_ref['uuid']
3364
self.security_group = self.setup_and_return_security_group()
3366
db.instance_add_security_group(self.context, inst_uuid,
3367
self.security_group.id)
3369
instance = db.instance_get(self.context, inst_id)
3371
network_info = _fake_network_info(self.stubs, 1)
3372
self.fw.setup_basic_filtering(instance, network_info)
3373
original_filter_count = len(fakefilter.filters)
3374
self.fw.unfilter_instance(instance, network_info)
3375
self.assertEqual(original_filter_count - len(fakefilter.filters), 1)
3377
db.instance_destroy(admin_ctxt, instance_ref['uuid'])
3380
class LibvirtUtilsTestCase(test.TestCase):
3381
def test_get_iscsi_initiator(self):
3382
self.mox.StubOutWithMock(utils, 'execute')
3383
initiator = 'fake.initiator.iqn'
3384
rval = ("junk\nInitiatorName=%s\njunk\n" % initiator, None)
3385
utils.execute('cat', '/etc/iscsi/initiatorname.iscsi',
3386
run_as_root=True).AndReturn(rval)
3388
self.mox.ReplayAll()
3389
result = libvirt_utils.get_iscsi_initiator()
3390
self.assertEqual(initiator, result)
3392
def test_create_image(self):
3393
self.mox.StubOutWithMock(utils, 'execute')
3394
utils.execute('qemu-img', 'create', '-f', 'raw',
3395
'/some/path', '10G')
3396
utils.execute('qemu-img', 'create', '-f', 'qcow2',
3397
'/some/stuff', '1234567891234')
3399
self.mox.ReplayAll()
3400
libvirt_utils.create_image('raw', '/some/path', '10G')
3401
libvirt_utils.create_image('qcow2', '/some/stuff', '1234567891234')
3403
def test_create_cow_image(self):
3404
self.mox.StubOutWithMock(utils, 'execute')
3405
utils.execute('qemu-img', 'create', '-f', 'qcow2',
3406
'-o', 'backing_file=/some/path',
3409
self.mox.ReplayAll()
3410
libvirt_utils.create_cow_image('/some/path', '/the/new/cow')
3412
def test_pick_disk_driver_name(self):
3413
type_map = {'kvm': ([True, 'qemu'], [False, 'qemu'], [None, 'qemu']),
3414
'qemu': ([True, 'qemu'], [False, 'qemu'], [None, 'qemu']),
3415
'xen': ([True, 'phy'], [False, 'tap'], [None, 'tap']),
3416
'uml': ([True, None], [False, None], [None, None]),
3417
'lxc': ([True, None], [False, None], [None, None])}
3419
for (libvirt_type, checks) in type_map.iteritems():
3420
self.flags(libvirt_type=libvirt_type)
3421
for (is_block_dev, expected_result) in checks:
3422
result = libvirt_utils.pick_disk_driver_name(is_block_dev)
3423
self.assertEquals(result, expected_result)
3425
def test_get_disk_size(self):
3426
self.mox.StubOutWithMock(utils, 'execute')
3427
utils.execute('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
3428
'/some/path').AndReturn(('''image: 00000001
3430
virtual size: 4.4M (4592640 bytes)
3431
disk size: 4.4M''', ''))
3434
self.mox.ReplayAll()
3435
self.assertEquals(disk.get_disk_size('/some/path'), 4592640)
3437
def test_copy_image(self):
3438
dst_fd, dst_path = tempfile.mkstemp()
3442
src_fd, src_path = tempfile.mkstemp()
3444
with os.fdopen(src_fd, 'w') as fp:
3447
libvirt_utils.copy_image(src_path, dst_path)
3448
with open(dst_path, 'r') as fp:
3449
self.assertEquals(fp.read(), 'canary')
3455
def test_mkfs(self):
3456
self.mox.StubOutWithMock(utils, 'execute')
3457
utils.execute('mkfs', '-t', 'ext4', '-F', '/my/block/dev')
3458
utils.execute('mkswap', '/my/swap/block/dev')
3459
self.mox.ReplayAll()
3461
libvirt_utils.mkfs('ext4', '/my/block/dev')
3462
libvirt_utils.mkfs('swap', '/my/swap/block/dev')
3464
def test_write_to_file(self):
3465
dst_fd, dst_path = tempfile.mkstemp()
3469
libvirt_utils.write_to_file(dst_path, 'hello')
3470
with open(dst_path, 'r') as fp:
3471
self.assertEquals(fp.read(), 'hello')
3475
def test_write_to_file_with_umask(self):
3476
dst_fd, dst_path = tempfile.mkstemp()
3481
libvirt_utils.write_to_file(dst_path, 'hello', umask=0277)
3482
with open(dst_path, 'r') as fp:
3483
self.assertEquals(fp.read(), 'hello')
3484
mode = os.stat(dst_path).st_mode
3485
self.assertEquals(mode & 0277, 0)
3489
def test_chown(self):
3490
self.mox.StubOutWithMock(utils, 'execute')
3491
utils.execute('chown', 'soren', '/some/path', run_as_root=True)
3492
self.mox.ReplayAll()
3493
libvirt_utils.chown('/some/path', 'soren')
3495
def _do_test_extract_snapshot(self, dest_format='raw', out_format='raw'):
3496
self.mox.StubOutWithMock(utils, 'execute')
3497
utils.execute('qemu-img', 'convert', '-f', 'qcow2', '-O', out_format,
3498
'-s', 'snap1', '/path/to/disk/image', '/extracted/snap')
3501
self.mox.ReplayAll()
3502
libvirt_utils.extract_snapshot('/path/to/disk/image', 'qcow2',
3503
'snap1', '/extracted/snap', dest_format)
3505
def test_extract_snapshot_raw(self):
3506
self._do_test_extract_snapshot()
3508
def test_extract_snapshot_iso(self):
3509
self._do_test_extract_snapshot(dest_format='iso')
3511
def test_extract_snapshot_qcow2(self):
3512
self._do_test_extract_snapshot(dest_format='qcow2', out_format='qcow2')
3514
def test_load_file(self):
3515
dst_fd, dst_path = tempfile.mkstemp()
3519
# We have a test for write_to_file. If that is sound, this suffices
3520
libvirt_utils.write_to_file(dst_path, 'hello')
3521
self.assertEquals(libvirt_utils.load_file(dst_path), 'hello')
3525
def test_file_open(self):
3526
dst_fd, dst_path = tempfile.mkstemp()
3530
# We have a test for write_to_file. If that is sound, this suffices
3531
libvirt_utils.write_to_file(dst_path, 'hello')
3532
with libvirt_utils.file_open(dst_path, 'r') as fp:
3533
self.assertEquals(fp.read(), 'hello')
3537
def test_get_fs_info(self):
3539
class FakeStatResult(object):
3543
self.f_frsize = 4096
3544
self.f_blocks = 2000
3551
self.f_namemax = 255
3555
def fake_statvfs(path):
3557
return FakeStatResult()
3559
self.stubs.Set(os, 'statvfs', fake_statvfs)
3561
fs_info = libvirt_utils.get_fs_info('/some/file/path')
3562
self.assertEquals('/some/file/path', self.path)
3563
self.assertEquals(8192000, fs_info['total'])
3564
self.assertEquals(3686400, fs_info['free'])
3565
self.assertEquals(4096000, fs_info['used'])
3567
def test_fetch_image(self):
3568
self.mox.StubOutWithMock(images, 'fetch_to_raw')
3570
context = 'opaque context'
3571
target = '/tmp/targetfile'
3575
images.fetch_to_raw(context, image_id, target, user_id, project_id)
3577
self.mox.ReplayAll()
3578
libvirt_utils.fetch_image(context, target, image_id,
3579
user_id, project_id)
3581
def test_get_disk_backing_file(self):
3582
with_actual_path = False
3584
def fake_execute(*args, **kwargs):
3585
if with_actual_path:
3586
return ("some: output\n"
3587
"backing file: /foo/bar/baz (actual path: /a/b/c)\n"
3590
return ("some: output\n"
3591
"backing file: /foo/bar/baz\n"
3594
self.stubs.Set(utils, 'execute', fake_execute)
3596
out = libvirt_utils.get_disk_backing_file('')
3597
self.assertEqual(out, 'baz')
3598
with_actual_path = True
3599
out = libvirt_utils.get_disk_backing_file('')
3600
self.assertEqual(out, 'c')
3603
class LibvirtDriverTestCase(test.TestCase):
3604
"""Test for nova.virt.libvirt.libvirt_driver.LibvirtDriver."""
3606
super(LibvirtDriverTestCase, self).setUp()
3607
self.libvirtconnection = libvirt_driver.LibvirtDriver(read_only=True)
3609
def _create_instance(self, params=None):
3610
"""Create a test instance"""
3615
inst['image_ref'] = '1'
3616
inst['reservation_id'] = 'r-fakeres'
3617
inst['launch_time'] = '10'
3618
inst['user_id'] = 'fake'
3619
inst['project_id'] = 'fake'
3620
type_id = instance_types.get_instance_type_by_name('m1.tiny')['id']
3621
inst['instance_type_id'] = type_id
3622
inst['ami_launch_index'] = 0
3623
inst['host'] = 'host1'
3624
inst['root_gb'] = 10
3625
inst['ephemeral_gb'] = 20
3626
inst['config_drive'] = 1
3627
inst['kernel_id'] = 2
3628
inst['ramdisk_id'] = 3
3629
inst['config_drive_id'] = 1
3630
inst['key_data'] = 'ABCDEFG'
3633
return db.instance_create(context.get_admin_context(), inst)
3635
def test_migrate_disk_and_power_off_exception(self):
3636
"""Test for nova.virt.libvirt.libvirt_driver.LivirtConnection
3637
.migrate_disk_and_power_off. """
3641
def fake_get_instance_disk_info(instance):
3644
def fake_destroy(instance):
3647
def fake_get_host_ip_addr():
3650
def fake_execute(*args, **kwargs):
3652
if self.counter == 1:
3653
assert False, "intentional failure"
3655
def fake_os_path_exists(path):
3658
self.stubs.Set(self.libvirtconnection, 'get_instance_disk_info',
3659
fake_get_instance_disk_info)
3660
self.stubs.Set(self.libvirtconnection, '_destroy', fake_destroy)
3661
self.stubs.Set(self.libvirtconnection, 'get_host_ip_addr',
3662
fake_get_host_ip_addr)
3663
self.stubs.Set(utils, 'execute', fake_execute)
3664
self.stubs.Set(os.path, 'exists', fake_os_path_exists)
3666
ins_ref = self._create_instance()
3668
self.assertRaises(AssertionError,
3669
self.libvirtconnection.migrate_disk_and_power_off,
3670
None, ins_ref, '10.0.0.2', None, None)
3672
def test_migrate_disk_and_power_off(self):
3673
"""Test for nova.virt.libvirt.libvirt_driver.LivirtConnection
3674
.migrate_disk_and_power_off. """
3676
disk_info = [{'type': 'qcow2', 'path': '/test/disk',
3677
'virt_disk_size': '10737418240',
3678
'backing_file': '/base/disk',
3679
'disk_size':'83886080'},
3680
{'type': 'raw', 'path': '/test/disk.local',
3681
'virt_disk_size': '10737418240',
3682
'backing_file': '/base/disk.local',
3683
'disk_size':'83886080'}]
3684
disk_info_text = jsonutils.dumps(disk_info)
3686
def fake_get_instance_disk_info(instance):
3687
return disk_info_text
3689
def fake_destroy(instance):
3692
def fake_get_host_ip_addr():
3695
def fake_execute(*args, **kwargs):
3698
self.stubs.Set(self.libvirtconnection, 'get_instance_disk_info',
3699
fake_get_instance_disk_info)
3700
self.stubs.Set(self.libvirtconnection, '_destroy', fake_destroy)
3701
self.stubs.Set(self.libvirtconnection, 'get_host_ip_addr',
3702
fake_get_host_ip_addr)
3703
self.stubs.Set(utils, 'execute', fake_execute)
3705
ins_ref = self._create_instance()
3706
""" dest is different host case """
3707
out = self.libvirtconnection.migrate_disk_and_power_off(
3708
None, ins_ref, '10.0.0.2', None, None)
3709
self.assertEquals(out, disk_info_text)
3711
""" dest is same host case """
3712
out = self.libvirtconnection.migrate_disk_and_power_off(
3713
None, ins_ref, '10.0.0.1', None, None)
3714
self.assertEquals(out, disk_info_text)
3716
def test_wait_for_running(self):
3717
def fake_get_info(instance):
3718
if instance['name'] == "not_found":
3719
raise exception.NotFound
3720
elif instance['name'] == "running":
3721
return {'state': power_state.RUNNING}
3723
return {'state': power_state.SHUTDOWN}
3725
self.stubs.Set(self.libvirtconnection, 'get_info',
3728
""" instance not found case """
3729
self.assertRaises(exception.NotFound,
3730
self.libvirtconnection._wait_for_running,
3731
{'name': 'not_found',
3732
'uuid': 'not_found_uuid'})
3734
""" instance is running case """
3735
self.assertRaises(utils.LoopingCallDone,
3736
self.libvirtconnection._wait_for_running,
3738
'uuid': 'running_uuid'})
3741
self.libvirtconnection._wait_for_running({'name': 'else',
3742
'uuid': 'other_uuid'})
3744
def test_finish_migration(self):
3745
"""Test for nova.virt.libvirt.libvirt_driver.LivirtConnection
3746
.finish_migration. """
3748
disk_info = [{'type': 'qcow2', 'path': '/test/disk',
3749
'local_gb': 10, 'backing_file': '/base/disk'},
3750
{'type': 'raw', 'path': '/test/disk.local',
3751
'local_gb': 10, 'backing_file': '/base/disk.local'}]
3752
disk_info_text = jsonutils.dumps(disk_info)
3754
def fake_can_resize_fs(path, size, use_cow=False):
3757
def fake_extend(path, size):
3760
def fake_to_xml(instance, network_info, image_meta=None, rescue=None,
3761
block_device_info=None):
3764
def fake_plug_vifs(instance, network_info):
3767
def fake_create_image(context, inst, libvirt_xml, suffix='',
3768
disk_images=None, network_info=None,
3769
block_device_info=None):
3772
def fake_create_domain(xml):
3775
def fake_enable_hairpin(instance):
3778
def fake_execute(*args, **kwargs):
3781
def fake_get_info(instance):
3782
return {'state': power_state.RUNNING}
3784
self.flags(use_cow_images=True)
3785
self.stubs.Set(libvirt_driver.disk, 'extend', fake_extend)
3786
self.stubs.Set(libvirt_driver.disk, 'can_resize_fs',
3788
self.stubs.Set(self.libvirtconnection, 'to_xml', fake_to_xml)
3789
self.stubs.Set(self.libvirtconnection, 'plug_vifs', fake_plug_vifs)
3790
self.stubs.Set(self.libvirtconnection, '_create_image',
3792
self.stubs.Set(self.libvirtconnection, '_create_domain',
3794
self.stubs.Set(self.libvirtconnection, '_enable_hairpin',
3795
fake_enable_hairpin)
3796
self.stubs.Set(utils, 'execute', fake_execute)
3797
fw = base_firewall.NoopFirewallDriver()
3798
self.stubs.Set(self.libvirtconnection, 'firewall_driver', fw)
3799
self.stubs.Set(self.libvirtconnection, 'get_info',
3802
ins_ref = self._create_instance()
3804
self.libvirtconnection.finish_migration(
3805
context.get_admin_context(), None, ins_ref,
3806
disk_info_text, None, None, None)
3808
def test_finish_revert_migration(self):
3809
"""Test for nova.virt.libvirt.libvirt_driver.LivirtConnection
3810
.finish_revert_migration. """
3812
def fake_execute(*args, **kwargs):
3815
def fake_plug_vifs(instance, network_info):
3818
def fake_create_domain(xml):
3821
def fake_enable_hairpin(instance):
3824
def fake_get_info(instance):
3825
return {'state': power_state.RUNNING}
3827
def fake_to_xml(instance, network_info, image_meta=None, rescue=None,
3828
block_device_info=None):
3831
self.stubs.Set(self.libvirtconnection, 'to_xml', fake_to_xml)
3832
self.stubs.Set(self.libvirtconnection, 'plug_vifs', fake_plug_vifs)
3833
self.stubs.Set(utils, 'execute', fake_execute)
3834
fw = base_firewall.NoopFirewallDriver()
3835
self.stubs.Set(self.libvirtconnection, 'firewall_driver', fw)
3836
self.stubs.Set(self.libvirtconnection, '_create_domain',
3838
self.stubs.Set(self.libvirtconnection, '_enable_hairpin',
3839
fake_enable_hairpin)
3840
self.stubs.Set(self.libvirtconnection, 'get_info',
3843
with utils.tempdir() as tmpdir:
3844
self.flags(instances_path=tmpdir)
3845
ins_ref = self._create_instance()
3846
os.mkdir(os.path.join(tmpdir, ins_ref['name']))
3847
libvirt_xml_path = os.path.join(tmpdir,
3850
f = open(libvirt_xml_path, 'w')
3853
self.libvirtconnection.finish_revert_migration(ins_ref, None)
3855
def test_confirm_migration(self):
3856
ins_ref = self._create_instance()
3858
self.mox.StubOutWithMock(self.libvirtconnection, "_cleanup_resize")
3859
self.libvirtconnection._cleanup_resize(ins_ref,
3860
_fake_network_info(self.stubs, 1))
3862
self.mox.ReplayAll()
3863
self.libvirtconnection.confirm_migration("migration_ref", ins_ref,
3864
_fake_network_info(self.stubs, 1))
3866
def test_cleanup_resize_same_host(self):
3867
ins_ref = self._create_instance({'host': FLAGS.host})
3869
def fake_os_path_exists(path):
3872
def fake_shutil_rmtree(target):
3875
self.stubs.Set(os.path, 'exists', fake_os_path_exists)
3876
self.stubs.Set(shutil, 'rmtree', fake_shutil_rmtree)
3878
self.mox.ReplayAll()
3879
self.libvirtconnection._cleanup_resize(ins_ref,
3880
_fake_network_info(self.stubs, 1))
3882
def test_cleanup_resize_not_same_host(self):
3883
host = 'not' + FLAGS.host
3884
ins_ref = self._create_instance({'host': host})
3886
def fake_os_path_exists(path):
3889
def fake_shutil_rmtree(target):
3892
def fake_unfilter_instance(instance, network_info):
3895
self.stubs.Set(os.path, 'exists', fake_os_path_exists)
3896
self.stubs.Set(shutil, 'rmtree', fake_shutil_rmtree)
3897
self.stubs.Set(self.libvirtconnection.firewall_driver,
3898
'unfilter_instance', fake_unfilter_instance)
3900
self.mox.ReplayAll()
3901
self.libvirtconnection._cleanup_resize(ins_ref,
3902
_fake_network_info(self.stubs, 1))
3905
class LibvirtNonblockingTestCase(test.TestCase):
3906
"""Test libvirt_nonblocking option"""
3909
super(LibvirtNonblockingTestCase, self).setUp()
3910
self.flags(libvirt_nonblocking=True, libvirt_uri="test:///default")
3913
super(LibvirtNonblockingTestCase, self).tearDown()
3915
def test_connection_to_primitive(self):
3916
"""Test bug 962840"""
3917
import nova.virt.libvirt.driver as libvirt_driver
3918
connection = libvirt_driver.LibvirtDriver('')
3919
jsonutils.to_primitive(connection._conn, convert_instances=True)