Merge from trunk
This commit is contained in:
2
Authors
2
Authors
@@ -6,6 +6,7 @@ Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
|
|||||||
Chiradeep Vittal <chiradeep@cloud.com>
|
Chiradeep Vittal <chiradeep@cloud.com>
|
||||||
Chmouel Boudjnah <chmouel@chmouel.com>
|
Chmouel Boudjnah <chmouel@chmouel.com>
|
||||||
Chris Behrens <cbehrens@codestud.com>
|
Chris Behrens <cbehrens@codestud.com>
|
||||||
|
Christian Berendt <berendt@b1-systems.de>
|
||||||
Cory Wright <corywright@gmail.com>
|
Cory Wright <corywright@gmail.com>
|
||||||
David Pravec <David.Pravec@danix.org>
|
David Pravec <David.Pravec@danix.org>
|
||||||
Dan Prince <dan.prince@rackspace.com>
|
Dan Prince <dan.prince@rackspace.com>
|
||||||
@@ -41,6 +42,7 @@ MORITA Kazutaka <morita.kazutaka@gmail.com>
|
|||||||
Muneyuki Noguchi <noguchimn@nttdata.co.jp>
|
Muneyuki Noguchi <noguchimn@nttdata.co.jp>
|
||||||
Nachi Ueno <ueno.nachi@lab.ntt.co.jp> <openstack@lab.ntt.co.jp> <nati.ueno@gmail.com> <nova@u4>
|
Nachi Ueno <ueno.nachi@lab.ntt.co.jp> <openstack@lab.ntt.co.jp> <nati.ueno@gmail.com> <nova@u4>
|
||||||
Paul Voccio <paul@openstack.org>
|
Paul Voccio <paul@openstack.org>
|
||||||
|
Ricardo Carrillo Cruz <emaildericky@gmail.com>
|
||||||
Rick Clark <rick@openstack.org>
|
Rick Clark <rick@openstack.org>
|
||||||
Rick Harris <rconradharris@gmail.com>
|
Rick Harris <rconradharris@gmail.com>
|
||||||
Rob Kost <kost@isi.edu>
|
Rob Kost <kost@isi.edu>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ Nova User API client library.
|
|||||||
|
|
||||||
import base64
|
import base64
|
||||||
import boto
|
import boto
|
||||||
|
import boto.exception
|
||||||
import httplib
|
import httplib
|
||||||
|
|
||||||
from boto.ec2.regioninfo import RegionInfo
|
from boto.ec2.regioninfo import RegionInfo
|
||||||
@@ -288,10 +289,14 @@ class NovaAdminClient(object):
|
|||||||
|
|
||||||
def get_user(self, name):
|
def get_user(self, name):
|
||||||
"""Grab a single user by name."""
|
"""Grab a single user by name."""
|
||||||
user = self.apiconn.get_object('DescribeUser', {'Name': name},
|
try:
|
||||||
|
return self.apiconn.get_object('DescribeUser',
|
||||||
|
{'Name': name},
|
||||||
UserInfo)
|
UserInfo)
|
||||||
if user.username != None:
|
except boto.exception.BotoServerError, e:
|
||||||
return user
|
if e.status == 400 and e.error_code == 'NotFound':
|
||||||
|
return None
|
||||||
|
raise
|
||||||
|
|
||||||
def has_user(self, username):
|
def has_user(self, username):
|
||||||
"""Determine if user exists."""
|
"""Determine if user exists."""
|
||||||
@@ -376,6 +381,13 @@ class NovaAdminClient(object):
|
|||||||
'MemberUsers': member_users}
|
'MemberUsers': member_users}
|
||||||
return self.apiconn.get_object('RegisterProject', params, ProjectInfo)
|
return self.apiconn.get_object('RegisterProject', params, ProjectInfo)
|
||||||
|
|
||||||
|
def modify_project(self, projectname, manager_user=None, description=None):
|
||||||
|
"""Modifies an existing project."""
|
||||||
|
params = {'Name': projectname,
|
||||||
|
'ManagerUser': manager_user,
|
||||||
|
'Description': description}
|
||||||
|
return self.apiconn.get_status('ModifyProject', params)
|
||||||
|
|
||||||
def delete_project(self, projectname):
|
def delete_project(self, projectname):
|
||||||
"""Permanently deletes the specified project."""
|
"""Permanently deletes the specified project."""
|
||||||
return self.apiconn.get_object('DeregisterProject',
|
return self.apiconn.get_object('DeregisterProject',
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import cStringIO
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from nova import flags
|
from nova import flags
|
||||||
@@ -191,6 +192,12 @@ class NovaLogger(logging.Logger):
|
|||||||
kwargs.pop('exc_info')
|
kwargs.pop('exc_info')
|
||||||
self.error(message, **kwargs)
|
self.error(message, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def handle_exception(type, value, tb):
|
||||||
|
logging.root.critical(str(value), exc_info=(type, value, tb))
|
||||||
|
|
||||||
|
|
||||||
|
sys.excepthook = handle_exception
|
||||||
logging.setLoggerClass(NovaLogger)
|
logging.setLoggerClass(NovaLogger)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ class SimpleScheduler(chance.ChanceScheduler):
|
|||||||
def schedule_run_instance(self, context, instance_id, *_args, **_kwargs):
|
def schedule_run_instance(self, context, instance_id, *_args, **_kwargs):
|
||||||
"""Picks a host that is up and has the fewest running instances."""
|
"""Picks a host that is up and has the fewest running instances."""
|
||||||
instance_ref = db.instance_get(context, instance_id)
|
instance_ref = db.instance_get(context, instance_id)
|
||||||
if instance_ref['availability_zone'] and context.is_admin:
|
if (instance_ref['availability_zone']
|
||||||
|
and ':' in instance_ref['availability_zone']
|
||||||
|
and context.is_admin):
|
||||||
zone, _x, host = instance_ref['availability_zone'].partition(':')
|
zone, _x, host = instance_ref['availability_zone'].partition(':')
|
||||||
service = db.service_get_by_args(context.elevated(), host,
|
service = db.service_get_by_args(context.elevated(), host,
|
||||||
'nova-compute')
|
'nova-compute')
|
||||||
@@ -75,7 +77,9 @@ class SimpleScheduler(chance.ChanceScheduler):
|
|||||||
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs):
|
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs):
|
||||||
"""Picks a host that is up and has the fewest volumes."""
|
"""Picks a host that is up and has the fewest volumes."""
|
||||||
volume_ref = db.volume_get(context, volume_id)
|
volume_ref = db.volume_get(context, volume_id)
|
||||||
if (':' in volume_ref['availability_zone']) and context.is_admin:
|
if (volume_ref['availability_zone']
|
||||||
|
and ':' in volume_ref['availability_zone']
|
||||||
|
and context.is_admin):
|
||||||
zone, _x, host = volume_ref['availability_zone'].partition(':')
|
zone, _x, host = volume_ref['availability_zone'].partition(':')
|
||||||
service = db.service_get_by_args(context.elevated(), host,
|
service = db.service_get_by_args(context.elevated(), host,
|
||||||
'nova-volume')
|
'nova-volume')
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class ComputeTestCase(test.TestCase):
|
|||||||
self.manager = manager.AuthManager()
|
self.manager = manager.AuthManager()
|
||||||
self.user = self.manager.create_user('fake', 'fake', 'fake')
|
self.user = self.manager.create_user('fake', 'fake', 'fake')
|
||||||
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
||||||
self.context = context.get_admin_context()
|
self.context = context.RequestContext('fake', 'fake', False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.manager.delete_user(self.user)
|
self.manager.delete_user(self.user)
|
||||||
@@ -69,6 +69,13 @@ class ComputeTestCase(test.TestCase):
|
|||||||
inst['ami_launch_index'] = 0
|
inst['ami_launch_index'] = 0
|
||||||
return db.instance_create(self.context, inst)['id']
|
return db.instance_create(self.context, inst)['id']
|
||||||
|
|
||||||
|
def _create_group(self):
|
||||||
|
values = {'name': 'testgroup',
|
||||||
|
'description': 'testgroup',
|
||||||
|
'user_id': self.user.id,
|
||||||
|
'project_id': self.project.id}
|
||||||
|
return db.security_group_create(self.context, values)
|
||||||
|
|
||||||
def test_create_instance_defaults_display_name(self):
|
def test_create_instance_defaults_display_name(self):
|
||||||
"""Verify that an instance cannot be created without a display_name."""
|
"""Verify that an instance cannot be created without a display_name."""
|
||||||
cases = [dict(), dict(display_name=None)]
|
cases = [dict(), dict(display_name=None)]
|
||||||
@@ -82,23 +89,55 @@ class ComputeTestCase(test.TestCase):
|
|||||||
|
|
||||||
def test_create_instance_associates_security_groups(self):
|
def test_create_instance_associates_security_groups(self):
|
||||||
"""Make sure create associates security groups"""
|
"""Make sure create associates security groups"""
|
||||||
values = {'name': 'default',
|
group = self._create_group()
|
||||||
'description': 'default',
|
|
||||||
'user_id': self.user.id,
|
|
||||||
'project_id': self.project.id}
|
|
||||||
group = db.security_group_create(self.context, values)
|
|
||||||
ref = self.compute_api.create(
|
ref = self.compute_api.create(
|
||||||
self.context,
|
self.context,
|
||||||
instance_type=FLAGS.default_instance_type,
|
instance_type=FLAGS.default_instance_type,
|
||||||
image_id=None,
|
image_id=None,
|
||||||
security_group=['default'])
|
security_group=['testgroup'])
|
||||||
try:
|
try:
|
||||||
self.assertEqual(len(db.security_group_get_by_instance(
|
self.assertEqual(len(db.security_group_get_by_instance(
|
||||||
self.context, ref[0]['id'])), 1)
|
self.context, ref[0]['id'])), 1)
|
||||||
|
group = db.security_group_get(self.context, group['id'])
|
||||||
|
self.assert_(len(group.instances) == 1)
|
||||||
finally:
|
finally:
|
||||||
db.security_group_destroy(self.context, group['id'])
|
db.security_group_destroy(self.context, group['id'])
|
||||||
db.instance_destroy(self.context, ref[0]['id'])
|
db.instance_destroy(self.context, ref[0]['id'])
|
||||||
|
|
||||||
|
def test_destroy_instance_disassociates_security_groups(self):
|
||||||
|
"""Make sure destroying disassociates security groups"""
|
||||||
|
group = self._create_group()
|
||||||
|
|
||||||
|
ref = self.compute_api.create(
|
||||||
|
self.context,
|
||||||
|
instance_type=FLAGS.default_instance_type,
|
||||||
|
image_id=None,
|
||||||
|
security_group=['testgroup'])
|
||||||
|
try:
|
||||||
|
db.instance_destroy(self.context, ref[0]['id'])
|
||||||
|
group = db.security_group_get(self.context, group['id'])
|
||||||
|
self.assert_(len(group.instances) == 0)
|
||||||
|
finally:
|
||||||
|
db.security_group_destroy(self.context, group['id'])
|
||||||
|
|
||||||
|
def test_destroy_security_group_disassociates_instances(self):
|
||||||
|
"""Make sure destroying security groups disassociates instances"""
|
||||||
|
group = self._create_group()
|
||||||
|
|
||||||
|
ref = self.compute_api.create(
|
||||||
|
self.context,
|
||||||
|
instance_type=FLAGS.default_instance_type,
|
||||||
|
image_id=None,
|
||||||
|
security_group=['testgroup'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
db.security_group_destroy(self.context, group['id'])
|
||||||
|
group = db.security_group_get(context.get_admin_context(
|
||||||
|
read_deleted=True), group['id'])
|
||||||
|
self.assert_(len(group.instances) == 0)
|
||||||
|
finally:
|
||||||
|
db.instance_destroy(self.context, ref[0]['id'])
|
||||||
|
|
||||||
def test_run_terminate(self):
|
def test_run_terminate(self):
|
||||||
"""Make sure it is possible to run and terminate instance"""
|
"""Make sure it is possible to run and terminate instance"""
|
||||||
instance_id = self._create_instance()
|
instance_id = self._create_instance()
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ from nose import config
|
|||||||
from nose import result
|
from nose import result
|
||||||
from nose import core
|
from nose import core
|
||||||
|
|
||||||
|
from nova import log as logging
|
||||||
|
|
||||||
|
|
||||||
class NovaTestResult(result.TextTestResult):
|
class NovaTestResult(result.TextTestResult):
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
@@ -58,6 +60,7 @@ class NovaTestRunner(core.TextTestRunner):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
logging.basicConfig()
|
||||||
c = config.Config(stream=sys.stdout,
|
c = config.Config(stream=sys.stdout,
|
||||||
env=os.environ,
|
env=os.environ,
|
||||||
verbosity=3,
|
verbosity=3,
|
||||||
|
|||||||
Reference in New Issue
Block a user