~ubuntu-branches/ubuntu/raring/nova/raring-proposed

« back to all changes in this revision

Viewing changes to .pc/ubuntu/fix-libvirt-firewall-slowdown.patch/nova/tests/test_libvirt.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandelman, Chuck Short
  • Date: 2012-11-23 09:04:58 UTC
  • mfrom: (1.1.66)
  • Revision ID: package-import@ubuntu.com-20121123090458-91565o7aev1i1h71
Tags: 2013.1~g1-0ubuntu1
[ Adam Gandelman ]
* debian/control: Ensure novaclient is upgraded with nova,
  require python-keystoneclient >= 1:2.9.0. (LP: #1073289)
* debian/patches/{ubuntu/*, rbd-security.patch}: Dropped, applied
  upstream.
* debian/control: Add python-testtools to Build-Depends.

[ Chuck Short ]
* New upstream version.
* Refreshed debian/patches/avoid_setuptools_git_dependency.patch.
* debian/rules: FTBFS if missing binaries.
* debian/nova-scheudler.install: Add missing rabbit-queues and
  nova-rpc-zmq-receiver.
* Remove nova-volume since it doesnt exist anymore, transition to cinder-*.
* debian/rules: install apport hook in the right place.
* debian/patches/ubuntu-show-tests.patch: Display test failures.
* debian/control: Add depends on genisoimage
* debian/control: Suggest guestmount.
* debian/control: Suggest websockify. (LP: #1076442)
* debian/nova.conf: Disable nova-volume service.
* debian/control: Depend on xen-system-* rather than the hypervisor.
* debian/control, debian/mans/nova-conductor.8, debian/nova-conductor.init,
  debian/nova-conductor.install, debian/nova-conductor.logrotate
  debian/nova-conductor.manpages, debian/nova-conductor.postrm
  debian/nova-conductor.upstart.in: Add nova-conductor service.
* debian/control: Add python-fixtures as a build deps.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
#
3
 
#    Copyright 2010 OpenStack LLC
4
 
#    Copyright 2012 University Of Minho
5
 
#
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
9
 
#
10
 
#         http://www.apache.org/licenses/LICENSE-2.0
11
 
#
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
16
 
#    under the License.
17
 
 
18
 
import copy
19
 
import errno
20
 
import eventlet
21
 
import json
22
 
import mox
23
 
import os
24
 
import re
25
 
import shutil
26
 
import tempfile
27
 
 
28
 
from lxml import etree
29
 
from xml.dom import minidom
30
 
 
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
37
 
from nova import db
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
43
 
from nova import test
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
60
 
 
61
 
 
62
 
try:
63
 
    import libvirt
64
 
except ImportError:
65
 
    import nova.tests.fakelibvirt as libvirt
66
 
libvirt_driver.libvirt = libvirt
67
 
 
68
 
 
69
 
FLAGS = flags.FLAGS
70
 
LOG = logging.getLogger(__name__)
71
 
 
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
75
 
 
76
 
 
77
 
def _concurrency(wait, done, target):
78
 
    wait.wait()
79
 
    done.send()
80
 
 
81
 
 
82
 
class FakeVirDomainSnapshot(object):
83
 
 
84
 
    def __init__(self, dom=None):
85
 
        self.dom = dom
86
 
 
87
 
    def delete(self, flags):
88
 
        pass
89
 
 
90
 
 
91
 
class FakeVirtDomain(object):
92
 
 
93
 
    def __init__(self, fake_xml=None):
94
 
        if fake_xml:
95
 
            self._fake_dom_xml = fake_xml
96
 
        else:
97
 
            self._fake_dom_xml = """
98
 
                <domain type='kvm'>
99
 
                    <devices>
100
 
                        <disk type='file'>
101
 
                            <source file='filename'/>
102
 
                        </disk>
103
 
                    </devices>
104
 
                </domain>
105
 
            """
106
 
 
107
 
    def name(self):
108
 
        return "fake-domain %s" % self
109
 
 
110
 
    def info(self):
111
 
        return [power_state.RUNNING, None, None, None, None]
112
 
 
113
 
    def create(self):
114
 
        pass
115
 
 
116
 
    def managedSave(self, *args):
117
 
        pass
118
 
 
119
 
    def createWithFlags(self, launch_flags):
120
 
        pass
121
 
 
122
 
    def XMLDesc(self, *args):
123
 
        return self._fake_dom_xml
124
 
 
125
 
 
126
 
class LibvirtVolumeTestCase(test.TestCase):
127
 
 
128
 
    def setUp(self):
129
 
        super(LibvirtVolumeTestCase, self).setUp()
130
 
        self.executes = []
131
 
 
132
 
        def fake_execute(*cmd, **kwargs):
133
 
            self.executes.append(cmd)
134
 
            return None, None
135
 
 
136
 
        self.stubs.Set(utils, 'execute', fake_execute)
137
 
 
138
 
        class FakeLibvirtDriver(object):
139
 
            def __init__(self, hyperv="QEMU"):
140
 
                self.hyperv = hyperv
141
 
 
142
 
            def get_hypervisor_type(self):
143
 
                return self.hyperv
144
 
 
145
 
            def get_all_block_devices(self):
146
 
                return []
147
 
 
148
 
        self.fake_conn = FakeLibvirtDriver()
149
 
        self.connr = {
150
 
            'ip': '127.0.0.1',
151
 
            'initiator': 'fake_initiator',
152
 
            'host': 'fake_host'
153
 
        }
154
 
 
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}
160
 
        connection_info = {
161
 
            'driver_volume_type': 'fake',
162
 
            'data': {
163
 
                    'device_path': '/foo',
164
 
                },
165
 
            'serial': 'fake_serial',
166
 
        }
167
 
        mount_device = "vde"
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')
172
 
 
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
181
 
        vol = {'id': 1,
182
 
               'name': name,
183
 
               'provider_auth': None,
184
 
               'provider_location': '%s,fake %s' % (location, iqn)}
185
 
        connection_info = vol_driver.initialize_connection(vol, self.connr)
186
 
        mount_device = "vde"
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,
195
 
                              '-p', location),
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)
209
 
 
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)
220
 
        vol = {'id': 1,
221
 
               'name': name,
222
 
               'provider_auth': None,
223
 
               'provider_location': '%s,fake %s' % (location, iqn)}
224
 
        connection_info = vol_driver.initialize_connection(vol, self.connr)
225
 
        mount_device = "vde"
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,
234
 
                              '-p', location),
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)
241
 
 
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)
248
 
        mount_device = "vde"
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)
256
 
 
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)
263
 
        mount_device = "vde"
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)
273
 
 
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'
281
 
        user = 'foo'
282
 
        secret_type = 'ceph'
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
287
 
 
288
 
        mount_device = "vde"
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)
300
 
 
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'
308
 
        user = 'foo'
309
 
        secret_type = 'ceph'
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
314
 
 
315
 
        mount_device = "vde"
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)
325
 
 
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
333
 
        vol = {'id': 1,
334
 
               'name': name,
335
 
               'provider_auth': None,
336
 
               'provider_location': '%s,fake %s' % (location, iqn)}
337
 
        connection_info = vol_driver.initialize_connection(vol, self.connr)
338
 
        mount_device = "vde"
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)
346
 
 
347
 
    def test_libvirt_nfs_driver(self):
348
 
        # NOTE(vish) exists is to make driver assume connecting worked
349
 
        mnt_base = '/mnt'
350
 
        self.flags(nfs_mount_point_base=mnt_base)
351
 
 
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)
358
 
 
359
 
        connection_info = {'data': {'export': export_string, 'name': name}}
360
 
        mount_device = "vde"
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)
366
 
 
367
 
        expected_commands = [
368
 
            ('stat', export_mnt_base),
369
 
            ('mount', '-t', 'nfs', export_string, export_mnt_base)]
370
 
        self.assertEqual(self.executes, expected_commands)
371
 
 
372
 
 
373
 
class CacheConcurrencyTestCase(test.TestCase):
374
 
    def setUp(self):
375
 
        super(CacheConcurrencyTestCase, self).setUp()
376
 
        self.flags(instances_path='nova.compute.manager')
377
 
 
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)
385
 
 
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:
389
 
                return True
390
 
            return False
391
 
 
392
 
        def fake_execute(*args, **kwargs):
393
 
            pass
394
 
 
395
 
        def fake_extend(image, size):
396
 
            pass
397
 
 
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
402
 
 
403
 
    def tearDown(self):
404
 
        imagebackend.libvirt_utils = libvirt_utils
405
 
 
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)
409
 
 
410
 
        super(CacheConcurrencyTestCase, self).tearDown()
411
 
 
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)
423
 
        wait2.send()
424
 
        eventlet.sleep(0)
425
 
        try:
426
 
            self.assertFalse(done2.ready())
427
 
        finally:
428
 
            wait1.send()
429
 
        done1.wait()
430
 
        eventlet.sleep(0)
431
 
        self.assertTrue(done2.ready())
432
 
        # Wait on greenthreads to assert they didn't raise exceptions
433
 
        # during execution
434
 
        thr1.wait()
435
 
        thr2.wait()
436
 
 
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)
448
 
        wait2.send()
449
 
        eventlet.sleep(0)
450
 
        try:
451
 
            self.assertTrue(done2.ready())
452
 
        finally:
453
 
            wait1.send()
454
 
            eventlet.sleep(0)
455
 
        # Wait on greenthreads to assert they didn't raise exceptions
456
 
        # during execution
457
 
        thr1.wait()
458
 
        thr2.wait()
459
 
 
460
 
 
461
 
class FakeVolumeDriver(object):
462
 
    def __init__(self, *args, **kwargs):
463
 
        pass
464
 
 
465
 
    def attach_volume(self, *args):
466
 
        pass
467
 
 
468
 
    def detach_volume(self, *args):
469
 
        pass
470
 
 
471
 
    def get_xml(self, *args):
472
 
        return ""
473
 
 
474
 
 
475
 
class LibvirtConnTestCase(test.TestCase):
476
 
 
477
 
    def setUp(self):
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
487
 
 
488
 
        def fake_extend(image, size):
489
 
            pass
490
 
 
491
 
        self.stubs.Set(libvirt_driver.disk, 'extend', fake_extend)
492
 
 
493
 
        nova.tests.image.fake.stub_out_image_service(self.stubs)
494
 
 
495
 
    def tearDown(self):
496
 
        libvirt_driver.libvirt_utils = libvirt_utils
497
 
        nova.tests.image.fake.FakeImageService_reset()
498
 
        super(LibvirtConnTestCase, self).tearDown()
499
 
 
500
 
    test_instance = {'memory_kb': '1024000',
501
 
                     'basepath': '/some/path',
502
 
                     'bridge_name': 'br100',
503
 
                     'vcpus': 2,
504
 
                     'project_id': 'fake',
505
 
                     'bridge': 'br101',
506
 
                     'image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
507
 
                     'root_gb': 10,
508
 
                     'ephemeral_gb': 20,
509
 
                     'instance_type_id': '5'}  # m1.small
510
 
 
511
 
    def create_fake_libvirt_mock(self, **kwargs):
512
 
        """Defining mocks for LibvirtDriver(libvirt is not used)."""
513
 
 
514
 
        # A fake libvirt.virConnect
515
 
        class FakeLibvirtDriver(object):
516
 
            def defineXML(self, xml):
517
 
                return FakeVirtDomain()
518
 
 
519
 
        # Creating mocks
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)
526
 
 
527
 
        self.flags(libvirt_vif_driver="nova.tests.fake_network.FakeVIFDriver")
528
 
 
529
 
        self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
530
 
        libvirt_driver.LibvirtDriver._conn = fake
531
 
 
532
 
    def fake_lookup(self, instance_name):
533
 
        return FakeVirtDomain()
534
 
 
535
 
    def fake_execute(self, *args):
536
 
        open(args[-1], "a").close()
537
 
 
538
 
    def create_service(self, **kwargs):
539
 
        service_ref = {'host': kwargs.get('host', 'dummy'),
540
 
                       'binary': 'nova-compute',
541
 
                       'topic': 'compute',
542
 
                       'report_count': 0,
543
 
                       'availability_zone': 'zone'}
544
 
 
545
 
        return db.service_create(context.get_admin_context(), service_ref)
546
 
 
547
 
    def test_get_connector(self):
548
 
        initiator = 'fake.initiator.iqn'
549
 
        ip = 'fakeip'
550
 
        host = 'fakehost'
551
 
        self.flags(my_ip=ip)
552
 
        self.flags(host=host)
553
 
 
554
 
        conn = libvirt_driver.LibvirtDriver(True)
555
 
        expected = {
556
 
            'ip': ip,
557
 
            'initiator': initiator,
558
 
            'host': host
559
 
        }
560
 
        volume = {
561
 
            'id': 'fake'
562
 
        }
563
 
        result = conn.get_volume_connector(volume)
564
 
        self.assertDictMatch(expected, result)
565
 
 
566
 
    def test_get_guest_config(self):
567
 
        conn = libvirt_driver.LibvirtDriver(True)
568
 
        instance_ref = db.instance_create(self.context, self.test_instance)
569
 
 
570
 
        cfg = conn.get_guest_config(instance_ref,
571
 
                                    _fake_network_info(self.stubs, 1),
572
 
                                    None, None)
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)
594
 
 
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,
605
 
                          "delay")
606
 
        self.assertEquals(cfg.clock.timers[1].name, "rtc")
607
 
        self.assertEquals(cfg.clock.timers[1].tickpolicy,
608
 
                          "catchup")
609
 
 
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)
613
 
 
614
 
        cfg = conn.get_guest_config(instance_ref,
615
 
                                    _fake_network_info(self.stubs, 2),
616
 
                                    None, None)
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)
640
 
 
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)
645
 
 
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)
661
 
 
662
 
    def test_get_guest_config_with_block_device(self):
663
 
        conn = libvirt_driver.LibvirtDriver(True)
664
 
 
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'}]}
670
 
 
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')
678
 
 
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)
683
 
 
684
 
        conf = conn.get_guest_config(instance_ref,
685
 
                                    _fake_network_info(self.stubs, 1),
686
 
                                    None, None)
687
 
        self.assertEquals(conf.cpu, None)
688
 
 
689
 
    def test_get_guest_cpu_config_default_kvm(self):
690
 
        self.flags(libvirt_type="kvm",
691
 
                   libvirt_cpu_mode=None)
692
 
 
693
 
        def get_lib_version_stub(self):
694
 
            return (0 * 1000 * 1000) + (9 * 1000) + 11
695
 
 
696
 
        self.stubs.Set(libvirt.virConnect,
697
 
                       "getLibVersion",
698
 
                       get_lib_version_stub)
699
 
        conn = libvirt_driver.LibvirtDriver(True)
700
 
        instance_ref = db.instance_create(self.context, self.test_instance)
701
 
 
702
 
        conf = conn.get_guest_config(instance_ref,
703
 
                                     _fake_network_info(self.stubs, 1),
704
 
                                     None, None)
705
 
        self.assertEquals(type(conf.cpu),
706
 
                          config.LibvirtConfigGuestCPU)
707
 
        self.assertEquals(conf.cpu.mode, "host-model")
708
 
        self.assertEquals(conf.cpu.model, None)
709
 
 
710
 
    def test_get_guest_cpu_config_default_uml(self):
711
 
        self.flags(libvirt_type="uml",
712
 
                   libvirt_cpu_mode=None)
713
 
 
714
 
        conn = libvirt_driver.LibvirtDriver(True)
715
 
        instance_ref = db.instance_create(self.context, self.test_instance)
716
 
 
717
 
        conf = conn.get_guest_config(instance_ref,
718
 
                                    _fake_network_info(self.stubs, 1),
719
 
                                    None, None)
720
 
        self.assertEquals(conf.cpu, None)
721
 
 
722
 
    def test_get_guest_cpu_config_default_lxc(self):
723
 
        self.flags(libvirt_type="lxc",
724
 
                   libvirt_cpu_mode=None)
725
 
 
726
 
        conn = libvirt_driver.LibvirtDriver(True)
727
 
        instance_ref = db.instance_create(self.context, self.test_instance)
728
 
 
729
 
        conf = conn.get_guest_config(instance_ref,
730
 
                                    _fake_network_info(self.stubs, 1),
731
 
                                    None, None)
732
 
        self.assertEquals(conf.cpu, None)
733
 
 
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
737
 
 
738
 
        self.stubs.Set(libvirt.virConnect,
739
 
                       "getLibVersion",
740
 
                       get_lib_version_stub)
741
 
        conn = libvirt_driver.LibvirtDriver(True)
742
 
        instance_ref = db.instance_create(self.context, self.test_instance)
743
 
 
744
 
        self.flags(libvirt_cpu_mode="host-passthrough")
745
 
        conf = conn.get_guest_config(instance_ref,
746
 
                                     _fake_network_info(self.stubs, 1),
747
 
                                     None, None)
748
 
        self.assertEquals(type(conf.cpu),
749
 
                          config.LibvirtConfigGuestCPU)
750
 
        self.assertEquals(conf.cpu.mode, "host-passthrough")
751
 
        self.assertEquals(conf.cpu.model, None)
752
 
 
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
756
 
 
757
 
        self.stubs.Set(libvirt.virConnect,
758
 
                       "getLibVersion",
759
 
                       get_lib_version_stub)
760
 
        conn = libvirt_driver.LibvirtDriver(True)
761
 
        instance_ref = db.instance_create(self.context, self.test_instance)
762
 
 
763
 
        self.flags(libvirt_cpu_mode="host-model")
764
 
        conf = conn.get_guest_config(instance_ref,
765
 
                                     _fake_network_info(self.stubs, 1),
766
 
                                     None, None)
767
 
        self.assertEquals(type(conf.cpu),
768
 
                          config.LibvirtConfigGuestCPU)
769
 
        self.assertEquals(conf.cpu.mode, "host-model")
770
 
        self.assertEquals(conf.cpu.model, None)
771
 
 
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
775
 
 
776
 
        self.stubs.Set(libvirt.virConnect,
777
 
                       "getLibVersion",
778
 
                       get_lib_version_stub)
779
 
        conn = libvirt_driver.LibvirtDriver(True)
780
 
        instance_ref = db.instance_create(self.context, self.test_instance)
781
 
 
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),
786
 
                                     None, None)
787
 
        self.assertEquals(type(conf.cpu),
788
 
                          config.LibvirtConfigGuestCPU)
789
 
        self.assertEquals(conf.cpu.mode, "custom")
790
 
        self.assertEquals(conf.cpu.model, "Penryn")
791
 
 
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
795
 
 
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)
800
 
 
801
 
        self.flags(libvirt_cpu_mode="host-passthrough")
802
 
        self.assertRaises(exception.NovaException,
803
 
                          conn.get_guest_config,
804
 
                          instance_ref,
805
 
                          _fake_network_info(self.stubs, 1),
806
 
                          None, None)
807
 
 
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
811
 
 
812
 
        # Ensure we have a predictable host CPU
813
 
        def get_host_capabilities_stub(self):
814
 
            cpu = config.LibvirtConfigGuestCPU()
815
 
            cpu.model = "Opteron_G4"
816
 
            cpu.vendor = "AMD"
817
 
 
818
 
            caps = config.LibvirtConfigCaps()
819
 
            caps.host = config.LibvirtConfigCapsHost()
820
 
            caps.host.cpu = cpu
821
 
            return caps
822
 
 
823
 
        self.stubs.Set(libvirt.virConnect,
824
 
                       "getLibVersion",
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)
831
 
 
832
 
        self.flags(libvirt_cpu_mode="host-model")
833
 
        conf = conn.get_guest_config(instance_ref,
834
 
                                     _fake_network_info(self.stubs, 1),
835
 
                                     None, None)
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")
841
 
 
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
845
 
 
846
 
        self.stubs.Set(libvirt.virConnect,
847
 
                       "getLibVersion",
848
 
                       get_lib_version_stub)
849
 
        conn = libvirt_driver.LibvirtDriver(True)
850
 
        instance_ref = db.instance_create(self.context, self.test_instance)
851
 
 
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),
856
 
                                     None, None)
857
 
        self.assertEquals(type(conf.cpu),
858
 
                          config.LibvirtConfigGuestCPU)
859
 
        self.assertEquals(conf.cpu.mode, None)
860
 
        self.assertEquals(conf.cpu.model, "Penryn")
861
 
 
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)
866
 
 
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)
872
 
 
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,
878
 
                                xen_only=True)
879
 
 
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)
885
 
 
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)
891
 
 
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)
898
 
 
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)
905
 
 
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)
910
 
 
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)
916
 
 
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)
922
 
 
923
 
    def test_xml_uuid(self):
924
 
        instance_data = dict(self.test_instance)
925
 
        self._check_xml_and_uuid(instance_data)
926
 
 
927
 
    def test_lxc_container_and_uri(self):
928
 
        instance_data = dict(self.test_instance)
929
 
        self._check_xml_and_container(instance_data)
930
 
 
931
 
    def test_xml_disk_prefix(self):
932
 
        instance_data = dict(self.test_instance)
933
 
        self._check_xml_and_disk_prefix(instance_data)
934
 
 
935
 
    def test_xml_disk_driver(self):
936
 
        instance_data = dict(self.test_instance)
937
 
        self._check_xml_and_disk_driver(instance_data)
938
 
 
939
 
    def test_xml_disk_bus_virtio(self):
940
 
        self._check_xml_and_disk_bus({"disk_format": "raw"},
941
 
                                     None,
942
 
                                     (("disk", "virtio", "vda"),))
943
 
 
944
 
    def test_xml_disk_bus_ide(self):
945
 
        self._check_xml_and_disk_bus({"disk_format": "iso"},
946
 
                                     None,
947
 
                                     (("cdrom", "ide", "hda"),))
948
 
 
949
 
    def test_xml_disk_bus_ide_and_virtio(self):
950
 
        swap = {'device_name': '/dev/vdc',
951
 
                'swap_size': 1}
952
 
        ephemerals = [{'num': 0,
953
 
                       'virtual_name': 'ephemeral0',
954
 
                       'device_name': '/dev/vdb',
955
 
                       'size': 1}]
956
 
        block_device_info = {
957
 
                'swap': swap,
958
 
                'ephemerals': ephemerals}
959
 
 
960
 
        self._check_xml_and_disk_bus({"disk_format": "iso"},
961
 
                                     block_device_info,
962
 
                                     (("cdrom", "ide", "hda"),
963
 
                                      ("disk", "virtio", "vdb"),
964
 
                                      ("disk", "virtio", "vdc")))
965
 
 
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]
971
 
 
972
 
        self.mox.ReplayAll()
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)
977
 
 
978
 
    def test_list_instances_when_instance_deleted(self):
979
 
 
980
 
        def fake_lookup(instance_name):
981
 
            raise libvirt.libvirtError("we deleted an instance!")
982
 
 
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]
987
 
 
988
 
        self.mox.ReplayAll()
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)
993
 
 
994
 
    def test_get_all_block_devices(self):
995
 
        xml = [
996
 
            # NOTE(vish): id 0 is skipped
997
 
            None,
998
 
            """
999
 
                <domain type='kvm'>
1000
 
                    <devices>
1001
 
                        <disk type='file'>
1002
 
                            <source file='filename'/>
1003
 
                        </disk>
1004
 
                        <disk type='block'>
1005
 
                            <source dev='/path/to/dev/1'/>
1006
 
                        </disk>
1007
 
                    </devices>
1008
 
                </domain>
1009
 
            """,
1010
 
            """
1011
 
                <domain type='kvm'>
1012
 
                    <devices>
1013
 
                        <disk type='file'>
1014
 
                            <source file='filename'/>
1015
 
                        </disk>
1016
 
                    </devices>
1017
 
                </domain>
1018
 
            """,
1019
 
            """
1020
 
                <domain type='kvm'>
1021
 
                    <devices>
1022
 
                        <disk type='file'>
1023
 
                            <source file='filename'/>
1024
 
                        </disk>
1025
 
                        <disk type='block'>
1026
 
                            <source dev='/path/to/dev/3'/>
1027
 
                        </disk>
1028
 
                    </devices>
1029
 
                </domain>
1030
 
            """,
1031
 
        ]
1032
 
 
1033
 
        def fake_lookup(id):
1034
 
            return FakeVirtDomain(xml[id])
1035
 
 
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
1040
 
 
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'])
1045
 
 
1046
 
    def test_get_disks(self):
1047
 
        xml = [
1048
 
            # NOTE(vish): id 0 is skipped
1049
 
            None,
1050
 
            """
1051
 
                <domain type='kvm'>
1052
 
                    <devices>
1053
 
                        <disk type='file'>
1054
 
                            <source file='filename'/>
1055
 
                            <target dev='vda' bus='virtio'/>
1056
 
                        </disk>
1057
 
                        <disk type='block'>
1058
 
                            <source dev='/path/to/dev/1'/>
1059
 
                            <target dev='vdb' bus='virtio'/>
1060
 
                        </disk>
1061
 
                    </devices>
1062
 
                </domain>
1063
 
            """,
1064
 
            """
1065
 
                <domain type='kvm'>
1066
 
                    <devices>
1067
 
                        <disk type='file'>
1068
 
                            <source file='filename'/>
1069
 
                            <target dev='vda' bus='virtio'/>
1070
 
                        </disk>
1071
 
                    </devices>
1072
 
                </domain>
1073
 
            """,
1074
 
            """
1075
 
                <domain type='kvm'>
1076
 
                    <devices>
1077
 
                        <disk type='file'>
1078
 
                            <source file='filename'/>
1079
 
                            <target dev='vda' bus='virtio'/>
1080
 
                        </disk>
1081
 
                        <disk type='block'>
1082
 
                            <source dev='/path/to/dev/3'/>
1083
 
                            <target dev='vdb' bus='virtio'/>
1084
 
                        </disk>
1085
 
                    </devices>
1086
 
                </domain>
1087
 
            """,
1088
 
        ]
1089
 
 
1090
 
        def fake_lookup(id):
1091
 
            return FakeVirtDomain(xml[id])
1092
 
 
1093
 
        def fake_lookup_name(name):
1094
 
            return FakeVirtDomain(xml[1])
1095
 
 
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
1101
 
 
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'])
1106
 
 
1107
 
    def test_snapshot_in_ami_format(self):
1108
 
        self.flags(libvirt_snapshots_directory='./')
1109
 
 
1110
 
        # Start test
1111
 
        image_service = nova.tests.image.fake.FakeImageService()
1112
 
 
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'
1116
 
 
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)
1127
 
 
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
1132
 
 
1133
 
        self.mox.ReplayAll()
1134
 
 
1135
 
        conn = libvirt_driver.LibvirtDriver(False)
1136
 
        conn.snapshot(self.context, instance_ref, recv_meta['id'])
1137
 
 
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)
1143
 
 
1144
 
    def test_snapshot_in_raw_format(self):
1145
 
        self.flags(libvirt_snapshots_directory='./')
1146
 
 
1147
 
        # Start test
1148
 
        image_service = nova.tests.image.fake.FakeImageService()
1149
 
 
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)
1160
 
 
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
1165
 
 
1166
 
        self.mox.ReplayAll()
1167
 
 
1168
 
        conn = libvirt_driver.LibvirtDriver(False)
1169
 
        conn.snapshot(self.context, instance_ref, recv_meta['id'])
1170
 
 
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)
1176
 
 
1177
 
    def test_snapshot_in_qcow2_format(self):
1178
 
        self.flags(snapshot_image_format='qcow2',
1179
 
                   libvirt_snapshots_directory='./')
1180
 
 
1181
 
        # Start test
1182
 
        image_service = nova.tests.image.fake.FakeImageService()
1183
 
 
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)
1194
 
 
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
1199
 
 
1200
 
        self.mox.ReplayAll()
1201
 
 
1202
 
        conn = libvirt_driver.LibvirtDriver(False)
1203
 
        conn.snapshot(self.context, instance_ref, recv_meta['id'])
1204
 
 
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)
1210
 
 
1211
 
    def test_snapshot_no_image_architecture(self):
1212
 
        self.flags(libvirt_snapshots_directory='./')
1213
 
 
1214
 
        # Start test
1215
 
        image_service = nova.tests.image.fake.FakeImageService()
1216
 
 
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'
1221
 
 
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)
1232
 
 
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
1237
 
 
1238
 
        self.mox.ReplayAll()
1239
 
 
1240
 
        conn = libvirt_driver.LibvirtDriver(False)
1241
 
        conn.snapshot(self.context, instance_ref, recv_meta['id'])
1242
 
 
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)
1247
 
 
1248
 
    def test_snapshot_no_original_image(self):
1249
 
        self.flags(libvirt_snapshots_directory='./')
1250
 
 
1251
 
        # Start test
1252
 
        image_service = nova.tests.image.fake.FakeImageService()
1253
 
 
1254
 
        # Assign a non-existent image
1255
 
        test_instance = copy.deepcopy(self.test_instance)
1256
 
        test_instance["image_ref"] = '661122aa-1234-dede-fefe-babababababa'
1257
 
 
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)
1265
 
 
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
1270
 
 
1271
 
        self.mox.ReplayAll()
1272
 
 
1273
 
        conn = libvirt_driver.LibvirtDriver(False)
1274
 
        conn.snapshot(self.context, instance_ref, recv_meta['id'])
1275
 
 
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)
1280
 
 
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,
1287
 
                          conn.attach_volume,
1288
 
                          {"driver_volume_type": "badtype"},
1289
 
                           "fake",
1290
 
                           "/dev/fake")
1291
 
 
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'))
1305
 
 
1306
 
    def _check_xml_and_container(self, instance):
1307
 
        user_context = context.RequestContext(self.user_id,
1308
 
                                              self.project_id)
1309
 
        instance_ref = db.instance_create(user_context, instance)
1310
 
 
1311
 
        self.flags(libvirt_type='lxc')
1312
 
        conn = libvirt_driver.LibvirtDriver(True)
1313
 
 
1314
 
        self.assertEquals(conn.uri, 'lxc:///')
1315
 
 
1316
 
        network_info = _fake_network_info(self.stubs, 1)
1317
 
        xml = conn.to_xml(instance_ref, network_info)
1318
 
        tree = etree.fromstring(xml)
1319
 
 
1320
 
        check = [
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'), '/')]
1324
 
 
1325
 
        for i, (check, expected_result) in enumerate(check):
1326
 
            self.assertEqual(check(tree),
1327
 
                             expected_result,
1328
 
                             '%s failed common check %d' % (xml, i))
1329
 
 
1330
 
        target = tree.find('./devices/filesystem/source').get('dir')
1331
 
        self.assertTrue(len(target) > 0)
1332
 
 
1333
 
    def _check_xml_and_disk_prefix(self, instance):
1334
 
        user_context = context.RequestContext(self.user_id,
1335
 
                                              self.project_id)
1336
 
        instance_ref = db.instance_create(user_context, instance)
1337
 
 
1338
 
        type_disk_map = {
1339
 
            'qemu': [
1340
 
               (lambda t: t.find('.').get('type'), 'qemu'),
1341
 
               (lambda t: t.find('./devices/disk/target').get('dev'), 'vda')],
1342
 
            'xen': [
1343
 
               (lambda t: t.find('.').get('type'), 'xen'),
1344
 
               (lambda t: t.find('./devices/disk/target').get('dev'), 'sda')],
1345
 
            'kvm': [
1346
 
               (lambda t: t.find('.').get('type'), 'kvm'),
1347
 
               (lambda t: t.find('./devices/disk/target').get('dev'), 'vda')],
1348
 
            'uml': [
1349
 
               (lambda t: t.find('.').get('type'), 'uml'),
1350
 
               (lambda t: t.find('./devices/disk/target').get('dev'), 'ubda')]
1351
 
            }
1352
 
 
1353
 
        for (libvirt_type, checks) in type_disk_map.iteritems():
1354
 
            self.flags(libvirt_type=libvirt_type)
1355
 
            conn = libvirt_driver.LibvirtDriver(True)
1356
 
 
1357
 
            network_info = _fake_network_info(self.stubs, 1)
1358
 
            xml = conn.to_xml(instance_ref, network_info)
1359
 
            tree = etree.fromstring(xml)
1360
 
 
1361
 
            for i, (check, expected_result) in enumerate(checks):
1362
 
                self.assertEqual(check(tree),
1363
 
                                 expected_result,
1364
 
                                 '%s != %s failed check %d' %
1365
 
                                 (check(tree), expected_result, i))
1366
 
 
1367
 
    def _check_xml_and_disk_driver(self, image_meta):
1368
 
        os_open = os.open
1369
 
        directio_supported = True
1370
 
 
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)
1378
 
 
1379
 
        self.stubs.Set(os, 'open', os_open_stub)
1380
 
 
1381
 
        def connection_supports_direct_io_stub(*args, **kwargs):
1382
 
            return directio_supported
1383
 
 
1384
 
        self.stubs.Set(libvirt_driver.LibvirtDriver,
1385
 
            '_supports_direct_io', connection_supports_direct_io_stub)
1386
 
 
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)
1390
 
 
1391
 
        xml = libvirt_driver.LibvirtDriver(True).to_xml(instance_ref,
1392
 
                                                        network_info,
1393
 
                                                        image_meta)
1394
 
        tree = etree.fromstring(xml)
1395
 
        disks = tree.findall('./devices/disk/driver')
1396
 
        for disk in disks:
1397
 
            self.assertEqual(disk.get("cache"), "none")
1398
 
 
1399
 
        directio_supported = False
1400
 
 
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,
1404
 
                                                        network_info,
1405
 
                                                        image_meta)
1406
 
        tree = etree.fromstring(xml)
1407
 
        disks = tree.findall('./devices/disk/driver')
1408
 
        for disk in disks:
1409
 
            self.assertEqual(disk.get("cache"), "writethrough")
1410
 
 
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)
1416
 
 
1417
 
        xml = libvirt_driver.LibvirtDriver(True).to_xml(
1418
 
            instance_ref,
1419
 
            network_info,
1420
 
            image_meta,
1421
 
            block_device_info=block_device_info)
1422
 
        tree = etree.fromstring(xml)
1423
 
 
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]
1430
 
 
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')
1434
 
 
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)
1438
 
 
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)
1443
 
 
1444
 
        xml = libvirt_driver.LibvirtDriver(True).to_xml(instance_ref,
1445
 
                                                        network_info,
1446
 
                                                        image_meta)
1447
 
        tree = etree.fromstring(xml)
1448
 
        self.assertEqual(tree.find('./uuid').text,
1449
 
                         instance_ref['uuid'])
1450
 
 
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(),
1456
 
                                             self.project_id)[0]
1457
 
 
1458
 
        type_uri_map = {'qemu': ('qemu:///system',
1459
 
                             [(lambda t: t.find('.').get('type'), 'qemu'),
1460
 
                              (lambda t: t.find('./os/type').text,
1461
 
                               vm_mode.HVM),
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,
1466
 
                               vm_mode.HVM),
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,
1471
 
                               vm_mode.UML)]),
1472
 
                        'xen': ('xen:///',
1473
 
                             [(lambda t: t.find('.').get('type'), 'xen'),
1474
 
                              (lambda t: t.find('./os/type').text,
1475
 
                               vm_mode.XEN)])}
1476
 
 
1477
 
        if expect_xen_hvm or xen_only:
1478
 
            hypervisors_to_check = ['xen']
1479
 
        else:
1480
 
            hypervisors_to_check = ['qemu', 'kvm', 'xen']
1481
 
 
1482
 
        if expect_xen_hvm:
1483
 
            type_uri_map = {}
1484
 
            type_uri_map['xen'] = ('xen:///',
1485
 
                                   [(lambda t: t.find('.').get('type'),
1486
 
                                       'xen'),
1487
 
                                    (lambda t: t.find('./os/type').text,
1488
 
                                        vm_mode.HVM)])
1489
 
 
1490
 
        for hypervisor_type in hypervisors_to_check:
1491
 
            check_list = type_uri_map[hypervisor_type][1]
1492
 
 
1493
 
            if rescue:
1494
 
                suffix = '.rescue'
1495
 
            else:
1496
 
                suffix = ''
1497
 
            if expect_kernel:
1498
 
                check = (lambda t: t.find('./os/kernel').text.split(
1499
 
                    '/')[1], 'kernel' + suffix)
1500
 
            else:
1501
 
                check = (lambda t: t.find('./os/kernel'), None)
1502
 
            check_list.append(check)
1503
 
 
1504
 
            # Hypervisors that only support vm_mode.HVM should
1505
 
            # not produce configuration that results in kernel
1506
 
            # arguments
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)
1512
 
 
1513
 
            if expect_ramdisk:
1514
 
                check = (lambda t: t.find('./os/initrd').text.split(
1515
 
                    '/')[1], 'ramdisk' + suffix)
1516
 
            else:
1517
 
                check = (lambda t: t.find('./os/initrd'), None)
1518
 
            check_list.append(check)
1519
 
 
1520
 
            if hypervisor_type in ['qemu', 'kvm']:
1521
 
                check = (lambda t: t.findall('./devices/serial')[0].get(
1522
 
                        'type'), 'file')
1523
 
                check_list.append(check)
1524
 
                check = (lambda t: t.findall('./devices/serial')[1].get(
1525
 
                        'type'), 'pty')
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)
1530
 
            else:
1531
 
                check = (lambda t: t.find('./devices/console').get(
1532
 
                        'type'), 'pty')
1533
 
                check_list.append(check)
1534
 
 
1535
 
        parameter = './devices/interface/filterref/parameter'
1536
 
        common_checks = [
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'),
1540
 
             True),
1541
 
            (lambda t: t.find('./memory').text, '2097152')]
1542
 
        if rescue:
1543
 
            common_checks += [
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')]
1548
 
        else:
1549
 
            common_checks += [(lambda t: t.findall(
1550
 
                './devices/disk/source')[0].get('file').split('/')[1],
1551
 
                               'disk')]
1552
 
            common_checks += [(lambda t: t.findall(
1553
 
                './devices/disk/source')[1].get('file').split('/')[1],
1554
 
                               'disk.local')]
1555
 
 
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)
1559
 
 
1560
 
            self.assertEquals(conn.uri, expected_uri)
1561
 
 
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),
1567
 
                                 expected_result,
1568
 
                                 '%s != %s failed check %d' %
1569
 
                                 (check(tree), expected_result, i))
1570
 
 
1571
 
            for i, (check, expected_result) in enumerate(common_checks):
1572
 
                self.assertEqual(check(tree),
1573
 
                                 expected_result,
1574
 
                                 '%s != %s failed common check %d' %
1575
 
                                 (check(tree), expected_result, i))
1576
 
 
1577
 
        # This test is supposed to make sure we don't
1578
 
        # override a specifically set uri
1579
 
        #
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'])
1590
 
 
1591
 
    def test_ensure_filtering_rules_for_instance_timeout(self):
1592
 
        """ensure_filtering_fules_for_instance() finishes with timeout."""
1593
 
        # Preparing mocks
1594
 
        def fake_none(self, *args):
1595
 
            return
1596
 
 
1597
 
        def fake_raise(self):
1598
 
            raise libvirt.libvirtError('ERR')
1599
 
 
1600
 
        class FakeTime(object):
1601
 
            def __init__(self):
1602
 
                self.counter = 0
1603
 
 
1604
 
            def sleep(self, t):
1605
 
                self.counter += t
1606
 
 
1607
 
        fake_timer = FakeTime()
1608
 
 
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)
1615
 
 
1616
 
        # Start test
1617
 
        self.mox.ReplayAll()
1618
 
        try:
1619
 
            conn = libvirt_driver.LibvirtDriver(False)
1620
 
            self.stubs.Set(conn.firewall_driver,
1621
 
                           'setup_basic_filtering',
1622
 
                           fake_none)
1623
 
            self.stubs.Set(conn.firewall_driver,
1624
 
                           'prepare_instance_filter',
1625
 
                           fake_none)
1626
 
            self.stubs.Set(conn.firewall_driver,
1627
 
                           'instance_filter_exists',
1628
 
                           fake_none)
1629
 
            conn.ensure_filtering_rules_for_instance(instance_ref,
1630
 
                                                     network_info,
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))
1636
 
        self.assertTrue(c1)
1637
 
 
1638
 
        self.assertEqual(29, fake_timer.counter, "Didn't wait the expected "
1639
 
                                                 "amount of time")
1640
 
 
1641
 
        db.instance_destroy(self.context, instance_ref['uuid'])
1642
 
 
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)
1648
 
 
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')
1652
 
 
1653
 
        conn._get_compute_info(self.context, FLAGS.host).AndReturn(
1654
 
                                              {'disk_available_least': 400})
1655
 
        # _check_cpu_match
1656
 
        conn._get_compute_info(self.context,
1657
 
                               src).AndReturn({'cpu_info': "asdf"})
1658
 
        conn._compare_cpu("asdf")
1659
 
 
1660
 
        # mounted_on_same_shared_storage
1661
 
        filename = "file"
1662
 
        conn._create_shared_storage_test_file().AndReturn(filename)
1663
 
 
1664
 
        self.mox.ReplayAll()
1665
 
        return_value = conn.check_can_live_migrate_destination(self.context,
1666
 
                                instance_ref, True)
1667
 
        self.assertDictMatch(return_value,
1668
 
                             {"filename": "file",
1669
 
                              'disk_available_mb': 409600,
1670
 
                              "disk_over_commit": False,
1671
 
                              "block_migration": True})
1672
 
 
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)
1678
 
 
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')
1682
 
 
1683
 
        # _check_cpu_match
1684
 
        conn._get_compute_info(self.context,
1685
 
                               src).AndReturn({'cpu_info': "asdf"})
1686
 
        conn._compare_cpu("asdf")
1687
 
 
1688
 
        # mounted_on_same_shared_storage
1689
 
        filename = "file"
1690
 
        conn._create_shared_storage_test_file().AndReturn(filename)
1691
 
 
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})
1700
 
 
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)
1706
 
 
1707
 
        self.mox.StubOutWithMock(conn, '_get_compute_info')
1708
 
        self.mox.StubOutWithMock(conn, '_compare_cpu')
1709
 
 
1710
 
        conn._get_compute_info(self.context, src).AndReturn(
1711
 
                {'cpu_info': "asdf"})
1712
 
        conn._compare_cpu("asdf").AndRaise(exception.InvalidCPUInfo)
1713
 
 
1714
 
        self.mox.ReplayAll()
1715
 
        self.assertRaises(exception.InvalidCPUInfo,
1716
 
                          conn.check_can_live_migrate_destination,
1717
 
                          self.context, instance_ref, False)
1718
 
 
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)
1726
 
 
1727
 
        self.mox.StubOutWithMock(conn, '_cleanup_shared_storage_test_file')
1728
 
        conn._cleanup_shared_storage_test_file("file")
1729
 
 
1730
 
        self.mox.ReplayAll()
1731
 
        conn.check_can_live_migrate_destination_cleanup(self.context,
1732
 
                                                        dest_check_data)
1733
 
 
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)
1741
 
 
1742
 
        self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
1743
 
        conn._check_shared_storage_test_file("file").AndReturn(False)
1744
 
 
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'],
1748
 
                                               False)
1749
 
 
1750
 
        self.mox.ReplayAll()
1751
 
        conn.check_can_live_migrate_source(self.context, instance_ref,
1752
 
                                           dest_check_data)
1753
 
 
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)
1761
 
 
1762
 
        self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
1763
 
        conn._check_shared_storage_test_file("file").AndReturn(True)
1764
 
 
1765
 
        self.mox.ReplayAll()
1766
 
        self.assertRaises(exception.InvalidLocalStorage,
1767
 
                          conn.check_can_live_migrate_source,
1768
 
                          self.context, instance_ref, dest_check_data)
1769
 
 
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)
1777
 
 
1778
 
        self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
1779
 
        conn._check_shared_storage_test_file("file").AndReturn(False)
1780
 
 
1781
 
        self.mox.ReplayAll()
1782
 
        self.assertRaises(exception.InvalidSharedStorage,
1783
 
                          conn.check_can_live_migrate_source,
1784
 
                          self.context, instance_ref, dest_check_data)
1785
 
 
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)
1791
 
 
1792
 
        self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
1793
 
        conn._check_shared_storage_test_file("file").AndReturn(False)
1794
 
 
1795
 
        self.mox.StubOutWithMock(conn, "get_instance_disk_info")
1796
 
        conn.get_instance_disk_info(instance_ref["name"]).AndReturn(
1797
 
                                            '[{"virt_disk_size":2}]')
1798
 
 
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)
1807
 
 
1808
 
    def test_live_migration_raises_exception(self):
1809
 
        """Confirms recover method is called when exceptions are raised."""
1810
 
        # Preparing data
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'],
1817
 
                                          instance_dict)
1818
 
        vol_dict = {'status': 'migrating', 'size': 1}
1819
 
        volume_ref = db.volume_create(self.context, vol_dict)
1820
 
        db.volume_attached(self.context,
1821
 
                           volume_ref['id'],
1822
 
                           instance_ref['uuid'],
1823
 
                           '/dev/fake')
1824
 
 
1825
 
        # Preparing mocks
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',
1830
 
                            mox.IgnoreArg(),
1831
 
                            None,
1832
 
                            _bandwidth).AndRaise(libvirt.libvirtError('ERR'))
1833
 
 
1834
 
        def fake_lookup(instance_name):
1835
 
            if instance_name == instance_ref.name:
1836
 
                return vdmock
1837
 
 
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,
1841
 
                                              'dest', False)
1842
 
 
1843
 
        #start test
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)
1850
 
 
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')
1856
 
 
1857
 
        db.volume_destroy(self.context, volume_ref['id'])
1858
 
        db.instance_destroy(self.context, instance_ref['uuid'])
1859
 
 
1860
 
    def test_pre_live_migration_works_correctly_mocked(self):
1861
 
        # Creating testdata
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)
1866
 
 
1867
 
        class FakeNetworkInfo():
1868
 
            def fixed_ips(self):
1869
 
                return ["test_ip_addr"]
1870
 
 
1871
 
        inst_ref = {'id': 'foo'}
1872
 
        c = context.get_admin_context()
1873
 
        nw_info = FakeNetworkInfo()
1874
 
 
1875
 
        # Creating mocks
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)
1886
 
 
1887
 
        self.mox.ReplayAll()
1888
 
        result = conn.pre_live_migration(c, inst_ref, vol, nw_info)
1889
 
        self.assertEqual(result, None)
1890
 
 
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)
1895
 
 
1896
 
            # Test data
1897
 
            instance_ref = db.instance_create(self.context, self.test_instance)
1898
 
            dummy_info = [{'path': '%s/disk' % tmpdir,
1899
 
                           'disk_size': 10737418240,
1900
 
                           'type': 'raw',
1901
 
                           'backing_file': ''},
1902
 
                          {'backing_file': 'otherdisk_1234567',
1903
 
                           'path': '%s/otherdisk' % tmpdir,
1904
 
                           'virt_disk_size': 10737418240}]
1905
 
            dummyjson = json.dumps(dummy_info)
1906
 
 
1907
 
            # qemu-img should be mockd since test environment might not have
1908
 
            # large disk space.
1909
 
            self.mox.StubOutWithMock(imagebackend.Image, 'cache')
1910
 
            imagebackend.Image.cache(context=mox.IgnoreArg(),
1911
 
                                     fetch_func=mox.IgnoreArg(),
1912
 
                                     filename='otherdisk',
1913
 
                                     image_id=123456,
1914
 
                                     project_id='fake',
1915
 
                                     size=10737418240L,
1916
 
                                     user_id=None).AndReturn(None)
1917
 
            self.mox.ReplayAll()
1918
 
 
1919
 
            conn = libvirt_driver.LibvirtDriver(False)
1920
 
            conn.pre_block_migration(self.context, instance_ref,
1921
 
                                     dummyjson)
1922
 
 
1923
 
            self.assertTrue(os.path.exists('%s/%s/' %
1924
 
                                           (tmpdir, instance_ref.name)))
1925
 
 
1926
 
        db.instance_destroy(self.context, instance_ref['uuid'])
1927
 
 
1928
 
    def test_get_instance_disk_info_works_correctly(self):
1929
 
        # Test data
1930
 
        instance_ref = db.instance_create(self.context, self.test_instance)
1931
 
        dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
1932
 
                    "<devices>"
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>")
1940
 
 
1941
 
        # Preparing mocks
1942
 
        vdmock = self.mox.CreateMock(libvirt.virDomain)
1943
 
        self.mox.StubOutWithMock(vdmock, "XMLDesc")
1944
 
        vdmock.XMLDesc(0).AndReturn(dummyxml)
1945
 
 
1946
 
        def fake_lookup(instance_name):
1947
 
            if instance_name == instance_ref.name:
1948
 
                return vdmock
1949
 
        self.create_fake_libvirt_mock(lookupByName=fake_lookup)
1950
 
 
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'
1955
 
 
1956
 
        self.mox.StubOutWithMock(os.path, "getsize")
1957
 
        os.path.getsize('/test/disk').AndReturn((10737418240))
1958
 
        os.path.getsize('/test/disk.local').AndReturn((21474836480))
1959
 
 
1960
 
        ret = ("image: /test/disk\n"
1961
 
               "file format: raw\n"
1962
 
               "virtual size: 20G (21474836480 bytes)\n"
1963
 
               "disk size: 3.1G\n"
1964
 
               "cluster_size: 2097152\n"
1965
 
               "backing file: /test/dummy (actual path: /backing/file)\n")
1966
 
 
1967
 
        self.mox.StubOutWithMock(utils, "execute")
1968
 
        utils.execute('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
1969
 
                      '/test/disk.local').AndReturn((ret, ''))
1970
 
 
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")
1983
 
 
1984
 
        db.instance_destroy(self.context, instance_ref['uuid'])
1985
 
 
1986
 
    def test_spawn_with_network_info(self):
1987
 
        # Preparing mocks
1988
 
        def fake_none(self, instance):
1989
 
            return
1990
 
 
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()
1996
 
 
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)
2000
 
 
2001
 
        # Start test
2002
 
        self.mox.ReplayAll()
2003
 
        conn = libvirt_driver.LibvirtDriver(False)
2004
 
        self.stubs.Set(conn.firewall_driver,
2005
 
                       'setup_basic_filtering',
2006
 
                       fake_none)
2007
 
        self.stubs.Set(conn.firewall_driver,
2008
 
                       'prepare_instance_filter',
2009
 
                       fake_none)
2010
 
 
2011
 
        try:
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'
2017
 
                                                 ', not int'))
2018
 
            self.assertNotIn('Unexpected method call', unicode(e))
2019
 
 
2020
 
        path = os.path.join(FLAGS.instances_path, instance.name)
2021
 
        if os.path.isdir(path):
2022
 
            shutil.rmtree(path)
2023
 
 
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))
2028
 
 
2029
 
    def test_get_console_output_file(self):
2030
 
 
2031
 
        with utils.tempdir() as tmpdir:
2032
 
            self.flags(instances_path=tmpdir)
2033
 
 
2034
 
            instance_ref = self.test_instance
2035
 
            instance_ref['image_ref'] = 123456
2036
 
            instance = db.instance_create(self.context, instance_ref)
2037
 
 
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")
2042
 
            f.write("foo")
2043
 
            f.close()
2044
 
            fake_dom_xml = """
2045
 
                <domain type='kvm'>
2046
 
                    <devices>
2047
 
                        <disk type='file'>
2048
 
                            <source file='filename'/>
2049
 
                        </disk>
2050
 
                        <console type='file'>
2051
 
                            <source path='%s'/>
2052
 
                            <target port='0'/>
2053
 
                        </console>
2054
 
                    </devices>
2055
 
                </domain>
2056
 
            """ % console_log
2057
 
 
2058
 
            def fake_lookup(id):
2059
 
                return FakeVirtDomain(fake_dom_xml)
2060
 
 
2061
 
            self.create_fake_libvirt_mock()
2062
 
            libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup
2063
 
            libvirt_driver.libvirt_utils = fake_libvirt_utils
2064
 
 
2065
 
            conn = libvirt_driver.LibvirtDriver(False)
2066
 
            output = conn.get_console_output(instance)
2067
 
            self.assertEquals("foo", output)
2068
 
 
2069
 
    def test_get_console_output_pty(self):
2070
 
 
2071
 
        with utils.tempdir() as tmpdir:
2072
 
            self.flags(instances_path=tmpdir)
2073
 
 
2074
 
            instance_ref = self.test_instance
2075
 
            instance_ref['image_ref'] = 123456
2076
 
            instance = db.instance_create(self.context, instance_ref)
2077
 
 
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")
2082
 
            f.write("foo")
2083
 
            f.close()
2084
 
            fake_dom_xml = """
2085
 
                <domain type='kvm'>
2086
 
                    <devices>
2087
 
                        <disk type='file'>
2088
 
                            <source file='filename'/>
2089
 
                        </disk>
2090
 
                        <console type='pty'>
2091
 
                            <source path='%s'/>
2092
 
                            <target port='0'/>
2093
 
                        </console>
2094
 
                    </devices>
2095
 
                </domain>
2096
 
            """ % pty_file
2097
 
 
2098
 
            def fake_lookup(id):
2099
 
                return FakeVirtDomain(fake_dom_xml)
2100
 
 
2101
 
            def _fake_flush(self, fake_pty):
2102
 
                with open(fake_pty, 'r') as fp:
2103
 
                    return fp.read()
2104
 
 
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
2109
 
 
2110
 
            conn = libvirt_driver.LibvirtDriver(False)
2111
 
            output = conn.get_console_output(instance)
2112
 
            self.assertEquals("foo", output)
2113
 
 
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)
2118
 
 
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)):
2123
 
 
2124
 
            conn = libvirt_driver.LibvirtDriver(False)
2125
 
 
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")
2130
 
 
2131
 
            conn._wrapped_conn.getCapabilities().AndRaise(
2132
 
                    libvirt.libvirtError("fake failure"))
2133
 
 
2134
 
            libvirt.libvirtError.get_error_code().AndReturn(error)
2135
 
            libvirt.libvirtError.get_error_domain().AndReturn(domain)
2136
 
 
2137
 
            self.mox.ReplayAll()
2138
 
 
2139
 
            self.assertFalse(conn._test_connection())
2140
 
 
2141
 
            self.mox.UnsetStubs()
2142
 
 
2143
 
    def test_volume_in_mapping(self):
2144
 
        conn = libvirt_driver.LibvirtDriver(False)
2145
 
        swap = {'device_name': '/dev/sdb',
2146
 
                'swap_size': 1}
2147
 
        ephemerals = [{'num': 0,
2148
 
                       'virtual_name': 'ephemeral0',
2149
 
                       'device_name': '/dev/sdc1',
2150
 
                       'size': 1},
2151
 
                      {'num': 2,
2152
 
                       'virtual_name': 'ephemeral2',
2153
 
                       'device_name': '/dev/sdd',
2154
 
                       'size': 1}]
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',
2161
 
                'swap': swap,
2162
 
                'ephemerals': ephemerals,
2163
 
                'block_device_mapping': block_device_mapping}
2164
 
 
2165
 
        def _assert_volume_in_mapping(device_name, true_or_false):
2166
 
            self.assertEquals(conn._volume_in_mapping(device_name,
2167
 
                                                      block_device_info),
2168
 
                              true_or_false)
2169
 
 
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)
2178
 
 
2179
 
    def test_immediate_delete(self):
2180
 
        def fake_lookup_by_name(instance_name):
2181
 
            raise exception.InstanceNotFound()
2182
 
 
2183
 
        conn = libvirt_driver.LibvirtDriver(False)
2184
 
        self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name)
2185
 
 
2186
 
        instance = db.instance_create(self.context, self.test_instance)
2187
 
        conn.destroy(instance, {})
2188
 
 
2189
 
    def test_destroy_undefines(self):
2190
 
        mock = self.mox.CreateMock(libvirt.virDomain)
2191
 
        mock.destroy()
2192
 
        mock.undefineFlags(1).AndReturn(1)
2193
 
 
2194
 
        self.mox.ReplayAll()
2195
 
 
2196
 
        def fake_lookup_by_name(instance_name):
2197
 
            return mock
2198
 
 
2199
 
        def fake_get_info(instance_name):
2200
 
            return {'state': power_state.SHUTDOWN}
2201
 
 
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, [])
2208
 
 
2209
 
    def test_destroy_undefines_no_undefine_flags(self):
2210
 
        mock = self.mox.CreateMock(libvirt.virDomain)
2211
 
        mock.destroy()
2212
 
        mock.undefineFlags(1).AndRaise(libvirt.libvirtError('Err'))
2213
 
        mock.undefine()
2214
 
 
2215
 
        self.mox.ReplayAll()
2216
 
 
2217
 
        def fake_lookup_by_name(instance_name):
2218
 
            return mock
2219
 
 
2220
 
        def fake_get_info(instance_name):
2221
 
            return {'state': power_state.SHUTDOWN}
2222
 
 
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, [])
2229
 
 
2230
 
    def test_destroy_undefines_no_attribute_with_managed_save(self):
2231
 
        mock = self.mox.CreateMock(libvirt.virDomain)
2232
 
        mock.destroy()
2233
 
        mock.undefineFlags(1).AndRaise(AttributeError())
2234
 
        mock.hasManagedSaveImage(0).AndReturn(True)
2235
 
        mock.managedSaveRemove(0)
2236
 
        mock.undefine()
2237
 
 
2238
 
        self.mox.ReplayAll()
2239
 
 
2240
 
        def fake_lookup_by_name(instance_name):
2241
 
            return mock
2242
 
 
2243
 
        def fake_get_info(instance_name):
2244
 
            return {'state': power_state.SHUTDOWN}
2245
 
 
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, [])
2252
 
 
2253
 
    def test_destroy_undefines_no_attribute_no_managed_save(self):
2254
 
        mock = self.mox.CreateMock(libvirt.virDomain)
2255
 
        mock.destroy()
2256
 
        mock.undefineFlags(1).AndRaise(AttributeError())
2257
 
        mock.hasManagedSaveImage(0).AndRaise(AttributeError())
2258
 
        mock.undefine()
2259
 
 
2260
 
        self.mox.ReplayAll()
2261
 
 
2262
 
        def fake_lookup_by_name(instance_name):
2263
 
            return mock
2264
 
 
2265
 
        def fake_get_info(instance_name):
2266
 
            return {'state': power_state.SHUTDOWN}
2267
 
 
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, [])
2274
 
 
2275
 
    def test_private_destroy_not_found(self):
2276
 
        mock = self.mox.CreateMock(libvirt.virDomain)
2277
 
        mock.destroy()
2278
 
        self.mox.ReplayAll()
2279
 
 
2280
 
        def fake_lookup_by_name(instance_name):
2281
 
            return mock
2282
 
 
2283
 
        def fake_get_info(instance_name):
2284
 
            raise exception.InstanceNotFound()
2285
 
 
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)
2293
 
 
2294
 
    def test_available_least_handles_missing(self):
2295
 
        """Ensure destroy calls managedSaveRemove for saved instance"""
2296
 
        conn = libvirt_driver.LibvirtDriver(False)
2297
 
 
2298
 
        def list_instances():
2299
 
            return ['fake']
2300
 
        self.stubs.Set(conn, 'list_instances', list_instances)
2301
 
 
2302
 
        def get_info(instance_name):
2303
 
            raise exception.InstanceNotFound()
2304
 
        self.stubs.Set(conn, 'get_instance_disk_info', get_info)
2305
 
 
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)
2309
 
 
2310
 
    def test_cpu_info(self):
2311
 
        conn = libvirt_driver.LibvirtDriver(True)
2312
 
 
2313
 
        def get_host_capabilities_stub(self):
2314
 
            cpu = config.LibvirtConfigCPU()
2315
 
            cpu.model = "Opteron_G4"
2316
 
            cpu.vendor = "AMD"
2317
 
            cpu.arch = "x86_64"
2318
 
 
2319
 
            cpu.cores = 2
2320
 
            cpu.threads = 1
2321
 
            cpu.sockets = 4
2322
 
 
2323
 
            cpu.add_feature(config.LibvirtConfigCPUFeature("extapic"))
2324
 
            cpu.add_feature(config.LibvirtConfigCPUFeature("3dnow"))
2325
 
 
2326
 
            caps = config.LibvirtConfigCaps()
2327
 
            caps.host = config.LibvirtConfigCapsHost()
2328
 
            caps.host.cpu = cpu
2329
 
 
2330
 
            guest = config.LibvirtConfigGuest()
2331
 
            guest.ostype = vm_mode.HVM
2332
 
            guest.arch = "x86_64"
2333
 
            guest.domtype = ["kvm"]
2334
 
            caps.guests.append(guest)
2335
 
 
2336
 
            guest = config.LibvirtConfigGuest()
2337
 
            guest.ostype = vm_mode.HVM
2338
 
            guest.arch = "i686"
2339
 
            guest.domtype = ["kvm"]
2340
 
            caps.guests.append(guest)
2341
 
 
2342
 
            return caps
2343
 
 
2344
 
        self.stubs.Set(libvirt_driver.LibvirtDriver,
2345
 
                       'get_host_capabilities',
2346
 
                       get_host_capabilities_stub)
2347
 
 
2348
 
        want = {"vendor": "AMD",
2349
 
                "features": ["extapic", "3dnow"],
2350
 
                "model": "Opteron_G4",
2351
 
                "arch": "x86_64",
2352
 
                "topology": {"cores": 2, "threads": 1, "sockets": 4}}
2353
 
        got = jsonutils.loads(conn.get_cpu_info())
2354
 
        self.assertEqual(want, got)
2355
 
 
2356
 
    def test_diagnostic_vcpus_exception(self):
2357
 
        xml = """
2358
 
                <domain type='kvm'>
2359
 
                    <devices>
2360
 
                        <disk type='file'>
2361
 
                            <source file='filename'/>
2362
 
                            <target dev='vda' bus='virtio'/>
2363
 
                        </disk>
2364
 
                        <disk type='block'>
2365
 
                            <source dev='/path/to/dev/1'/>
2366
 
                            <target dev='vdb' bus='virtio'/>
2367
 
                        </disk>
2368
 
                        <interface type='network'>
2369
 
                            <mac address='52:54:00:a4:38:38'/>
2370
 
                            <source network='default'/>
2371
 
                            <target dev='vnet0'/>
2372
 
                        </interface>
2373
 
                    </devices>
2374
 
                </domain>
2375
 
            """
2376
 
 
2377
 
        class DiagFakeDomain(FakeVirtDomain):
2378
 
 
2379
 
            def __init__(self):
2380
 
                super(DiagFakeDomain, self).__init__(fake_xml=xml)
2381
 
 
2382
 
            def vcpus(self):
2383
 
                raise libvirt.libvirtError('vcpus missing')
2384
 
 
2385
 
            def blockStats(self, path):
2386
 
                return (169L, 688640L, 0L, 0L, -1L)
2387
 
 
2388
 
            def interfaceStats(self, path):
2389
 
                return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
2390
 
 
2391
 
            def memoryStats(self):
2392
 
                return {'actual': 220160L, 'rss': 200164L}
2393
 
 
2394
 
            def maxMemory(self):
2395
 
                return 280160L
2396
 
 
2397
 
        def fake_lookup_name(name):
2398
 
            return DiagFakeDomain()
2399
 
 
2400
 
        self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2401
 
        libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2402
 
 
2403
 
        conn = libvirt_driver.LibvirtDriver(False)
2404
 
        actual = conn.get_diagnostics({"name": "testvirt"})
2405
 
        expect = {'vda_read': 688640L,
2406
 
                  'vda_read_req': 169L,
2407
 
                  'vda_write': 0L,
2408
 
                  'vda_write_req': 0L,
2409
 
                  'vda_errors': -1L,
2410
 
                  'vdb_read': 688640L,
2411
 
                  'vdb_read_req': 169L,
2412
 
                  'vdb_write': 0L,
2413
 
                  'vdb_write_req': 0L,
2414
 
                  'vdb_errors': -1L,
2415
 
                  'memory': 280160L,
2416
 
                  'memory-actual': 220160L,
2417
 
                  'memory-rss': 200164L,
2418
 
                  'vnet0_rx': 4408L,
2419
 
                  'vnet0_rx_drop': 0L,
2420
 
                  'vnet0_rx_errors': 0L,
2421
 
                  'vnet0_rx_packets': 82L,
2422
 
                  'vnet0_tx': 0L,
2423
 
                  'vnet0_tx_drop': 0L,
2424
 
                  'vnet0_tx_errors': 0L,
2425
 
                  'vnet0_tx_packets': 0L,
2426
 
                  }
2427
 
        self.assertEqual(actual, expect)
2428
 
 
2429
 
    def test_diagnostic_blockstats_exception(self):
2430
 
        xml = """
2431
 
                <domain type='kvm'>
2432
 
                    <devices>
2433
 
                        <disk type='file'>
2434
 
                            <source file='filename'/>
2435
 
                            <target dev='vda' bus='virtio'/>
2436
 
                        </disk>
2437
 
                        <disk type='block'>
2438
 
                            <source dev='/path/to/dev/1'/>
2439
 
                            <target dev='vdb' bus='virtio'/>
2440
 
                        </disk>
2441
 
                        <interface type='network'>
2442
 
                            <mac address='52:54:00:a4:38:38'/>
2443
 
                            <source network='default'/>
2444
 
                            <target dev='vnet0'/>
2445
 
                        </interface>
2446
 
                    </devices>
2447
 
                </domain>
2448
 
            """
2449
 
 
2450
 
        class DiagFakeDomain(FakeVirtDomain):
2451
 
 
2452
 
            def __init__(self):
2453
 
                super(DiagFakeDomain, self).__init__(fake_xml=xml)
2454
 
 
2455
 
            def vcpus(self):
2456
 
                return ([(0, 1, 15340000000L, 0),
2457
 
                         (1, 1, 1640000000L, 0),
2458
 
                         (2, 1, 3040000000L, 0),
2459
 
                         (3, 1, 1420000000L, 0)],
2460
 
                        [(True, False),
2461
 
                         (True, False),
2462
 
                         (True, False),
2463
 
                         (True, False)])
2464
 
 
2465
 
            def blockStats(self, path):
2466
 
                raise libvirt.libvirtError('blockStats missing')
2467
 
 
2468
 
            def interfaceStats(self, path):
2469
 
                return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
2470
 
 
2471
 
            def memoryStats(self):
2472
 
                return {'actual': 220160L, 'rss': 200164L}
2473
 
 
2474
 
            def maxMemory(self):
2475
 
                return 280160L
2476
 
 
2477
 
        def fake_lookup_name(name):
2478
 
            return DiagFakeDomain()
2479
 
 
2480
 
        self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2481
 
        libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2482
 
 
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,
2489
 
                  'memory': 280160L,
2490
 
                  'memory-actual': 220160L,
2491
 
                  'memory-rss': 200164L,
2492
 
                  'vnet0_rx': 4408L,
2493
 
                  'vnet0_rx_drop': 0L,
2494
 
                  'vnet0_rx_errors': 0L,
2495
 
                  'vnet0_rx_packets': 82L,
2496
 
                  'vnet0_tx': 0L,
2497
 
                  'vnet0_tx_drop': 0L,
2498
 
                  'vnet0_tx_errors': 0L,
2499
 
                  'vnet0_tx_packets': 0L,
2500
 
                  }
2501
 
        self.assertEqual(actual, expect)
2502
 
 
2503
 
    def test_diagnostic_interfacestats_exception(self):
2504
 
        xml = """
2505
 
                <domain type='kvm'>
2506
 
                    <devices>
2507
 
                        <disk type='file'>
2508
 
                            <source file='filename'/>
2509
 
                            <target dev='vda' bus='virtio'/>
2510
 
                        </disk>
2511
 
                        <disk type='block'>
2512
 
                            <source dev='/path/to/dev/1'/>
2513
 
                            <target dev='vdb' bus='virtio'/>
2514
 
                        </disk>
2515
 
                        <interface type='network'>
2516
 
                            <mac address='52:54:00:a4:38:38'/>
2517
 
                            <source network='default'/>
2518
 
                            <target dev='vnet0'/>
2519
 
                        </interface>
2520
 
                    </devices>
2521
 
                </domain>
2522
 
            """
2523
 
 
2524
 
        class DiagFakeDomain(FakeVirtDomain):
2525
 
 
2526
 
            def __init__(self):
2527
 
                super(DiagFakeDomain, self).__init__(fake_xml=xml)
2528
 
 
2529
 
            def vcpus(self):
2530
 
                return ([(0, 1, 15340000000L, 0),
2531
 
                         (1, 1, 1640000000L, 0),
2532
 
                         (2, 1, 3040000000L, 0),
2533
 
                         (3, 1, 1420000000L, 0)],
2534
 
                        [(True, False),
2535
 
                         (True, False),
2536
 
                         (True, False),
2537
 
                         (True, False)])
2538
 
 
2539
 
            def blockStats(self, path):
2540
 
                return (169L, 688640L, 0L, 0L, -1L)
2541
 
 
2542
 
            def interfaceStats(self, path):
2543
 
                raise libvirt.libvirtError('interfaceStat missing')
2544
 
 
2545
 
            def memoryStats(self):
2546
 
                return {'actual': 220160L, 'rss': 200164L}
2547
 
 
2548
 
            def maxMemory(self):
2549
 
                return 280160L
2550
 
 
2551
 
        def fake_lookup_name(name):
2552
 
            return DiagFakeDomain()
2553
 
 
2554
 
        self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2555
 
        libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2556
 
 
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,
2565
 
                  'vda_write': 0L,
2566
 
                  'vda_write_req': 0L,
2567
 
                  'vda_errors': -1L,
2568
 
                  'vdb_read': 688640L,
2569
 
                  'vdb_read_req': 169L,
2570
 
                  'vdb_write': 0L,
2571
 
                  'vdb_write_req': 0L,
2572
 
                  'vdb_errors': -1L,
2573
 
                  'memory': 280160L,
2574
 
                  'memory-actual': 220160L,
2575
 
                  'memory-rss': 200164L,
2576
 
                  }
2577
 
        self.assertEqual(actual, expect)
2578
 
 
2579
 
    def test_diagnostic_memorystats_exception(self):
2580
 
        xml = """
2581
 
                <domain type='kvm'>
2582
 
                    <devices>
2583
 
                        <disk type='file'>
2584
 
                            <source file='filename'/>
2585
 
                            <target dev='vda' bus='virtio'/>
2586
 
                        </disk>
2587
 
                        <disk type='block'>
2588
 
                            <source dev='/path/to/dev/1'/>
2589
 
                            <target dev='vdb' bus='virtio'/>
2590
 
                        </disk>
2591
 
                        <interface type='network'>
2592
 
                            <mac address='52:54:00:a4:38:38'/>
2593
 
                            <source network='default'/>
2594
 
                            <target dev='vnet0'/>
2595
 
                        </interface>
2596
 
                    </devices>
2597
 
                </domain>
2598
 
            """
2599
 
 
2600
 
        class DiagFakeDomain(FakeVirtDomain):
2601
 
 
2602
 
            def __init__(self):
2603
 
                super(DiagFakeDomain, self).__init__(fake_xml=xml)
2604
 
 
2605
 
            def vcpus(self):
2606
 
                return ([(0, 1, 15340000000L, 0),
2607
 
                         (1, 1, 1640000000L, 0),
2608
 
                         (2, 1, 3040000000L, 0),
2609
 
                         (3, 1, 1420000000L, 0)],
2610
 
                        [(True, False),
2611
 
                         (True, False),
2612
 
                         (True, False),
2613
 
                         (True, False)])
2614
 
 
2615
 
            def blockStats(self, path):
2616
 
                return (169L, 688640L, 0L, 0L, -1L)
2617
 
 
2618
 
            def interfaceStats(self, path):
2619
 
                return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
2620
 
 
2621
 
            def memoryStats(self):
2622
 
                raise libvirt.libvirtError('memoryStats missing')
2623
 
 
2624
 
            def maxMemory(self):
2625
 
                return 280160L
2626
 
 
2627
 
        def fake_lookup_name(name):
2628
 
            return DiagFakeDomain()
2629
 
 
2630
 
        self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2631
 
        libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2632
 
 
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,
2641
 
                  'vda_write': 0L,
2642
 
                  'vda_write_req': 0L,
2643
 
                  'vda_errors': -1L,
2644
 
                  'vdb_read': 688640L,
2645
 
                  'vdb_read_req': 169L,
2646
 
                  'vdb_write': 0L,
2647
 
                  'vdb_write_req': 0L,
2648
 
                  'vdb_errors': -1L,
2649
 
                  'memory': 280160L,
2650
 
                  'vnet0_rx': 4408L,
2651
 
                  'vnet0_rx_drop': 0L,
2652
 
                  'vnet0_rx_errors': 0L,
2653
 
                  'vnet0_rx_packets': 82L,
2654
 
                  'vnet0_tx': 0L,
2655
 
                  'vnet0_tx_drop': 0L,
2656
 
                  'vnet0_tx_errors': 0L,
2657
 
                  'vnet0_tx_packets': 0L,
2658
 
                  }
2659
 
        self.assertEqual(actual, expect)
2660
 
 
2661
 
    def test_diagnostic_full(self):
2662
 
        xml = """
2663
 
                <domain type='kvm'>
2664
 
                    <devices>
2665
 
                        <disk type='file'>
2666
 
                            <source file='filename'/>
2667
 
                            <target dev='vda' bus='virtio'/>
2668
 
                        </disk>
2669
 
                        <disk type='block'>
2670
 
                            <source dev='/path/to/dev/1'/>
2671
 
                            <target dev='vdb' bus='virtio'/>
2672
 
                        </disk>
2673
 
                        <interface type='network'>
2674
 
                            <mac address='52:54:00:a4:38:38'/>
2675
 
                            <source network='default'/>
2676
 
                            <target dev='vnet0'/>
2677
 
                        </interface>
2678
 
                    </devices>
2679
 
                </domain>
2680
 
            """
2681
 
 
2682
 
        class DiagFakeDomain(FakeVirtDomain):
2683
 
 
2684
 
            def __init__(self):
2685
 
                super(DiagFakeDomain, self).__init__(fake_xml=xml)
2686
 
 
2687
 
            def vcpus(self):
2688
 
                return ([(0, 1, 15340000000L, 0),
2689
 
                         (1, 1, 1640000000L, 0),
2690
 
                         (2, 1, 3040000000L, 0),
2691
 
                         (3, 1, 1420000000L, 0)],
2692
 
                        [(True, False),
2693
 
                         (True, False),
2694
 
                         (True, False),
2695
 
                         (True, False)])
2696
 
 
2697
 
            def blockStats(self, path):
2698
 
                return (169L, 688640L, 0L, 0L, -1L)
2699
 
 
2700
 
            def interfaceStats(self, path):
2701
 
                return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
2702
 
 
2703
 
            def memoryStats(self):
2704
 
                return {'actual': 220160L, 'rss': 200164L}
2705
 
 
2706
 
            def maxMemory(self):
2707
 
                return 280160L
2708
 
 
2709
 
        def fake_lookup_name(name):
2710
 
            return DiagFakeDomain()
2711
 
 
2712
 
        self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
2713
 
        libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
2714
 
 
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,
2723
 
                  'vda_write': 0L,
2724
 
                  'vda_write_req': 0L,
2725
 
                  'vda_errors': -1L,
2726
 
                  'vdb_read': 688640L,
2727
 
                  'vdb_read_req': 169L,
2728
 
                  'vdb_write': 0L,
2729
 
                  'vdb_write_req': 0L,
2730
 
                  'vdb_errors': -1L,
2731
 
                  'memory': 280160L,
2732
 
                  'memory-actual': 220160L,
2733
 
                  'memory-rss': 200164L,
2734
 
                  'vnet0_rx': 4408L,
2735
 
                  'vnet0_rx_drop': 0L,
2736
 
                  'vnet0_rx_errors': 0L,
2737
 
                  'vnet0_rx_packets': 82L,
2738
 
                  'vnet0_tx': 0L,
2739
 
                  'vnet0_tx_drop': 0L,
2740
 
                  'vnet0_tx_errors': 0L,
2741
 
                  'vnet0_tx_packets': 0L,
2742
 
                  }
2743
 
        self.assertEqual(actual, expect)
2744
 
 
2745
 
    def test_get_instance_capabilities(self):
2746
 
        conn = libvirt_driver.LibvirtDriver(True)
2747
 
 
2748
 
        def get_host_capabilities_stub(self):
2749
 
            caps = config.LibvirtConfigCaps()
2750
 
 
2751
 
            guest = config.LibvirtConfigGuest()
2752
 
            guest.ostype = 'hvm'
2753
 
            guest.arch = 'x86_64'
2754
 
            guest.domtype = ['kvm', 'qemu']
2755
 
            caps.guests.append(guest)
2756
 
 
2757
 
            guest = config.LibvirtConfigGuest()
2758
 
            guest.ostype = 'hvm'
2759
 
            guest.arch = 'i686'
2760
 
            guest.domtype = ['kvm']
2761
 
            caps.guests.append(guest)
2762
 
 
2763
 
            return caps
2764
 
 
2765
 
        self.stubs.Set(libvirt_driver.LibvirtDriver,
2766
 
                       'get_host_capabilities',
2767
 
                       get_host_capabilities_stub)
2768
 
 
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)
2774
 
 
2775
 
 
2776
 
class HostStateTestCase(test.TestCase):
2777
 
 
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")]
2784
 
 
2785
 
    class FakeConnection(object):
2786
 
        """Fake connection object"""
2787
 
 
2788
 
        def get_vcpu_total(self):
2789
 
            return 1
2790
 
 
2791
 
        def get_vcpu_used(self):
2792
 
            return 0
2793
 
 
2794
 
        def get_cpu_info(self):
2795
 
            return HostStateTestCase.cpu_info
2796
 
 
2797
 
        def get_local_gb_total(self):
2798
 
            return 100
2799
 
 
2800
 
        def get_local_gb_used(self):
2801
 
            return 20
2802
 
 
2803
 
        def get_memory_mb_total(self):
2804
 
            return 497
2805
 
 
2806
 
        def get_memory_mb_used(self):
2807
 
            return 88
2808
 
 
2809
 
        def get_hypervisor_type(self):
2810
 
            return 'QEMU'
2811
 
 
2812
 
        def get_hypervisor_version(self):
2813
 
            return 13091
2814
 
 
2815
 
        def get_hypervisor_hostname(self):
2816
 
            return 'compute1'
2817
 
 
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')
2821
 
 
2822
 
        def get_disk_available_least(self):
2823
 
            return 13091
2824
 
 
2825
 
        def get_instance_capabilities(self):
2826
 
            return HostStateTestCase.instance_caps
2827
 
 
2828
 
    def test_update_status(self):
2829
 
        self.mox.StubOutWithMock(libvirt_driver, 'LibvirtDriver')
2830
 
        libvirt_driver.LibvirtDriver(True).AndReturn(self.FakeConnection())
2831
 
 
2832
 
        self.mox.ReplayAll()
2833
 
        hs = libvirt_driver.HostState(True)
2834
 
        stats = hs._stats
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"}
2843
 
                })
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')
2852
 
 
2853
 
 
2854
 
class NWFilterFakes:
2855
 
    def __init__(self):
2856
 
        self.filters = {}
2857
 
 
2858
 
    def nwfilterLookupByName(self, name):
2859
 
        if name in self.filters:
2860
 
            return self.filters[name]
2861
 
        raise libvirt.libvirtError('Filter Not Found')
2862
 
 
2863
 
    def filterDefineXMLMock(self, xml):
2864
 
        class FakeNWFilterInternal:
2865
 
            def __init__(self, parent, name):
2866
 
                self.name = name
2867
 
                self.parent = parent
2868
 
 
2869
 
            def undefine(self):
2870
 
                del self.parent.filters[self.name]
2871
 
                pass
2872
 
        tree = etree.fromstring(xml)
2873
 
        name = tree.get('name')
2874
 
        if name not in self.filters:
2875
 
            self.filters[name] = FakeNWFilterInternal(self, name)
2876
 
        return True
2877
 
 
2878
 
 
2879
 
class IptablesFirewallTestCase(test.TestCase):
2880
 
    def setUp(self):
2881
 
        super(IptablesFirewallTestCase, self).setUp()
2882
 
 
2883
 
        self.user_id = 'fake'
2884
 
        self.project_id = 'fake'
2885
 
        self.context = context.RequestContext(self.user_id, self.project_id)
2886
 
 
2887
 
        class FakeLibvirtDriver(object):
2888
 
            def nwfilterDefineXML(*args, **kwargs):
2889
 
                """setup_basic_rules in nwfilter calls this."""
2890
 
                pass
2891
 
        self.fake_libvirt_connection = FakeLibvirtDriver()
2892
 
        self.fw = firewall.IptablesFirewallDriver(
2893
 
                      get_connection=lambda: self.fake_libvirt_connection)
2894
 
 
2895
 
    in_nat_rules = [
2896
 
      '# Generated by iptables-save v1.4.10 on Sat Feb 19 00:03:19 2011',
2897
 
      '*nat',
2898
 
      ':PREROUTING ACCEPT [1170:189210]',
2899
 
      ':INPUT ACCEPT [844:71028]',
2900
 
      ':OUTPUT ACCEPT [5149:405186]',
2901
 
      ':POSTROUTING ACCEPT [5063:386098]',
2902
 
    ]
2903
 
 
2904
 
    in_filter_rules = [
2905
 
      '# Generated by iptables-save v1.4.4 on Mon Dec  6 11:54:13 2010',
2906
 
      '*filter',
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 ',
2920
 
      'COMMIT',
2921
 
      '# Completed on Mon Dec  6 11:54:13 2010',
2922
 
    ]
2923
 
 
2924
 
    in6_filter_rules = [
2925
 
      '# Generated by ip6tables-save v1.4.4 on Tue Jan 18 23:47:56 2011',
2926
 
      '*filter',
2927
 
      ':INPUT ACCEPT [349155:75810423]',
2928
 
      ':FORWARD ACCEPT [0:0]',
2929
 
      ':OUTPUT ACCEPT [349256:75777230]',
2930
 
      'COMMIT',
2931
 
      '# Completed on Tue Jan 18 23:47:56 2011',
2932
 
    ]
2933
 
 
2934
 
    def _create_instance_ref(self):
2935
 
        return db.instance_create(self.context,
2936
 
                                  {'user_id': 'fake',
2937
 
                                   'project_id': 'fake',
2938
 
                                   'instance_type_id': 1})
2939
 
 
2940
 
    def test_static_filters(self):
2941
 
        instance_ref = self._create_instance_ref()
2942
 
        src_instance_ref = self._create_instance_ref()
2943
 
 
2944
 
        admin_ctxt = context.get_admin_context()
2945
 
        secgroup = db.security_group_create(admin_ctxt,
2946
 
                                            {'user_id': 'fake',
2947
 
                                             'project_id': 'fake',
2948
 
                                             'name': 'testgroup',
2949
 
                                             'description': 'test group'})
2950
 
 
2951
 
        src_secgroup = db.security_group_create(admin_ctxt,
2952
 
                                                {'user_id': 'fake',
2953
 
                                                 'project_id': 'fake',
2954
 
                                                 'name': 'testsourcegroup',
2955
 
                                                 'description': 'src group'})
2956
 
 
2957
 
        db.security_group_rule_create(admin_ctxt,
2958
 
                                      {'parent_group_id': secgroup['id'],
2959
 
                                       'protocol': 'icmp',
2960
 
                                       'from_port': -1,
2961
 
                                       'to_port': -1,
2962
 
                                       'cidr': '192.168.11.0/24'})
2963
 
 
2964
 
        db.security_group_rule_create(admin_ctxt,
2965
 
                                      {'parent_group_id': secgroup['id'],
2966
 
                                       'protocol': 'icmp',
2967
 
                                       'from_port': 8,
2968
 
                                       'to_port': -1,
2969
 
                                       'cidr': '192.168.11.0/24'})
2970
 
 
2971
 
        db.security_group_rule_create(admin_ctxt,
2972
 
                                      {'parent_group_id': secgroup['id'],
2973
 
                                       'protocol': 'tcp',
2974
 
                                       'from_port': 80,
2975
 
                                       'to_port': 81,
2976
 
                                       'cidr': '192.168.10.0/24'})
2977
 
 
2978
 
        db.security_group_rule_create(admin_ctxt,
2979
 
                                      {'parent_group_id': secgroup['id'],
2980
 
                                       'protocol': 'tcp',
2981
 
                                       'from_port': 80,
2982
 
                                       'to_port': 81,
2983
 
                                       'group_id': src_secgroup['id']})
2984
 
 
2985
 
        db.security_group_rule_create(admin_ctxt,
2986
 
                                      {'parent_group_id': secgroup['id'],
2987
 
                                       'group_id': src_secgroup['id']})
2988
 
 
2989
 
        db.instance_add_security_group(admin_ctxt, instance_ref['uuid'],
2990
 
                                       secgroup['id'])
2991
 
        db.instance_add_security_group(admin_ctxt, src_instance_ref['uuid'],
2992
 
                                       src_secgroup['id'])
2993
 
        instance_ref = db.instance_get(admin_ctxt, instance_ref['id'])
2994
 
        src_instance_ref = db.instance_get(admin_ctxt, src_instance_ref['id'])
2995
 
 
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
3009
 
                return '', ''
3010
 
            if cmd == ('ip6tables-restore', '-c',):
3011
 
                lines = process_input.split('\n')
3012
 
                if '*filter' in lines:
3013
 
                    self.out6_rules = lines
3014
 
                return '', ''
3015
 
            print cmd, kwargs
3016
 
 
3017
 
        network_model = _fake_network_info(self.stubs, 1, spectacular=True)
3018
 
 
3019
 
        from nova.network import linux_net
3020
 
        linux_net.iptables_manager.execute = fake_iptables_execute
3021
 
 
3022
 
        _fake_stub_out_get_nw_info(self.stubs, lambda *a, **kw: network_model)
3023
 
 
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)
3027
 
 
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)
3034
 
 
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]
3041
 
                break
3042
 
        self.assertTrue(instance_chain, "The instance chain wasn't added")
3043
 
 
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]
3049
 
                break
3050
 
        self.assertTrue(security_group_chain,
3051
 
                        "The security group chain wasn't added")
3052
 
 
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")
3057
 
 
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")
3062
 
 
3063
 
        for ip in network_model.fixed_ips():
3064
 
            if ip['version'] != 4:
3065
 
                continue
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")
3074
 
 
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'])
3080
 
 
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)
3087
 
 
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)
3094
 
 
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
3100
 
        networks_count = 5
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,
3107
 
                                                      network_info)
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)
3117
 
 
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")
3127
 
 
3128
 
    def test_unfilter_instance_undefines_nwfilter(self):
3129
 
        admin_ctxt = context.get_admin_context()
3130
 
 
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()
3137
 
 
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)
3144
 
 
3145
 
        # should undefine just the instance filter
3146
 
        self.assertEqual(original_filter_count - len(fakefilter.filters), 1)
3147
 
 
3148
 
        db.instance_destroy(admin_ctxt, instance_ref['uuid'])
3149
 
 
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']
3155
 
 
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))
3164
 
 
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,
3168
 
                                                  {'protocol': 'tcp',
3169
 
                                                   'cidr': '10.99.99.99/32',
3170
 
                                                   'from_port': 1,
3171
 
                                                   'to_port': 65535})
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))
3176
 
 
3177
 
        # Add another, refresh, and make sure number of rules goes to two
3178
 
        provider_fw1 = db.provider_fw_rule_create(admin_ctxt,
3179
 
                                                  {'protocol': 'udp',
3180
 
                                                   'cidr': '10.99.99.99/32',
3181
 
                                                   'from_port': 1,
3182
 
                                                   'to_port': 65535})
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))
3187
 
 
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]
3194
 
        provjump_rules = []
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))
3200
 
 
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))
3207
 
 
3208
 
 
3209
 
class NWFilterTestCase(test.TestCase):
3210
 
    def setUp(self):
3211
 
        super(NWFilterTestCase, self).setUp()
3212
 
 
3213
 
        class Mock(object):
3214
 
            pass
3215
 
 
3216
 
        self.user_id = 'fake'
3217
 
        self.project_id = 'fake'
3218
 
        self.context = context.RequestContext(self.user_id, self.project_id)
3219
 
 
3220
 
        self.fake_libvirt_connection = Mock()
3221
 
 
3222
 
        self.fw = firewall.NWFilterFirewall(
3223
 
                                         lambda: self.fake_libvirt_connection)
3224
 
 
3225
 
    def test_cidr_rule_nwfilter_xml(self):
3226
 
        cloud_controller = cloud.CloudController()
3227
 
        cloud_controller.create_security_group(self.context,
3228
 
                                               'testgroup',
3229
 
                                               'test group description')
3230
 
        cloud_controller.authorize_security_group_ingress(self.context,
3231
 
                                                          'testgroup',
3232
 
                                                          from_port='80',
3233
 
                                                          to_port='81',
3234
 
                                                          ip_protocol='tcp',
3235
 
                                                          cidr_ip='0.0.0.0/0')
3236
 
 
3237
 
        security_group = db.security_group_get_by_name(self.context,
3238
 
                                                       'fake',
3239
 
                                                       'testgroup')
3240
 
        self.teardown_security_group()
3241
 
 
3242
 
    def teardown_security_group(self):
3243
 
        cloud_controller = cloud.CloudController()
3244
 
        cloud_controller.delete_security_group(self.context, 'testgroup')
3245
 
 
3246
 
    def setup_and_return_security_group(self):
3247
 
        cloud_controller = cloud.CloudController()
3248
 
        cloud_controller.create_security_group(self.context,
3249
 
                                               'testgroup',
3250
 
                                               'test group description')
3251
 
        cloud_controller.authorize_security_group_ingress(self.context,
3252
 
                                                          'testgroup',
3253
 
                                                          from_port='80',
3254
 
                                                          to_port='81',
3255
 
                                                          ip_protocol='tcp',
3256
 
                                                          cidr_ip='0.0.0.0/0')
3257
 
 
3258
 
        return db.security_group_get_by_name(self.context, 'fake', 'testgroup')
3259
 
 
3260
 
    def _create_instance(self):
3261
 
        return db.instance_create(self.context,
3262
 
                                  {'user_id': 'fake',
3263
 
                                   'project_id': 'fake',
3264
 
                                   'instance_type_id': 1})
3265
 
 
3266
 
    def _create_instance_type(self, params=None):
3267
 
        """Create a test instance"""
3268
 
        if not params:
3269
 
            params = {}
3270
 
 
3271
 
        context = self.context.elevated()
3272
 
        inst = {}
3273
 
        inst['name'] = 'm1.small'
3274
 
        inst['memory_mb'] = '1024'
3275
 
        inst['vcpus'] = '1'
3276
 
        inst['root_gb'] = '10'
3277
 
        inst['ephemeral_gb'] = '20'
3278
 
        inst['flavorid'] = '1'
3279
 
        inst['swap'] = '2048'
3280
 
        inst['rxtx_factor'] = 1
3281
 
        inst.update(params)
3282
 
        return db.instance_type_create(context, inst)['id']
3283
 
 
3284
 
    def test_creates_base_rule_first(self):
3285
 
        # These come pre-defined by libvirt
3286
 
        self.defined_filters = ['no-mac-spoofing',
3287
 
                                'no-ip-spoofing',
3288
 
                                'no-arp-spoofing',
3289
 
                                'allow-dhcp-server']
3290
 
 
3291
 
        self.recursive_depends = {}
3292
 
        for f in self.defined_filters:
3293
 
            self.recursive_depends[f] = []
3294
 
 
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
3306
 
 
3307
 
            self.defined_filters.append(name)
3308
 
            return True
3309
 
 
3310
 
        self.fake_libvirt_connection.nwfilterDefineXML = _filterDefineXMLMock
3311
 
 
3312
 
        instance_ref = self._create_instance()
3313
 
        inst_id = instance_ref['id']
3314
 
        inst_uuid = instance_ref['uuid']
3315
 
 
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',
3320
 
                             'no-mac-spoofing']
3321
 
            if allow_dhcp:
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" %
3327
 
                                required)
3328
 
 
3329
 
        self.security_group = self.setup_and_return_security_group()
3330
 
 
3331
 
        db.instance_add_security_group(self.context, inst_uuid,
3332
 
                                       self.security_group.id)
3333
 
        instance = db.instance_get(self.context, inst_id)
3334
 
 
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']
3340
 
 
3341
 
        self.fw.setup_basic_filtering(instance, network_info)
3342
 
        allow_dhcp = False
3343
 
        for (network, mapping) in network_info:
3344
 
            if mapping['dhcp_server']:
3345
 
                allow_dhcp = True
3346
 
                break
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'])
3352
 
 
3353
 
    def test_unfilter_instance_undefines_nwfilters(self):
3354
 
        admin_ctxt = context.get_admin_context()
3355
 
 
3356
 
        fakefilter = NWFilterFakes()
3357
 
        self.fw._conn.nwfilterDefineXML = fakefilter.filterDefineXMLMock
3358
 
        self.fw._conn.nwfilterLookupByName = fakefilter.nwfilterLookupByName
3359
 
 
3360
 
        instance_ref = self._create_instance()
3361
 
        inst_id = instance_ref['id']
3362
 
        inst_uuid = instance_ref['uuid']
3363
 
 
3364
 
        self.security_group = self.setup_and_return_security_group()
3365
 
 
3366
 
        db.instance_add_security_group(self.context, inst_uuid,
3367
 
                                       self.security_group.id)
3368
 
 
3369
 
        instance = db.instance_get(self.context, inst_id)
3370
 
 
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)
3376
 
 
3377
 
        db.instance_destroy(admin_ctxt, instance_ref['uuid'])
3378
 
 
3379
 
 
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)
3387
 
        # Start test
3388
 
        self.mox.ReplayAll()
3389
 
        result = libvirt_utils.get_iscsi_initiator()
3390
 
        self.assertEqual(initiator, result)
3391
 
 
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')
3398
 
        # Start test
3399
 
        self.mox.ReplayAll()
3400
 
        libvirt_utils.create_image('raw', '/some/path', '10G')
3401
 
        libvirt_utils.create_image('qcow2', '/some/stuff', '1234567891234')
3402
 
 
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',
3407
 
                      '/the/new/cow')
3408
 
        # Start test
3409
 
        self.mox.ReplayAll()
3410
 
        libvirt_utils.create_cow_image('/some/path', '/the/new/cow')
3411
 
 
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])}
3418
 
 
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)
3424
 
 
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
3429
 
file format: raw
3430
 
virtual size: 4.4M (4592640 bytes)
3431
 
disk size: 4.4M''', ''))
3432
 
 
3433
 
        # Start test
3434
 
        self.mox.ReplayAll()
3435
 
        self.assertEquals(disk.get_disk_size('/some/path'), 4592640)
3436
 
 
3437
 
    def test_copy_image(self):
3438
 
        dst_fd, dst_path = tempfile.mkstemp()
3439
 
        try:
3440
 
            os.close(dst_fd)
3441
 
 
3442
 
            src_fd, src_path = tempfile.mkstemp()
3443
 
            try:
3444
 
                with os.fdopen(src_fd, 'w') as fp:
3445
 
                    fp.write('canary')
3446
 
 
3447
 
                libvirt_utils.copy_image(src_path, dst_path)
3448
 
                with open(dst_path, 'r') as fp:
3449
 
                    self.assertEquals(fp.read(), 'canary')
3450
 
            finally:
3451
 
                os.unlink(src_path)
3452
 
        finally:
3453
 
            os.unlink(dst_path)
3454
 
 
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()
3460
 
 
3461
 
        libvirt_utils.mkfs('ext4', '/my/block/dev')
3462
 
        libvirt_utils.mkfs('swap', '/my/swap/block/dev')
3463
 
 
3464
 
    def test_write_to_file(self):
3465
 
        dst_fd, dst_path = tempfile.mkstemp()
3466
 
        try:
3467
 
            os.close(dst_fd)
3468
 
 
3469
 
            libvirt_utils.write_to_file(dst_path, 'hello')
3470
 
            with open(dst_path, 'r') as fp:
3471
 
                self.assertEquals(fp.read(), 'hello')
3472
 
        finally:
3473
 
            os.unlink(dst_path)
3474
 
 
3475
 
    def test_write_to_file_with_umask(self):
3476
 
        dst_fd, dst_path = tempfile.mkstemp()
3477
 
        try:
3478
 
            os.close(dst_fd)
3479
 
            os.unlink(dst_path)
3480
 
 
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)
3486
 
        finally:
3487
 
            os.unlink(dst_path)
3488
 
 
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')
3494
 
 
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')
3499
 
 
3500
 
        # Start test
3501
 
        self.mox.ReplayAll()
3502
 
        libvirt_utils.extract_snapshot('/path/to/disk/image', 'qcow2',
3503
 
                                       'snap1', '/extracted/snap', dest_format)
3504
 
 
3505
 
    def test_extract_snapshot_raw(self):
3506
 
        self._do_test_extract_snapshot()
3507
 
 
3508
 
    def test_extract_snapshot_iso(self):
3509
 
        self._do_test_extract_snapshot(dest_format='iso')
3510
 
 
3511
 
    def test_extract_snapshot_qcow2(self):
3512
 
        self._do_test_extract_snapshot(dest_format='qcow2', out_format='qcow2')
3513
 
 
3514
 
    def test_load_file(self):
3515
 
        dst_fd, dst_path = tempfile.mkstemp()
3516
 
        try:
3517
 
            os.close(dst_fd)
3518
 
 
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')
3522
 
        finally:
3523
 
            os.unlink(dst_path)
3524
 
 
3525
 
    def test_file_open(self):
3526
 
        dst_fd, dst_path = tempfile.mkstemp()
3527
 
        try:
3528
 
            os.close(dst_fd)
3529
 
 
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')
3534
 
        finally:
3535
 
            os.unlink(dst_path)
3536
 
 
3537
 
    def test_get_fs_info(self):
3538
 
 
3539
 
        class FakeStatResult(object):
3540
 
 
3541
 
            def __init__(self):
3542
 
                self.f_bsize = 4096
3543
 
                self.f_frsize = 4096
3544
 
                self.f_blocks = 2000
3545
 
                self.f_bfree = 1000
3546
 
                self.f_bavail = 900
3547
 
                self.f_files = 2000
3548
 
                self.f_ffree = 1000
3549
 
                self.f_favail = 900
3550
 
                self.f_flag = 4096
3551
 
                self.f_namemax = 255
3552
 
 
3553
 
        self.path = None
3554
 
 
3555
 
        def fake_statvfs(path):
3556
 
            self.path = path
3557
 
            return FakeStatResult()
3558
 
 
3559
 
        self.stubs.Set(os, 'statvfs', fake_statvfs)
3560
 
 
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'])
3566
 
 
3567
 
    def test_fetch_image(self):
3568
 
        self.mox.StubOutWithMock(images, 'fetch_to_raw')
3569
 
 
3570
 
        context = 'opaque context'
3571
 
        target = '/tmp/targetfile'
3572
 
        image_id = '4'
3573
 
        user_id = 'fake'
3574
 
        project_id = 'fake'
3575
 
        images.fetch_to_raw(context, image_id, target, user_id, project_id)
3576
 
 
3577
 
        self.mox.ReplayAll()
3578
 
        libvirt_utils.fetch_image(context, target, image_id,
3579
 
                                  user_id, project_id)
3580
 
 
3581
 
    def test_get_disk_backing_file(self):
3582
 
        with_actual_path = False
3583
 
 
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"
3588
 
                        "...: ...\n"), ''
3589
 
            else:
3590
 
                return ("some: output\n"
3591
 
                        "backing file: /foo/bar/baz\n"
3592
 
                        "...: ...\n"), ''
3593
 
 
3594
 
        self.stubs.Set(utils, 'execute', fake_execute)
3595
 
 
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')
3601
 
 
3602
 
 
3603
 
class LibvirtDriverTestCase(test.TestCase):
3604
 
    """Test for nova.virt.libvirt.libvirt_driver.LibvirtDriver."""
3605
 
    def setUp(self):
3606
 
        super(LibvirtDriverTestCase, self).setUp()
3607
 
        self.libvirtconnection = libvirt_driver.LibvirtDriver(read_only=True)
3608
 
 
3609
 
    def _create_instance(self, params=None):
3610
 
        """Create a test instance"""
3611
 
        if not params:
3612
 
            params = {}
3613
 
 
3614
 
        inst = {}
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'
3631
 
 
3632
 
        inst.update(params)
3633
 
        return db.instance_create(context.get_admin_context(), inst)
3634
 
 
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. """
3638
 
 
3639
 
        self.counter = 0
3640
 
 
3641
 
        def fake_get_instance_disk_info(instance):
3642
 
            return '[]'
3643
 
 
3644
 
        def fake_destroy(instance):
3645
 
            pass
3646
 
 
3647
 
        def fake_get_host_ip_addr():
3648
 
            return '10.0.0.1'
3649
 
 
3650
 
        def fake_execute(*args, **kwargs):
3651
 
            self.counter += 1
3652
 
            if self.counter == 1:
3653
 
                assert False, "intentional failure"
3654
 
 
3655
 
        def fake_os_path_exists(path):
3656
 
            return True
3657
 
 
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)
3665
 
 
3666
 
        ins_ref = self._create_instance()
3667
 
 
3668
 
        self.assertRaises(AssertionError,
3669
 
                          self.libvirtconnection.migrate_disk_and_power_off,
3670
 
                          None, ins_ref, '10.0.0.2', None, None)
3671
 
 
3672
 
    def test_migrate_disk_and_power_off(self):
3673
 
        """Test for nova.virt.libvirt.libvirt_driver.LivirtConnection
3674
 
        .migrate_disk_and_power_off. """
3675
 
 
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)
3685
 
 
3686
 
        def fake_get_instance_disk_info(instance):
3687
 
            return disk_info_text
3688
 
 
3689
 
        def fake_destroy(instance):
3690
 
            pass
3691
 
 
3692
 
        def fake_get_host_ip_addr():
3693
 
            return '10.0.0.1'
3694
 
 
3695
 
        def fake_execute(*args, **kwargs):
3696
 
            pass
3697
 
 
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)
3704
 
 
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)
3710
 
 
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)
3715
 
 
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}
3722
 
            else:
3723
 
                return {'state': power_state.SHUTDOWN}
3724
 
 
3725
 
        self.stubs.Set(self.libvirtconnection, 'get_info',
3726
 
                       fake_get_info)
3727
 
 
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'})
3733
 
 
3734
 
        """ instance is running case """
3735
 
        self.assertRaises(utils.LoopingCallDone,
3736
 
                self.libvirtconnection._wait_for_running,
3737
 
                    {'name': 'running',
3738
 
                     'uuid': 'running_uuid'})
3739
 
 
3740
 
        """ else case """
3741
 
        self.libvirtconnection._wait_for_running({'name': 'else',
3742
 
                                                  'uuid': 'other_uuid'})
3743
 
 
3744
 
    def test_finish_migration(self):
3745
 
        """Test for nova.virt.libvirt.libvirt_driver.LivirtConnection
3746
 
        .finish_migration. """
3747
 
 
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)
3753
 
 
3754
 
        def fake_can_resize_fs(path, size, use_cow=False):
3755
 
            return False
3756
 
 
3757
 
        def fake_extend(path, size):
3758
 
            pass
3759
 
 
3760
 
        def fake_to_xml(instance, network_info, image_meta=None, rescue=None,
3761
 
                        block_device_info=None):
3762
 
            return ""
3763
 
 
3764
 
        def fake_plug_vifs(instance, network_info):
3765
 
            pass
3766
 
 
3767
 
        def fake_create_image(context, inst, libvirt_xml, suffix='',
3768
 
                      disk_images=None, network_info=None,
3769
 
                      block_device_info=None):
3770
 
            pass
3771
 
 
3772
 
        def fake_create_domain(xml):
3773
 
            return None
3774
 
 
3775
 
        def fake_enable_hairpin(instance):
3776
 
            pass
3777
 
 
3778
 
        def fake_execute(*args, **kwargs):
3779
 
            pass
3780
 
 
3781
 
        def fake_get_info(instance):
3782
 
            return {'state': power_state.RUNNING}
3783
 
 
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',
3787
 
                       fake_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',
3791
 
                       fake_create_image)
3792
 
        self.stubs.Set(self.libvirtconnection, '_create_domain',
3793
 
                       fake_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',
3800
 
                       fake_get_info)
3801
 
 
3802
 
        ins_ref = self._create_instance()
3803
 
 
3804
 
        self.libvirtconnection.finish_migration(
3805
 
                      context.get_admin_context(), None, ins_ref,
3806
 
                      disk_info_text, None, None, None)
3807
 
 
3808
 
    def test_finish_revert_migration(self):
3809
 
        """Test for nova.virt.libvirt.libvirt_driver.LivirtConnection
3810
 
        .finish_revert_migration. """
3811
 
 
3812
 
        def fake_execute(*args, **kwargs):
3813
 
            pass
3814
 
 
3815
 
        def fake_plug_vifs(instance, network_info):
3816
 
            pass
3817
 
 
3818
 
        def fake_create_domain(xml):
3819
 
            return None
3820
 
 
3821
 
        def fake_enable_hairpin(instance):
3822
 
            pass
3823
 
 
3824
 
        def fake_get_info(instance):
3825
 
            return {'state': power_state.RUNNING}
3826
 
 
3827
 
        def fake_to_xml(instance, network_info, image_meta=None, rescue=None,
3828
 
                        block_device_info=None):
3829
 
            return ""
3830
 
 
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',
3837
 
                       fake_create_domain)
3838
 
        self.stubs.Set(self.libvirtconnection, '_enable_hairpin',
3839
 
                       fake_enable_hairpin)
3840
 
        self.stubs.Set(self.libvirtconnection, 'get_info',
3841
 
                       fake_get_info)
3842
 
 
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,
3848
 
                                            ins_ref['name'],
3849
 
                                            'libvirt.xml')
3850
 
            f = open(libvirt_xml_path, 'w')
3851
 
            f.close()
3852
 
 
3853
 
            self.libvirtconnection.finish_revert_migration(ins_ref, None)
3854
 
 
3855
 
    def test_confirm_migration(self):
3856
 
        ins_ref = self._create_instance()
3857
 
 
3858
 
        self.mox.StubOutWithMock(self.libvirtconnection, "_cleanup_resize")
3859
 
        self.libvirtconnection._cleanup_resize(ins_ref,
3860
 
                             _fake_network_info(self.stubs, 1))
3861
 
 
3862
 
        self.mox.ReplayAll()
3863
 
        self.libvirtconnection.confirm_migration("migration_ref", ins_ref,
3864
 
                                            _fake_network_info(self.stubs, 1))
3865
 
 
3866
 
    def test_cleanup_resize_same_host(self):
3867
 
        ins_ref = self._create_instance({'host': FLAGS.host})
3868
 
 
3869
 
        def fake_os_path_exists(path):
3870
 
            return True
3871
 
 
3872
 
        def fake_shutil_rmtree(target):
3873
 
            pass
3874
 
 
3875
 
        self.stubs.Set(os.path, 'exists', fake_os_path_exists)
3876
 
        self.stubs.Set(shutil, 'rmtree', fake_shutil_rmtree)
3877
 
 
3878
 
        self.mox.ReplayAll()
3879
 
        self.libvirtconnection._cleanup_resize(ins_ref,
3880
 
                                            _fake_network_info(self.stubs, 1))
3881
 
 
3882
 
    def test_cleanup_resize_not_same_host(self):
3883
 
        host = 'not' + FLAGS.host
3884
 
        ins_ref = self._create_instance({'host': host})
3885
 
 
3886
 
        def fake_os_path_exists(path):
3887
 
            return True
3888
 
 
3889
 
        def fake_shutil_rmtree(target):
3890
 
            pass
3891
 
 
3892
 
        def fake_unfilter_instance(instance, network_info):
3893
 
            pass
3894
 
 
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)
3899
 
 
3900
 
        self.mox.ReplayAll()
3901
 
        self.libvirtconnection._cleanup_resize(ins_ref,
3902
 
                                            _fake_network_info(self.stubs, 1))
3903
 
 
3904
 
 
3905
 
class LibvirtNonblockingTestCase(test.TestCase):
3906
 
    """Test libvirt_nonblocking option"""
3907
 
 
3908
 
    def setUp(self):
3909
 
        super(LibvirtNonblockingTestCase, self).setUp()
3910
 
        self.flags(libvirt_nonblocking=True, libvirt_uri="test:///default")
3911
 
 
3912
 
    def tearDown(self):
3913
 
        super(LibvirtNonblockingTestCase, self).tearDown()
3914
 
 
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)