Merge trunk
This commit is contained in:
1
.mailmap
1
.mailmap
@@ -15,6 +15,7 @@
|
|||||||
<corywright@gmail.com> <cory.wright@rackspace.com>
|
<corywright@gmail.com> <cory.wright@rackspace.com>
|
||||||
<devin.carlen@gmail.com> <devcamcar@illian.local>
|
<devin.carlen@gmail.com> <devcamcar@illian.local>
|
||||||
<ewan.mellor@citrix.com> <emellor@silver>
|
<ewan.mellor@citrix.com> <emellor@silver>
|
||||||
|
<itoumsn@nttdata.co.jp> <itoumsn@shayol>
|
||||||
<jaypipes@gmail.com> <jpipes@serialcoder>
|
<jaypipes@gmail.com> <jpipes@serialcoder>
|
||||||
<jmckenty@gmail.com> <jmckenty@joshua-mckentys-macbook-pro.local>
|
<jmckenty@gmail.com> <jmckenty@joshua-mckentys-macbook-pro.local>
|
||||||
<jmckenty@gmail.com> <jmckenty@yyj-dhcp171.corp.flock.com>
|
<jmckenty@gmail.com> <jmckenty@yyj-dhcp171.corp.flock.com>
|
||||||
|
|||||||
1
Authors
1
Authors
@@ -39,6 +39,7 @@ Ken Pepple <ken.pepple@gmail.com>
|
|||||||
Kevin L. Mitchell <kevin.mitchell@rackspace.com>
|
Kevin L. Mitchell <kevin.mitchell@rackspace.com>
|
||||||
Koji Iida <iida.koji@lab.ntt.co.jp>
|
Koji Iida <iida.koji@lab.ntt.co.jp>
|
||||||
Lorin Hochstein <lorin@isi.edu>
|
Lorin Hochstein <lorin@isi.edu>
|
||||||
|
Masanori Itoh <itoumsn@nttdata.co.jp>
|
||||||
Matt Dietz <matt.dietz@rackspace.com>
|
Matt Dietz <matt.dietz@rackspace.com>
|
||||||
Michael Gundlach <michael.gundlach@rackspace.com>
|
Michael Gundlach <michael.gundlach@rackspace.com>
|
||||||
Monsyne Dragon <mdragon@rackspace.com>
|
Monsyne Dragon <mdragon@rackspace.com>
|
||||||
|
|||||||
46
bin/nova-api
46
bin/nova-api
@@ -36,49 +36,15 @@ gettext.install('nova', unicode=1)
|
|||||||
|
|
||||||
from nova import flags
|
from nova import flags
|
||||||
from nova import log as logging
|
from nova import log as logging
|
||||||
|
from nova import service
|
||||||
from nova import utils
|
from nova import utils
|
||||||
from nova import version
|
from nova import version
|
||||||
from nova import wsgi
|
from nova import wsgi
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger('nova.api')
|
LOG = logging.getLogger('nova.api')
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
flags.DEFINE_string('ec2_listen', "0.0.0.0",
|
|
||||||
'IP address for EC2 API to listen')
|
|
||||||
flags.DEFINE_integer('ec2_listen_port', 8773, 'port for ec2 api to listen')
|
|
||||||
flags.DEFINE_string('osapi_listen', "0.0.0.0",
|
|
||||||
'IP address for OpenStack API to listen')
|
|
||||||
flags.DEFINE_integer('osapi_listen_port', 8774, 'port for os api to listen')
|
|
||||||
flags.DEFINE_flag(flags.HelpFlag())
|
|
||||||
flags.DEFINE_flag(flags.HelpshortFlag())
|
|
||||||
flags.DEFINE_flag(flags.HelpXMLFlag())
|
|
||||||
|
|
||||||
API_ENDPOINTS = ['ec2', 'osapi']
|
|
||||||
|
|
||||||
|
|
||||||
def run_app(paste_config_file):
|
|
||||||
LOG.debug(_("Using paste.deploy config at: %s"), paste_config_file)
|
|
||||||
apps = []
|
|
||||||
for api in API_ENDPOINTS:
|
|
||||||
config = wsgi.load_paste_configuration(paste_config_file, api)
|
|
||||||
if config is None:
|
|
||||||
LOG.debug(_("No paste configuration for app: %s"), api)
|
|
||||||
continue
|
|
||||||
LOG.debug(_("App Config: %(api)s\n%(config)r") % locals())
|
|
||||||
LOG.info(_("Running %s API"), api)
|
|
||||||
app = wsgi.load_paste_app(paste_config_file, api)
|
|
||||||
apps.append((app, getattr(FLAGS, "%s_listen_port" % api),
|
|
||||||
getattr(FLAGS, "%s_listen" % api)))
|
|
||||||
if len(apps) == 0:
|
|
||||||
LOG.error(_("No known API applications configured in %s."),
|
|
||||||
paste_config_file)
|
|
||||||
return
|
|
||||||
|
|
||||||
server = wsgi.Server()
|
|
||||||
for app in apps:
|
|
||||||
server.start(*app)
|
|
||||||
server.wait()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
utils.default_flagfile()
|
utils.default_flagfile()
|
||||||
@@ -90,8 +56,6 @@ if __name__ == '__main__':
|
|||||||
for flag in FLAGS:
|
for flag in FLAGS:
|
||||||
flag_get = FLAGS.get(flag, None)
|
flag_get = FLAGS.get(flag, None)
|
||||||
LOG.debug("%(flag)s : %(flag_get)s" % locals())
|
LOG.debug("%(flag)s : %(flag_get)s" % locals())
|
||||||
conf = wsgi.paste_config_file('nova-api.conf')
|
|
||||||
if conf:
|
service = service.serve_wsgi(service.ApiService)
|
||||||
run_app(conf)
|
service.wait()
|
||||||
else:
|
|
||||||
LOG.error(_("No paste configuration found for: %s"), 'nova-api.conf')
|
|
||||||
|
|||||||
@@ -545,6 +545,15 @@ class NetworkCommands(object):
|
|||||||
network.dhcp_start,
|
network.dhcp_start,
|
||||||
network.dns)
|
network.dns)
|
||||||
|
|
||||||
|
def delete(self, fixed_range):
|
||||||
|
"""Deletes a network"""
|
||||||
|
network = db.network_get_by_cidr(context.get_admin_context(), \
|
||||||
|
fixed_range)
|
||||||
|
if network.project_id is not None:
|
||||||
|
raise ValueError(_('Network must be disassociated from project %s'
|
||||||
|
' before delete' % network.project_id))
|
||||||
|
db.network_delete_safe(context.get_admin_context(), network.id)
|
||||||
|
|
||||||
|
|
||||||
class ServiceCommands(object):
|
class ServiceCommands(object):
|
||||||
"""Enable and disable running services"""
|
"""Enable and disable running services"""
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ class Exchange(object):
|
|||||||
nm = self.name
|
nm = self.name
|
||||||
LOG.debug(_('(%(nm)s) publish (key: %(routing_key)s)'
|
LOG.debug(_('(%(nm)s) publish (key: %(routing_key)s)'
|
||||||
' %(message)s') % locals())
|
' %(message)s') % locals())
|
||||||
routing_key = routing_key.split('.')[0]
|
|
||||||
if routing_key in self._routes:
|
if routing_key in self._routes:
|
||||||
for f in self._routes[routing_key]:
|
for f in self._routes[routing_key]:
|
||||||
LOG.debug(_('Publishing to route %s'), f)
|
LOG.debug(_('Publishing to route %s'), f)
|
||||||
|
|||||||
@@ -266,7 +266,10 @@ class NovaRootLogger(NovaLogger):
|
|||||||
|
|
||||||
|
|
||||||
def handle_exception(type, value, tb):
|
def handle_exception(type, value, tb):
|
||||||
logging.root.critical(str(value), exc_info=(type, value, tb))
|
extra = {}
|
||||||
|
if FLAGS.verbose:
|
||||||
|
extra['exc_info'] = (type, value, tb)
|
||||||
|
logging.root.critical(str(value), **extra)
|
||||||
|
|
||||||
|
|
||||||
def reset():
|
def reset():
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ class Consumer(messaging.Consumer):
|
|||||||
LOG.error(_("Reconnected to queue"))
|
LOG.error(_("Reconnected to queue"))
|
||||||
self.failed_connection = False
|
self.failed_connection = False
|
||||||
# NOTE(vish): This is catching all errors because we really don't
|
# NOTE(vish): This is catching all errors because we really don't
|
||||||
# exceptions to be logged 10 times a second if some
|
# want exceptions to be logged 10 times a second if some
|
||||||
# persistent failure occurs.
|
# persistent failure occurs.
|
||||||
except Exception: # pylint: disable-msg=W0703
|
except Exception: # pylint: disable-msg=W0703
|
||||||
if not self.failed_connection:
|
if not self.failed_connection:
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ class CloudTestCase(test.TestCase):
|
|||||||
self._create_key('test1')
|
self._create_key('test1')
|
||||||
self._create_key('test2')
|
self._create_key('test2')
|
||||||
result = self.cloud.describe_key_pairs(self.context)
|
result = self.cloud.describe_key_pairs(self.context)
|
||||||
keys = result["keypairsSet"]
|
keys = result["keySet"]
|
||||||
self.assertTrue(filter(lambda k: k['keyName'] == 'test1', keys))
|
self.assertTrue(filter(lambda k: k['keyName'] == 'test1', keys))
|
||||||
self.assertTrue(filter(lambda k: k['keyName'] == 'test2', keys))
|
self.assertTrue(filter(lambda k: k['keyName'] == 'test2', keys))
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class ComputeTestCase(test.TestCase):
|
|||||||
self.manager.delete_project(self.project)
|
self.manager.delete_project(self.project)
|
||||||
super(ComputeTestCase, self).tearDown()
|
super(ComputeTestCase, self).tearDown()
|
||||||
|
|
||||||
def _create_instance(self):
|
def _create_instance(self, params={}):
|
||||||
"""Create a test instance"""
|
"""Create a test instance"""
|
||||||
inst = {}
|
inst = {}
|
||||||
inst['image_id'] = 'ami-test'
|
inst['image_id'] = 'ami-test'
|
||||||
@@ -68,6 +68,7 @@ class ComputeTestCase(test.TestCase):
|
|||||||
inst['instance_type'] = 'm1.tiny'
|
inst['instance_type'] = 'm1.tiny'
|
||||||
inst['mac_address'] = utils.generate_mac()
|
inst['mac_address'] = utils.generate_mac()
|
||||||
inst['ami_launch_index'] = 0
|
inst['ami_launch_index'] = 0
|
||||||
|
inst.update(params)
|
||||||
return db.instance_create(self.context, inst)['id']
|
return db.instance_create(self.context, inst)['id']
|
||||||
|
|
||||||
def _create_group(self):
|
def _create_group(self):
|
||||||
@@ -268,9 +269,30 @@ class ComputeTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.compute.terminate_instance(self.context, instance_id)
|
self.compute.terminate_instance(self.context, instance_id)
|
||||||
|
|
||||||
|
def test_resize_instance(self):
|
||||||
|
"""Ensure instance can be migrated/resized"""
|
||||||
|
instance_id = self._create_instance()
|
||||||
|
context = self.context.elevated()
|
||||||
|
self.compute.run_instance(self.context, instance_id)
|
||||||
|
db.instance_update(self.context, instance_id, {'host': 'foo'})
|
||||||
|
self.compute.prep_resize(context, instance_id)
|
||||||
|
migration_ref = db.migration_get_by_instance_and_status(context,
|
||||||
|
instance_id, 'pre-migrating')
|
||||||
|
self.compute.resize_instance(context, instance_id,
|
||||||
|
migration_ref['id'])
|
||||||
|
self.compute.terminate_instance(context, instance_id)
|
||||||
|
|
||||||
def test_get_by_flavor_id(self):
|
def test_get_by_flavor_id(self):
|
||||||
type = instance_types.get_by_flavor_id(1)
|
type = instance_types.get_by_flavor_id(1)
|
||||||
self.assertEqual(type, 'm1.tiny')
|
self.assertEqual(type, 'm1.tiny')
|
||||||
|
|
||||||
|
def test_resize_same_source_fails(self):
|
||||||
|
"""Ensure instance fails to migrate when source and destination are
|
||||||
|
the same host"""
|
||||||
|
instance_id = self._create_instance()
|
||||||
|
self.compute.run_instance(self.context, instance_id)
|
||||||
|
self.assertRaises(exception.Error, self.compute.prep_resize,
|
||||||
|
self.context, instance_id)
|
||||||
|
self.compute.terminate_instance(self.context, instance_id)
|
||||||
type = instance_types.get_by_flavor_id("1")
|
type = instance_types.get_by_flavor_id("1")
|
||||||
self.assertEqual(type, 'm1.tiny')
|
self.assertEqual(type, 'm1.tiny')
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class DirectTestCase(test.TestCase):
|
|||||||
req.headers['X-OpenStack-User'] = 'user1'
|
req.headers['X-OpenStack-User'] = 'user1'
|
||||||
req.headers['X-OpenStack-Project'] = 'proj1'
|
req.headers['X-OpenStack-Project'] = 'proj1'
|
||||||
resp = req.get_response(self.auth_router)
|
resp = req.get_response(self.auth_router)
|
||||||
|
self.assertEqual(resp.status_int, 200)
|
||||||
data = json.loads(resp.body)
|
data = json.loads(resp.body)
|
||||||
self.assertEqual(data['user'], 'user1')
|
self.assertEqual(data['user'], 'user1')
|
||||||
self.assertEqual(data['project'], 'proj1')
|
self.assertEqual(data['project'], 'proj1')
|
||||||
@@ -69,6 +70,7 @@ class DirectTestCase(test.TestCase):
|
|||||||
req.method = 'POST'
|
req.method = 'POST'
|
||||||
req.body = 'json=%s' % json.dumps({'data': 'foo'})
|
req.body = 'json=%s' % json.dumps({'data': 'foo'})
|
||||||
resp = req.get_response(self.router)
|
resp = req.get_response(self.router)
|
||||||
|
self.assertEqual(resp.status_int, 200)
|
||||||
resp_parsed = json.loads(resp.body)
|
resp_parsed = json.loads(resp.body)
|
||||||
self.assertEqual(resp_parsed['data'], 'foo')
|
self.assertEqual(resp_parsed['data'], 'foo')
|
||||||
|
|
||||||
@@ -78,6 +80,7 @@ class DirectTestCase(test.TestCase):
|
|||||||
req.method = 'POST'
|
req.method = 'POST'
|
||||||
req.body = 'data=foo'
|
req.body = 'data=foo'
|
||||||
resp = req.get_response(self.router)
|
resp = req.get_response(self.router)
|
||||||
|
self.assertEqual(resp.status_int, 200)
|
||||||
resp_parsed = json.loads(resp.body)
|
resp_parsed = json.loads(resp.body)
|
||||||
self.assertEqual(resp_parsed['data'], 'foo')
|
self.assertEqual(resp_parsed['data'], 'foo')
|
||||||
|
|
||||||
|
|||||||
@@ -71,30 +71,33 @@ class LockTestCase(test.TestCase):
|
|||||||
"got mangled")
|
"got mangled")
|
||||||
|
|
||||||
def test_synchronized(self):
|
def test_synchronized(self):
|
||||||
rpipe, wpipe = os.pipe()
|
rpipe1, wpipe1 = os.pipe()
|
||||||
pid = os.fork()
|
rpipe2, wpipe2 = os.pipe()
|
||||||
if pid > 0:
|
|
||||||
os.close(wpipe)
|
|
||||||
|
|
||||||
@synchronized('testlock')
|
@synchronized('testlock')
|
||||||
def f():
|
def f(rpipe, wpipe):
|
||||||
rfds, _, __ = select.select([rpipe], [], [], 1)
|
try:
|
||||||
self.assertEquals(len(rfds), 0, "The other process, which was"
|
os.write(wpipe, "foo")
|
||||||
" supposed to be locked, "
|
except OSError, e:
|
||||||
"wrote on its end of the "
|
self.assertEquals(e.errno, errno.EPIPE)
|
||||||
"pipe")
|
return
|
||||||
os.close(rpipe)
|
|
||||||
|
|
||||||
f()
|
rfds, _, __ = select.select([rpipe], [], [], 1)
|
||||||
else:
|
self.assertEquals(len(rfds), 0, "The other process, which was"
|
||||||
|
" supposed to be locked, "
|
||||||
|
"wrote on its end of the "
|
||||||
|
"pipe")
|
||||||
os.close(rpipe)
|
os.close(rpipe)
|
||||||
|
|
||||||
@synchronized('testlock')
|
pid = os.fork()
|
||||||
def g():
|
if pid > 0:
|
||||||
try:
|
os.close(wpipe1)
|
||||||
os.write(wpipe, "foo")
|
os.close(rpipe2)
|
||||||
except OSError, e:
|
|
||||||
self.assertEquals(e.errno, errno.EPIPE)
|
f(rpipe1, wpipe2)
|
||||||
return
|
else:
|
||||||
g()
|
os.close(rpipe1)
|
||||||
|
os.close(wpipe2)
|
||||||
|
|
||||||
|
f(rpipe2, wpipe1)
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|||||||
@@ -485,13 +485,13 @@ def lease_ip(private_ip):
|
|||||||
private_ip)
|
private_ip)
|
||||||
instance_ref = db.fixed_ip_get_instance(context.get_admin_context(),
|
instance_ref = db.fixed_ip_get_instance(context.get_admin_context(),
|
||||||
private_ip)
|
private_ip)
|
||||||
cmd = "%s add %s %s fake" % (binpath('nova-dhcpbridge'),
|
cmd = (binpath('nova-dhcpbridge'), 'add',
|
||||||
instance_ref['mac_address'],
|
instance_ref['mac_address'],
|
||||||
private_ip)
|
private_ip, 'fake')
|
||||||
env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
|
env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
|
||||||
'TESTING': '1',
|
'TESTING': '1',
|
||||||
'FLAGFILE': FLAGS.dhcpbridge_flagfile}
|
'FLAGFILE': FLAGS.dhcpbridge_flagfile}
|
||||||
(out, err) = utils.execute(cmd, addl_env=env)
|
(out, err) = utils.execute(*cmd, addl_env=env)
|
||||||
LOG.debug("ISSUE_IP: %s, %s ", out, err)
|
LOG.debug("ISSUE_IP: %s, %s ", out, err)
|
||||||
|
|
||||||
|
|
||||||
@@ -501,11 +501,11 @@ def release_ip(private_ip):
|
|||||||
private_ip)
|
private_ip)
|
||||||
instance_ref = db.fixed_ip_get_instance(context.get_admin_context(),
|
instance_ref = db.fixed_ip_get_instance(context.get_admin_context(),
|
||||||
private_ip)
|
private_ip)
|
||||||
cmd = "%s del %s %s fake" % (binpath('nova-dhcpbridge'),
|
cmd = (binpath('nova-dhcpbridge'), 'del',
|
||||||
instance_ref['mac_address'],
|
instance_ref['mac_address'],
|
||||||
private_ip)
|
private_ip, 'fake')
|
||||||
env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
|
env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
|
||||||
'TESTING': '1',
|
'TESTING': '1',
|
||||||
'FLAGFILE': FLAGS.dhcpbridge_flagfile}
|
'FLAGFILE': FLAGS.dhcpbridge_flagfile}
|
||||||
(out, err) = utils.execute(cmd, addl_env=env)
|
(out, err) = utils.execute(*cmd, addl_env=env)
|
||||||
LOG.debug("RELEASE_IP: %s, %s ", out, err)
|
LOG.debug("RELEASE_IP: %s, %s ", out, err)
|
||||||
|
|||||||
@@ -322,23 +322,25 @@ class IptablesFirewallTestCase(test.TestCase):
|
|||||||
instance_ref = db.instance_get(admin_ctxt, instance_ref['id'])
|
instance_ref = db.instance_get(admin_ctxt, instance_ref['id'])
|
||||||
|
|
||||||
# self.fw.add_instance(instance_ref)
|
# self.fw.add_instance(instance_ref)
|
||||||
def fake_iptables_execute(cmd, process_input=None, attempts=5):
|
def fake_iptables_execute(*cmd, **kwargs):
|
||||||
if cmd == 'sudo ip6tables-save -t filter':
|
process_input = kwargs.get('process_input', None)
|
||||||
|
if cmd == ('sudo', 'ip6tables-save', '-t', 'filter'):
|
||||||
return '\n'.join(self.in6_filter_rules), None
|
return '\n'.join(self.in6_filter_rules), None
|
||||||
if cmd == 'sudo iptables-save -t filter':
|
if cmd == ('sudo', 'iptables-save', '-t', 'filter'):
|
||||||
return '\n'.join(self.in_filter_rules), None
|
return '\n'.join(self.in_filter_rules), None
|
||||||
if cmd == 'sudo iptables-save -t nat':
|
if cmd == ('sudo', 'iptables-save', '-t', 'nat'):
|
||||||
return '\n'.join(self.in_nat_rules), None
|
return '\n'.join(self.in_nat_rules), None
|
||||||
if cmd == 'sudo iptables-restore':
|
if cmd == ('sudo', 'iptables-restore'):
|
||||||
lines = process_input.split('\n')
|
lines = process_input.split('\n')
|
||||||
if '*filter' in lines:
|
if '*filter' in lines:
|
||||||
self.out_rules = lines
|
self.out_rules = lines
|
||||||
return '', ''
|
return '', ''
|
||||||
if cmd == 'sudo ip6tables-restore':
|
if cmd == ('sudo', 'ip6tables-restore'):
|
||||||
lines = process_input.split('\n')
|
lines = process_input.split('\n')
|
||||||
if '*filter' in lines:
|
if '*filter' in lines:
|
||||||
self.out6_rules = lines
|
self.out6_rules = lines
|
||||||
return '', ''
|
return '', ''
|
||||||
|
print cmd, kwargs
|
||||||
|
|
||||||
from nova.network import linux_net
|
from nova.network import linux_net
|
||||||
linux_net.iptables_manager.execute = fake_iptables_execute
|
linux_net.iptables_manager.execute = fake_iptables_execute
|
||||||
|
|||||||
@@ -346,6 +346,56 @@ class XenAPIDiffieHellmanTestCase(test.TestCase):
|
|||||||
super(XenAPIDiffieHellmanTestCase, self).tearDown()
|
super(XenAPIDiffieHellmanTestCase, self).tearDown()
|
||||||
|
|
||||||
|
|
||||||
|
class XenAPIMigrateInstance(test.TestCase):
|
||||||
|
"""
|
||||||
|
Unit test for verifying migration-related actions
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(XenAPIMigrateInstance, self).setUp()
|
||||||
|
self.stubs = stubout.StubOutForTesting()
|
||||||
|
FLAGS.target_host = '127.0.0.1'
|
||||||
|
FLAGS.xenapi_connection_url = 'test_url'
|
||||||
|
FLAGS.xenapi_connection_password = 'test_pass'
|
||||||
|
db_fakes.stub_out_db_instance_api(self.stubs)
|
||||||
|
stubs.stub_out_get_target(self.stubs)
|
||||||
|
xenapi_fake.reset()
|
||||||
|
self.manager = manager.AuthManager()
|
||||||
|
self.user = self.manager.create_user('fake', 'fake', 'fake',
|
||||||
|
admin=True)
|
||||||
|
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
||||||
|
self.values = {'name': 1, 'id': 1,
|
||||||
|
'project_id': self.project.id,
|
||||||
|
'user_id': self.user.id,
|
||||||
|
'image_id': 1,
|
||||||
|
'kernel_id': None,
|
||||||
|
'ramdisk_id': None,
|
||||||
|
'instance_type': 'm1.large',
|
||||||
|
'mac_address': 'aa:bb:cc:dd:ee:ff',
|
||||||
|
}
|
||||||
|
stubs.stub_out_migration_methods(self.stubs)
|
||||||
|
glance_stubs.stubout_glance_client(self.stubs,
|
||||||
|
glance_stubs.FakeGlance)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(XenAPIMigrateInstance, self).tearDown()
|
||||||
|
self.manager.delete_project(self.project)
|
||||||
|
self.manager.delete_user(self.user)
|
||||||
|
self.stubs.UnsetAll()
|
||||||
|
|
||||||
|
def test_migrate_disk_and_power_off(self):
|
||||||
|
instance = db.instance_create(self.values)
|
||||||
|
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
|
||||||
|
conn = xenapi_conn.get_connection(False)
|
||||||
|
conn.migrate_disk_and_power_off(instance, '127.0.0.1')
|
||||||
|
|
||||||
|
def test_finish_resize(self):
|
||||||
|
instance = db.instance_create(self.values)
|
||||||
|
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
|
||||||
|
conn = xenapi_conn.get_connection(False)
|
||||||
|
conn.finish_resize(instance, dict(base_copy='hurr', cow='durr'))
|
||||||
|
|
||||||
|
|
||||||
class XenAPIDetermineDiskImageTestCase(test.TestCase):
|
class XenAPIDetermineDiskImageTestCase(test.TestCase):
|
||||||
"""
|
"""
|
||||||
Unit tests for code that detects the ImageType
|
Unit tests for code that detects the ImageType
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from nova.virt import xenapi_conn
|
|||||||
from nova.virt.xenapi import fake
|
from nova.virt.xenapi import fake
|
||||||
from nova.virt.xenapi import volume_utils
|
from nova.virt.xenapi import volume_utils
|
||||||
from nova.virt.xenapi import vm_utils
|
from nova.virt.xenapi import vm_utils
|
||||||
|
from nova.virt.xenapi import vmops
|
||||||
|
|
||||||
|
|
||||||
def stubout_instance_snapshot(stubs):
|
def stubout_instance_snapshot(stubs):
|
||||||
@@ -217,3 +218,60 @@ class FakeSessionForVolumeFailedTests(FakeSessionForVolumeTests):
|
|||||||
|
|
||||||
def SR_forget(self, _1, ref):
|
def SR_forget(self, _1, ref):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class FakeSessionForMigrationTests(fake.SessionBase):
|
||||||
|
"""Stubs out a XenAPISession for Migration tests"""
|
||||||
|
def __init__(self, uri):
|
||||||
|
super(FakeSessionForMigrationTests, self).__init__(uri)
|
||||||
|
|
||||||
|
def VDI_get_by_uuid(*args):
|
||||||
|
return 'hurr'
|
||||||
|
|
||||||
|
def VM_start(self, _1, ref, _2, _3):
|
||||||
|
vm = fake.get_record('VM', ref)
|
||||||
|
if vm['power_state'] != 'Halted':
|
||||||
|
raise fake.Failure(['VM_BAD_POWER_STATE', ref, 'Halted',
|
||||||
|
vm['power_state']])
|
||||||
|
vm['power_state'] = 'Running'
|
||||||
|
vm['is_a_template'] = False
|
||||||
|
vm['is_control_domain'] = False
|
||||||
|
|
||||||
|
|
||||||
|
def stub_out_migration_methods(stubs):
|
||||||
|
def fake_get_snapshot(self, instance):
|
||||||
|
return 'foo', 'bar'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fake_get_vdi(cls, session, vm_ref):
|
||||||
|
vdi_ref = fake.create_vdi(name_label='derp', read_only=False,
|
||||||
|
sr_ref='herp', sharable=False)
|
||||||
|
vdi_rec = session.get_xenapi().VDI.get_record(vdi_ref)
|
||||||
|
return vdi_ref, {'uuid': vdi_rec['uuid'], }
|
||||||
|
|
||||||
|
def fake_shutdown(self, inst, vm, method='clean'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fake_sr(cls, session, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fake_get_sr_path(cls, *args):
|
||||||
|
return "fake"
|
||||||
|
|
||||||
|
def fake_destroy(*args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def fake_reset_network(*args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
stubs.Set(vmops.VMOps, '_destroy', fake_destroy)
|
||||||
|
stubs.Set(vm_utils.VMHelper, 'scan_default_sr', fake_sr)
|
||||||
|
stubs.Set(vm_utils.VMHelper, 'scan_sr', fake_sr)
|
||||||
|
stubs.Set(vmops.VMOps, '_get_snapshot', fake_get_snapshot)
|
||||||
|
stubs.Set(vm_utils.VMHelper, 'get_vdi_for_vm_safely', fake_get_vdi)
|
||||||
|
stubs.Set(xenapi_conn.XenAPISession, 'wait_for_task', lambda x, y, z: None)
|
||||||
|
stubs.Set(vm_utils.VMHelper, 'get_sr_path', fake_get_sr_path)
|
||||||
|
stubs.Set(vmops.VMOps, 'reset_network', fake_reset_network)
|
||||||
|
stubs.Set(vmops.VMOps, '_shutdown', fake_shutdown)
|
||||||
|
|||||||
Reference in New Issue
Block a user