merge with trunk
This commit is contained in:
1
Authors
1
Authors
@@ -59,6 +59,7 @@ Joshua McKenty <jmckenty@gmail.com>
|
||||
Justin Santa Barbara <justin@fathomdb.com>
|
||||
Justin Shepherd <jshepher@rackspace.com>
|
||||
Kei Masumoto <masumotok@nttdata.co.jp>
|
||||
masumoto<masumotok@nttdata.co.jp>
|
||||
Ken Pepple <ken.pepple@gmail.com>
|
||||
Kevin Bringard <kbringard@attinteractive.com>
|
||||
Kevin L. Mitchell <kevin.mitchell@rackspace.com>
|
||||
|
||||
73
bin/clear_rabbit_queues
Executable file
73
bin/clear_rabbit_queues
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2011 Openstack, LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Admin/debug script to wipe rabbitMQ (AMQP) queues nova uses.
|
||||
This can be used if you need to change durable options on queues,
|
||||
or to wipe all messages in the queue system if things are in a
|
||||
serious bad way.
|
||||
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import gettext
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
# If ../nova/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
|
||||
sys.path.insert(0, POSSIBLE_TOPDIR)
|
||||
|
||||
gettext.install('nova', unicode=1)
|
||||
|
||||
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
from nova import rpc
|
||||
from nova import utils
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_boolean('delete_exchange', False, 'delete nova exchange too.')
|
||||
|
||||
|
||||
def delete_exchange(exch):
|
||||
conn = rpc.create_connection()
|
||||
x = conn.get_channel()
|
||||
x.exchange_delete(exch)
|
||||
|
||||
|
||||
def delete_queues(queues):
|
||||
conn = rpc.create_connection()
|
||||
x = conn.get_channel()
|
||||
for q in queues:
|
||||
x.queue_delete(q)
|
||||
|
||||
if __name__ == '__main__':
|
||||
utils.default_flagfile()
|
||||
args = flags.FLAGS(sys.argv)
|
||||
logging.setup()
|
||||
delete_queues(args[1:])
|
||||
if FLAGS.delete_exchange:
|
||||
delete_exchange(FLAGS.control_exchange)
|
||||
@@ -834,11 +834,13 @@ class VmCommands(object):
|
||||
instance['availability_zone'],
|
||||
instance['launch_index'])
|
||||
|
||||
@args('--ec2_id', dest='ec2_id', metavar='<ec2 id>', help='EC2 ID')
|
||||
@args('--dest', dest='dest', metavar='<Destanation>',
|
||||
help='destanation node')
|
||||
def live_migration(self, ec2_id, dest):
|
||||
"""Migrates a running instance to a new machine."""
|
||||
def _migration(self, ec2_id, dest, block_migration=False):
|
||||
"""Migrates a running instance to a new machine.
|
||||
:param ec2_id: instance id which comes from euca-describe-instance.
|
||||
:param dest: destination host name.
|
||||
:param block_migration: if True, do block_migration.
|
||||
|
||||
"""
|
||||
|
||||
ctxt = context.get_admin_context()
|
||||
instance_id = ec2utils.ec2_id_to_id(ec2_id)
|
||||
@@ -859,11 +861,28 @@ class VmCommands(object):
|
||||
{"method": "live_migration",
|
||||
"args": {"instance_id": instance_id,
|
||||
"dest": dest,
|
||||
"topic": FLAGS.compute_topic}})
|
||||
"topic": FLAGS.compute_topic,
|
||||
"block_migration": block_migration}})
|
||||
|
||||
print _('Migration of %s initiated.'
|
||||
'Check its progress using euca-describe-instances.') % ec2_id
|
||||
|
||||
@args('--ec2_id', dest='ec2_id', metavar='<ec2 id>', help='EC2 ID')
|
||||
@args('--dest', dest='dest', metavar='<Destanation>',
|
||||
help='destanation node')
|
||||
def live_migration(self, ec2_id, dest):
|
||||
"""Migrates a running instance to a new machine."""
|
||||
|
||||
self._migration(ec2_id, dest)
|
||||
|
||||
@args('--ec2_id', dest='ec2_id', metavar='<ec2 id>', help='EC2 ID')
|
||||
@args('--dest', dest='dest', metavar='<Destanation>',
|
||||
help='destanation node')
|
||||
def block_migration(self, ec2_id, dest):
|
||||
"""Migrates a running instance to a new machine with storage data."""
|
||||
|
||||
self._migration(ec2_id, dest, True)
|
||||
|
||||
|
||||
class ServiceCommands(object):
|
||||
"""Enable and disable running services"""
|
||||
@@ -945,9 +964,19 @@ class ServiceCommands(object):
|
||||
mem_u = result['resource']['memory_mb_used']
|
||||
hdd_u = result['resource']['local_gb_used']
|
||||
|
||||
cpu_sum = 0
|
||||
mem_sum = 0
|
||||
hdd_sum = 0
|
||||
print 'HOST\t\t\tPROJECT\t\tcpu\tmem(mb)\tdisk(gb)'
|
||||
print '%s(total)\t\t\t%s\t%s\t%s' % (host, cpu, mem, hdd)
|
||||
print '%s(used)\t\t\t%s\t%s\t%s' % (host, cpu_u, mem_u, hdd_u)
|
||||
print '%s(used_now)\t\t\t%s\t%s\t%s' % (host, cpu_u, mem_u, hdd_u)
|
||||
for p_id, val in result['usage'].items():
|
||||
cpu_sum += val['vcpus']
|
||||
mem_sum += val['memory_mb']
|
||||
hdd_sum += val['local_gb']
|
||||
print '%s(used_max)\t\t\t%s\t%s\t%s' % (host, cpu_sum,
|
||||
mem_sum, hdd_sum)
|
||||
|
||||
for p_id, val in result['usage'].items():
|
||||
print '%s\t\t%s\t\t%s\t%s\t%s' % (host,
|
||||
p_id,
|
||||
|
||||
@@ -305,6 +305,7 @@ DEFINE_string('rabbit_virtual_host', '/', 'rabbit virtual host')
|
||||
DEFINE_integer('rabbit_retry_interval', 10, 'rabbit connection retry interval')
|
||||
DEFINE_integer('rabbit_max_retries', 12, 'rabbit connection attempts')
|
||||
DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to')
|
||||
DEFINE_boolean('rabbit_durable_queues', False, 'use durable queues')
|
||||
DEFINE_list('enabled_apis', ['ec2', 'osapi'],
|
||||
'list of APIs to enable by default')
|
||||
DEFINE_string('ec2_host', '$my_ip', 'ip of api server')
|
||||
|
||||
@@ -257,7 +257,7 @@ class TopicAdapterConsumer(AdapterConsumer):
|
||||
self.queue = topic
|
||||
self.routing_key = topic
|
||||
self.exchange = FLAGS.control_exchange
|
||||
self.durable = False
|
||||
self.durable = FLAGS.rabbit_durable_queues
|
||||
super(TopicAdapterConsumer, self).__init__(connection=connection,
|
||||
topic=topic, proxy=proxy)
|
||||
|
||||
@@ -345,7 +345,7 @@ class TopicPublisher(Publisher):
|
||||
def __init__(self, connection=None, topic='broadcast'):
|
||||
self.routing_key = topic
|
||||
self.exchange = FLAGS.control_exchange
|
||||
self.durable = False
|
||||
self.durable = FLAGS.rabbit_durable_queues
|
||||
super(TopicPublisher, self).__init__(connection=connection)
|
||||
|
||||
|
||||
@@ -373,6 +373,7 @@ class DirectConsumer(Consumer):
|
||||
self.queue = msg_id
|
||||
self.routing_key = msg_id
|
||||
self.exchange = msg_id
|
||||
self.durable = False
|
||||
self.auto_delete = True
|
||||
self.exclusive = True
|
||||
super(DirectConsumer, self).__init__(connection=connection)
|
||||
@@ -386,6 +387,7 @@ class DirectPublisher(Publisher):
|
||||
def __init__(self, connection=None, msg_id=None):
|
||||
self.routing_key = msg_id
|
||||
self.exchange = msg_id
|
||||
self.durable = False
|
||||
self.auto_delete = True
|
||||
super(DirectPublisher, self).__init__(connection=connection)
|
||||
|
||||
@@ -573,7 +575,7 @@ def send_message(topic, message, wait=True):
|
||||
|
||||
publisher = messaging.Publisher(connection=Connection.instance(),
|
||||
exchange=FLAGS.control_exchange,
|
||||
durable=False,
|
||||
durable=FLAGS.rabbit_durable_queues,
|
||||
exchange_type='topic',
|
||||
routing_key=topic)
|
||||
publisher.send(message)
|
||||
|
||||
@@ -632,7 +632,7 @@ class ComputeTestCase(test.TestCase):
|
||||
vid = i_ref['volumes'][i]['id']
|
||||
volmock.setup_compute_volume(c, vid).InAnyOrder('g1')
|
||||
drivermock.plug_vifs(i_ref, [])
|
||||
drivermock.ensure_filtering_rules_for_instance(i_ref)
|
||||
drivermock.ensure_filtering_rules_for_instance(i_ref, [])
|
||||
|
||||
self.compute.db = dbmock
|
||||
self.compute.volume_manager = volmock
|
||||
@@ -657,7 +657,7 @@ class ComputeTestCase(test.TestCase):
|
||||
self.mox.StubOutWithMock(compute_manager.LOG, 'info')
|
||||
compute_manager.LOG.info(_("%s has no volume."), i_ref['hostname'])
|
||||
drivermock.plug_vifs(i_ref, [])
|
||||
drivermock.ensure_filtering_rules_for_instance(i_ref)
|
||||
drivermock.ensure_filtering_rules_for_instance(i_ref, [])
|
||||
|
||||
self.compute.db = dbmock
|
||||
self.compute.driver = drivermock
|
||||
@@ -714,11 +714,15 @@ class ComputeTestCase(test.TestCase):
|
||||
dbmock.queue_get_for(c, FLAGS.compute_topic, i_ref['host']).\
|
||||
AndReturn(topic)
|
||||
rpc.call(c, topic, {"method": "pre_live_migration",
|
||||
"args": {'instance_id': i_ref['id']}})
|
||||
"args": {'instance_id': i_ref['id'],
|
||||
'block_migration': False,
|
||||
'disk': None}})
|
||||
|
||||
self.mox.StubOutWithMock(self.compute.driver, 'live_migration')
|
||||
self.compute.driver.live_migration(c, i_ref, i_ref['host'],
|
||||
self.compute.post_live_migration,
|
||||
self.compute.recover_live_migration)
|
||||
self.compute.rollback_live_migration,
|
||||
False)
|
||||
|
||||
self.compute.db = dbmock
|
||||
self.mox.ReplayAll()
|
||||
@@ -739,13 +743,18 @@ class ComputeTestCase(test.TestCase):
|
||||
dbmock.queue_get_for(c, FLAGS.compute_topic, i_ref['host']).\
|
||||
AndReturn(topic)
|
||||
rpc.call(c, topic, {"method": "pre_live_migration",
|
||||
"args": {'instance_id': i_ref['id']}}).\
|
||||
"args": {'instance_id': i_ref['id'],
|
||||
'block_migration': False,
|
||||
'disk': None}}).\
|
||||
AndRaise(rpc.RemoteError('', '', ''))
|
||||
dbmock.instance_update(c, i_ref['id'], {'state_description': 'running',
|
||||
'state': power_state.RUNNING,
|
||||
'host': i_ref['host']})
|
||||
for v in i_ref['volumes']:
|
||||
dbmock.volume_update(c, v['id'], {'status': 'in-use'})
|
||||
# mock for volume_api.remove_from_compute
|
||||
rpc.call(c, topic, {"method": "remove_volume",
|
||||
"args": {'volume_id': v['id']}})
|
||||
|
||||
self.compute.db = dbmock
|
||||
self.mox.ReplayAll()
|
||||
@@ -766,7 +775,9 @@ class ComputeTestCase(test.TestCase):
|
||||
AndReturn(topic)
|
||||
self.mox.StubOutWithMock(rpc, 'call')
|
||||
rpc.call(c, topic, {"method": "pre_live_migration",
|
||||
"args": {'instance_id': i_ref['id']}}).\
|
||||
"args": {'instance_id': i_ref['id'],
|
||||
'block_migration': False,
|
||||
'disk': None}}).\
|
||||
AndRaise(rpc.RemoteError('', '', ''))
|
||||
dbmock.instance_update(c, i_ref['id'], {'state_description': 'running',
|
||||
'state': power_state.RUNNING,
|
||||
@@ -791,11 +802,14 @@ class ComputeTestCase(test.TestCase):
|
||||
dbmock.queue_get_for(c, FLAGS.compute_topic, i_ref['host']).\
|
||||
AndReturn(topic)
|
||||
rpc.call(c, topic, {"method": "pre_live_migration",
|
||||
"args": {'instance_id': i_ref['id']}})
|
||||
"args": {'instance_id': i_ref['id'],
|
||||
'block_migration': False,
|
||||
'disk': None}})
|
||||
self.mox.StubOutWithMock(self.compute.driver, 'live_migration')
|
||||
self.compute.driver.live_migration(c, i_ref, i_ref['host'],
|
||||
self.compute.post_live_migration,
|
||||
self.compute.recover_live_migration)
|
||||
self.compute.rollback_live_migration,
|
||||
False)
|
||||
|
||||
self.compute.db = dbmock
|
||||
self.mox.ReplayAll()
|
||||
@@ -829,6 +843,10 @@ class ComputeTestCase(test.TestCase):
|
||||
self.compute.volume_manager.remove_compute_volume(c, v['id'])
|
||||
self.mox.StubOutWithMock(self.compute.driver, 'unfilter_instance')
|
||||
self.compute.driver.unfilter_instance(i_ref, [])
|
||||
self.mox.StubOutWithMock(rpc, 'call')
|
||||
rpc.call(c, db.queue_get_for(c, FLAGS.compute_topic, dest),
|
||||
{"method": "post_live_migration_at_destination",
|
||||
"args": {'instance_id': i_ref['id'], 'block_migration': False}})
|
||||
|
||||
# executing
|
||||
self.mox.ReplayAll()
|
||||
|
||||
@@ -21,6 +21,7 @@ import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from xml.etree.ElementTree import fromstring as xml_to_tree
|
||||
from xml.dom.minidom import parseString as xml_to_dom
|
||||
@@ -49,18 +50,19 @@ def _create_network_info(count=1, ipv6=None):
|
||||
if ipv6 is None:
|
||||
ipv6 = FLAGS.use_ipv6
|
||||
fake = 'fake'
|
||||
fake_ip = '0.0.0.0/0'
|
||||
fake_ip_2 = '0.0.0.1/0'
|
||||
fake_ip_3 = '0.0.0.1/0'
|
||||
fake_ip = '10.11.12.13'
|
||||
fake_ip_2 = '0.0.0.1'
|
||||
fake_ip_3 = '0.0.0.1'
|
||||
fake_vlan = 100
|
||||
fake_bridge_interface = 'eth0'
|
||||
network = {'bridge': fake,
|
||||
'cidr': fake_ip,
|
||||
'cidr_v6': fake_ip,
|
||||
'gateway_v6': fake,
|
||||
'vlan': fake_vlan,
|
||||
'bridge_interface': fake_bridge_interface}
|
||||
mapping = {'mac': fake,
|
||||
'dhcp_server': fake,
|
||||
'dhcp_server': '10.0.0.1',
|
||||
'gateway': fake,
|
||||
'gateway6': fake,
|
||||
'ips': [{'ip': fake_ip}, {'ip': fake_ip}]}
|
||||
@@ -273,15 +275,14 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn = connection.LibvirtConnection(True)
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
|
||||
result = conn._prepare_xml_info(instance_ref, False)
|
||||
self.assertFalse(result['nics'])
|
||||
|
||||
result = conn._prepare_xml_info(instance_ref, False,
|
||||
_create_network_info())
|
||||
result = conn._prepare_xml_info(instance_ref,
|
||||
_create_network_info(),
|
||||
False)
|
||||
self.assertTrue(len(result['nics']) == 1)
|
||||
|
||||
result = conn._prepare_xml_info(instance_ref, False,
|
||||
_create_network_info(2))
|
||||
result = conn._prepare_xml_info(instance_ref,
|
||||
_create_network_info(2),
|
||||
False)
|
||||
self.assertTrue(len(result['nics']) == 2)
|
||||
|
||||
def test_xml_and_uri_no_ramdisk_no_kernel(self):
|
||||
@@ -408,16 +409,16 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
network_info = _create_network_info(2)
|
||||
conn = connection.LibvirtConnection(True)
|
||||
instance_ref = db.instance_create(self.context, instance_data)
|
||||
xml = conn.to_xml(instance_ref, False, network_info)
|
||||
xml = conn.to_xml(instance_ref, network_info, False)
|
||||
tree = xml_to_tree(xml)
|
||||
interfaces = tree.findall("./devices/interface")
|
||||
self.assertEquals(len(interfaces), 2)
|
||||
parameters = interfaces[0].findall('./filterref/parameter')
|
||||
self.assertEquals(interfaces[0].get('type'), 'bridge')
|
||||
self.assertEquals(parameters[0].get('name'), 'IP')
|
||||
self.assertEquals(parameters[0].get('value'), '0.0.0.0/0')
|
||||
self.assertEquals(parameters[0].get('value'), '10.11.12.13')
|
||||
self.assertEquals(parameters[1].get('name'), 'DHCPSERVER')
|
||||
self.assertEquals(parameters[1].get('value'), 'fake')
|
||||
self.assertEquals(parameters[1].get('value'), '10.0.0.1')
|
||||
|
||||
def _check_xml_and_container(self, instance):
|
||||
user_context = context.RequestContext(self.user_id,
|
||||
@@ -431,7 +432,8 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
uri = conn.get_uri()
|
||||
self.assertEquals(uri, 'lxc:///')
|
||||
|
||||
xml = conn.to_xml(instance_ref)
|
||||
network_info = _create_network_info()
|
||||
xml = conn.to_xml(instance_ref, network_info)
|
||||
tree = xml_to_tree(xml)
|
||||
|
||||
check = [
|
||||
@@ -528,17 +530,20 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
uri = conn.get_uri()
|
||||
self.assertEquals(uri, expected_uri)
|
||||
|
||||
xml = conn.to_xml(instance_ref, rescue)
|
||||
network_info = _create_network_info()
|
||||
xml = conn.to_xml(instance_ref, network_info, rescue)
|
||||
tree = xml_to_tree(xml)
|
||||
for i, (check, expected_result) in enumerate(checks):
|
||||
self.assertEqual(check(tree),
|
||||
expected_result,
|
||||
'%s failed check %d' % (xml, i))
|
||||
'%s != %s failed check %d' %
|
||||
(check(tree), expected_result, i))
|
||||
|
||||
for i, (check, expected_result) in enumerate(common_checks):
|
||||
self.assertEqual(check(tree),
|
||||
expected_result,
|
||||
'%s failed common check %d' % (xml, i))
|
||||
'%s != %s failed common check %d' %
|
||||
(check(tree), expected_result, i))
|
||||
|
||||
# This test is supposed to make sure we don't
|
||||
# override a specifically set uri
|
||||
@@ -623,7 +628,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
return
|
||||
|
||||
# Preparing mocks
|
||||
def fake_none(self):
|
||||
def fake_none(self, *args):
|
||||
return
|
||||
|
||||
def fake_raise(self):
|
||||
@@ -640,6 +645,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
|
||||
self.create_fake_libvirt_mock()
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
network_info = _create_network_info()
|
||||
|
||||
# Start test
|
||||
self.mox.ReplayAll()
|
||||
@@ -649,6 +655,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.firewall_driver.setattr('prepare_instance_filter', fake_none)
|
||||
conn.firewall_driver.setattr('instance_filter_exists', fake_none)
|
||||
conn.ensure_filtering_rules_for_instance(instance_ref,
|
||||
network_info,
|
||||
time=fake_timer)
|
||||
except exception.Error, e:
|
||||
c1 = (0 <= e.message.find('Timeout migrating for'))
|
||||
@@ -690,17 +697,20 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
return vdmock
|
||||
|
||||
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
|
||||
self.mox.StubOutWithMock(self.compute, "recover_live_migration")
|
||||
self.compute.recover_live_migration(self.context, instance_ref,
|
||||
dest='dest')
|
||||
# self.mox.StubOutWithMock(self.compute, "recover_live_migration")
|
||||
self.mox.StubOutWithMock(self.compute, "rollback_live_migration")
|
||||
# self.compute.recover_live_migration(self.context, instance_ref,
|
||||
# dest='dest')
|
||||
self.compute.rollback_live_migration(self.context, instance_ref,
|
||||
'dest', False)
|
||||
|
||||
# Start test
|
||||
#start test
|
||||
self.mox.ReplayAll()
|
||||
conn = connection.LibvirtConnection(False)
|
||||
self.assertRaises(libvirt.libvirtError,
|
||||
conn._live_migration,
|
||||
self.context, instance_ref, 'dest', '',
|
||||
self.compute.recover_live_migration)
|
||||
self.context, instance_ref, 'dest', False,
|
||||
self.compute.rollback_live_migration)
|
||||
|
||||
instance_ref = db.instance_get(self.context, instance_ref['id'])
|
||||
self.assertTrue(instance_ref['state_description'] == 'running')
|
||||
@@ -711,6 +721,95 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
db.volume_destroy(self.context, volume_ref['id'])
|
||||
db.instance_destroy(self.context, instance_ref['id'])
|
||||
|
||||
def test_pre_block_migration_works_correctly(self):
|
||||
"""Confirms pre_block_migration works correctly."""
|
||||
|
||||
# Skip if non-libvirt environment
|
||||
if not self.lazy_load_library_exists():
|
||||
return
|
||||
|
||||
# Replace instances_path since this testcase creates tmpfile
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
store = FLAGS.instances_path
|
||||
FLAGS.instances_path = tmpdir
|
||||
|
||||
# Test data
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
dummyjson = '[{"path": "%s/disk", "local_gb": "10G", "type": "raw"}]'
|
||||
|
||||
# Preparing mocks
|
||||
# qemu-img should be mockd since test environment might not have
|
||||
# large disk space.
|
||||
self.mox.StubOutWithMock(utils, "execute")
|
||||
utils.execute('sudo', 'qemu-img', 'create', '-f', 'raw',
|
||||
'%s/%s/disk' % (tmpdir, instance_ref.name), '10G')
|
||||
|
||||
self.mox.ReplayAll()
|
||||
conn = connection.LibvirtConnection(False)
|
||||
conn.pre_block_migration(self.context, instance_ref,
|
||||
dummyjson % tmpdir)
|
||||
|
||||
self.assertTrue(os.path.exists('%s/%s/' %
|
||||
(tmpdir, instance_ref.name)))
|
||||
|
||||
shutil.rmtree(tmpdir)
|
||||
db.instance_destroy(self.context, instance_ref['id'])
|
||||
# Restore FLAGS.instances_path
|
||||
FLAGS.instances_path = store
|
||||
|
||||
def test_get_instance_disk_info_works_correctly(self):
|
||||
"""Confirms pre_block_migration works correctly."""
|
||||
# Skip if non-libvirt environment
|
||||
if not self.lazy_load_library_exists():
|
||||
return
|
||||
|
||||
# Test data
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
|
||||
"<devices>"
|
||||
"<disk type='file'><driver name='qemu' type='raw'/>"
|
||||
"<source file='/test/disk'/>"
|
||||
"<target dev='vda' bus='virtio'/></disk>"
|
||||
"<disk type='file'><driver name='qemu' type='qcow2'/>"
|
||||
"<source file='/test/disk.local'/>"
|
||||
"<target dev='vdb' bus='virtio'/></disk>"
|
||||
"</devices></domain>")
|
||||
|
||||
ret = ("image: /test/disk\nfile format: raw\n"
|
||||
"virtual size: 20G (21474836480 bytes)\ndisk size: 3.1G\n")
|
||||
|
||||
# Preparing mocks
|
||||
vdmock = self.mox.CreateMock(libvirt.virDomain)
|
||||
self.mox.StubOutWithMock(vdmock, "XMLDesc")
|
||||
vdmock.XMLDesc(0).AndReturn(dummyxml)
|
||||
|
||||
def fake_lookup(instance_name):
|
||||
if instance_name == instance_ref.name:
|
||||
return vdmock
|
||||
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
|
||||
|
||||
self.mox.StubOutWithMock(os.path, "getsize")
|
||||
# based on above testdata, one is raw image, so getsize is mocked.
|
||||
os.path.getsize("/test/disk").AndReturn(10 * 1024 * 1024 * 1024)
|
||||
# another is qcow image, so qemu-img should be mocked.
|
||||
self.mox.StubOutWithMock(utils, "execute")
|
||||
utils.execute('sudo', 'qemu-img', 'info', '/test/disk.local').\
|
||||
AndReturn((ret, ''))
|
||||
|
||||
self.mox.ReplayAll()
|
||||
conn = connection.LibvirtConnection(False)
|
||||
info = conn.get_instance_disk_info(self.context, instance_ref)
|
||||
info = utils.loads(info)
|
||||
|
||||
self.assertTrue(info[0]['type'] == 'raw' and
|
||||
info[1]['type'] == 'qcow2' and
|
||||
info[0]['path'] == '/test/disk' and
|
||||
info[1]['path'] == '/test/disk.local' and
|
||||
info[0]['local_gb'] == '10G' and
|
||||
info[1]['local_gb'] == '20G')
|
||||
|
||||
db.instance_destroy(self.context, instance_ref['id'])
|
||||
|
||||
def test_spawn_with_network_info(self):
|
||||
# Skip if non-libvirt environment
|
||||
if not self.lazy_load_library_exists():
|
||||
@@ -962,8 +1061,9 @@ class IptablesFirewallTestCase(test.TestCase):
|
||||
from nova.network import linux_net
|
||||
linux_net.iptables_manager.execute = fake_iptables_execute
|
||||
|
||||
self.fw.prepare_instance_filter(instance_ref)
|
||||
self.fw.apply_instance_filter(instance_ref)
|
||||
network_info = _create_network_info()
|
||||
self.fw.prepare_instance_filter(instance_ref, network_info)
|
||||
self.fw.apply_instance_filter(instance_ref, network_info)
|
||||
|
||||
in_rules = filter(lambda l: not l.startswith('#'),
|
||||
self.in_filter_rules)
|
||||
@@ -1033,7 +1133,7 @@ class IptablesFirewallTestCase(test.TestCase):
|
||||
ipv6_len = len(self.fw.iptables.ipv6['filter'].rules)
|
||||
inst_ipv4, inst_ipv6 = self.fw.instance_rules(instance_ref,
|
||||
network_info)
|
||||
self.fw.add_filters_for_instance(instance_ref, network_info)
|
||||
self.fw.prepare_instance_filter(instance_ref, network_info)
|
||||
ipv4 = self.fw.iptables.ipv4['filter'].rules
|
||||
ipv6 = self.fw.iptables.ipv6['filter'].rules
|
||||
ipv4_network_rules = len(ipv4) - len(inst_ipv4) - ipv4_len
|
||||
@@ -1048,7 +1148,7 @@ class IptablesFirewallTestCase(test.TestCase):
|
||||
self.mox.StubOutWithMock(self.fw,
|
||||
'add_filters_for_instance',
|
||||
use_mock_anything=True)
|
||||
self.fw.add_filters_for_instance(instance_ref, mox.IgnoreArg())
|
||||
self.fw.prepare_instance_filter(instance_ref, mox.IgnoreArg())
|
||||
self.fw.instances[instance_ref['id']] = instance_ref
|
||||
self.mox.ReplayAll()
|
||||
self.fw.do_refresh_security_group_rules("fake")
|
||||
@@ -1068,11 +1168,12 @@ class IptablesFirewallTestCase(test.TestCase):
|
||||
instance_ref = self._create_instance_ref()
|
||||
|
||||
_setup_networking(instance_ref['id'], self.test_ip)
|
||||
self.fw.setup_basic_filtering(instance_ref)
|
||||
self.fw.prepare_instance_filter(instance_ref)
|
||||
self.fw.apply_instance_filter(instance_ref)
|
||||
network_info = _create_network_info()
|
||||
self.fw.setup_basic_filtering(instance_ref, network_info)
|
||||
self.fw.prepare_instance_filter(instance_ref, network_info)
|
||||
self.fw.apply_instance_filter(instance_ref, network_info)
|
||||
original_filter_count = len(fakefilter.filters)
|
||||
self.fw.unfilter_instance(instance_ref)
|
||||
self.fw.unfilter_instance(instance_ref, network_info)
|
||||
|
||||
# should undefine just the instance filter
|
||||
self.assertEqual(original_filter_count - len(fakefilter.filters), 1)
|
||||
@@ -1082,14 +1183,14 @@ class IptablesFirewallTestCase(test.TestCase):
|
||||
def test_provider_firewall_rules(self):
|
||||
# setup basic instance data
|
||||
instance_ref = self._create_instance_ref()
|
||||
nw_info = _create_network_info(1)
|
||||
_setup_networking(instance_ref['id'], self.test_ip)
|
||||
# FRAGILE: peeks at how the firewall names chains
|
||||
chain_name = 'inst-%s' % instance_ref['id']
|
||||
|
||||
# create a firewall via setup_basic_filtering like libvirt_conn.spawn
|
||||
# should have a chain with 0 rules
|
||||
self.fw.setup_basic_filtering(instance_ref, network_info=nw_info)
|
||||
network_info = _create_network_info(1)
|
||||
self.fw.setup_basic_filtering(instance_ref, network_info)
|
||||
self.assertTrue('provider' in self.fw.iptables.ipv4['filter'].chains)
|
||||
rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
|
||||
if rule.chain == 'provider']
|
||||
@@ -1119,8 +1220,8 @@ class IptablesFirewallTestCase(test.TestCase):
|
||||
self.assertEqual(2, len(rules))
|
||||
|
||||
# create the instance filter and make sure it has a jump rule
|
||||
self.fw.prepare_instance_filter(instance_ref, network_info=nw_info)
|
||||
self.fw.apply_instance_filter(instance_ref)
|
||||
self.fw.prepare_instance_filter(instance_ref, network_info)
|
||||
self.fw.apply_instance_filter(instance_ref, network_info)
|
||||
inst_rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
|
||||
if rule.chain == chain_name]
|
||||
jump_rules = [rule for rule in inst_rules if '-j' in rule.rule]
|
||||
@@ -1272,7 +1373,7 @@ class NWFilterTestCase(test.TestCase):
|
||||
|
||||
def _ensure_all_called():
|
||||
instance_filter = 'nova-instance-%s-%s' % (instance_ref['name'],
|
||||
'561212121212')
|
||||
'fake')
|
||||
secgroup_filter = 'nova-secgroup-%s' % self.security_group['id']
|
||||
for required in [secgroup_filter, 'allow-dhcp-server',
|
||||
'no-arp-spoofing', 'no-ip-spoofing',
|
||||
@@ -1288,9 +1389,10 @@ class NWFilterTestCase(test.TestCase):
|
||||
self.security_group.id)
|
||||
instance = db.instance_get(self.context, inst_id)
|
||||
|
||||
self.fw.setup_basic_filtering(instance)
|
||||
self.fw.prepare_instance_filter(instance)
|
||||
self.fw.apply_instance_filter(instance)
|
||||
network_info = _create_network_info()
|
||||
self.fw.setup_basic_filtering(instance, network_info)
|
||||
self.fw.prepare_instance_filter(instance, network_info)
|
||||
self.fw.apply_instance_filter(instance, network_info)
|
||||
_ensure_all_called()
|
||||
self.teardown_security_group()
|
||||
db.instance_destroy(context.get_admin_context(), instance_ref['id'])
|
||||
@@ -1321,11 +1423,12 @@ class NWFilterTestCase(test.TestCase):
|
||||
instance = db.instance_get(self.context, inst_id)
|
||||
|
||||
_setup_networking(instance_ref['id'], self.test_ip)
|
||||
self.fw.setup_basic_filtering(instance)
|
||||
self.fw.prepare_instance_filter(instance)
|
||||
self.fw.apply_instance_filter(instance)
|
||||
network_info = _create_network_info()
|
||||
self.fw.setup_basic_filtering(instance, network_info)
|
||||
self.fw.prepare_instance_filter(instance, network_info)
|
||||
self.fw.apply_instance_filter(instance, network_info)
|
||||
original_filter_count = len(fakefilter.filters)
|
||||
self.fw.unfilter_instance(instance)
|
||||
self.fw.unfilter_instance(instance, network_info)
|
||||
|
||||
# should undefine 2 filters: instance and instance-secgroup
|
||||
self.assertEqual(original_filter_count - len(fakefilter.filters), 2)
|
||||
|
||||
Reference in New Issue
Block a user