summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorRicardo Carrillo Cruz <emaildericky@gmail.com>2011-02-04 11:26:28 +0100
committerRicardo Carrillo Cruz <emaildericky@gmail.com>2011-02-04 11:26:28 +0100
commite35ca46173a5f3bf2d1460c19249fd0bf9f5b538 (patch)
tree39eed216f35ae38d239e68ceec79ac1411110bd3 /nova
parent3ad22216eee67abfabb28efe2561f0fdcf10e6e1 (diff)
parent5e4259ce6deb227b778acf23770e35f786c9c3d0 (diff)
downloadnova-e35ca46173a5f3bf2d1460c19249fd0bf9f5b538.tar.gz
nova-e35ca46173a5f3bf2d1460c19249fd0bf9f5b538.tar.xz
nova-e35ca46173a5f3bf2d1460c19249fd0bf9f5b538.zip
Fixed PEP8 test problems, complaining about too many blank lines at line 51
Diffstat (limited to 'nova')
-rw-r--r--nova/adminclient.py44
-rw-r--r--nova/api/ec2/__init__.py18
-rw-r--r--nova/api/ec2/admin.py13
-rw-r--r--nova/api/ec2/cloud.py28
-rw-r--r--nova/api/openstack/__init__.py3
-rw-r--r--nova/api/openstack/servers.py28
-rw-r--r--nova/auth/ldapdriver.py7
-rw-r--r--nova/compute/manager.py2
-rw-r--r--nova/db/api.py6
-rw-r--r--nova/db/sqlalchemy/api.py13
-rw-r--r--nova/db/sqlalchemy/session.py3
-rw-r--r--nova/exception.py18
-rw-r--r--nova/network/manager.py5
-rw-r--r--nova/tests/test_virt.py2
-rw-r--r--nova/virt/fake.py5
-rw-r--r--nova/virt/hyperv.py2
-rw-r--r--nova/virt/libvirt_conn.py55
-rw-r--r--nova/virt/xenapi_conn.py2
-rw-r--r--nova/volume/api.py1
19 files changed, 207 insertions, 48 deletions
diff --git a/nova/adminclient.py b/nova/adminclient.py
index b2609c8c4..3cdd8347f 100644
--- a/nova/adminclient.py
+++ b/nova/adminclient.py
@@ -190,6 +190,45 @@ class HostInfo(object):
setattr(self, name, value)
+class InstanceType(object):
+ """
+ Information about a Nova instance type, as parsed through SAX.
+
+ **Fields include**
+
+ * name
+ * vcpus
+ * disk_gb
+ * memory_mb
+ * flavor_id
+
+ """
+
+ def __init__(self, connection=None):
+ self.connection = connection
+ self.name = None
+ self.vcpus = None
+ self.disk_gb = None
+ self.memory_mb = None
+ self.flavor_id = None
+
+ def __repr__(self):
+ return 'InstanceType:%s' % self.name
+
+ def startElement(self, name, attrs, connection):
+ return None
+
+ def endElement(self, name, value, connection):
+ if name == "memoryMb":
+ self.memory_mb = str(value)
+ elif name == "flavorId":
+ self.flavor_id = str(value)
+ elif name == "diskGb":
+ self.disk_gb = str(value)
+ else:
+ setattr(self, name, str(value))
+
+
class NovaAdminClient(object):
def __init__(
@@ -373,3 +412,8 @@ class NovaAdminClient(object):
def get_hosts(self):
return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)])
+
+ def get_instance_types(self):
+ """Grabs the list of all users."""
+ return self.apiconn.get_list('DescribeInstanceTypes', {},
+ [('item', InstanceType)])
diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py
index 9938b23f8..fc9a37908 100644
--- a/nova/api/ec2/__init__.py
+++ b/nova/api/ec2/__init__.py
@@ -170,7 +170,7 @@ class Authenticate(wsgi.Middleware):
req.path)
# Be explicit for what exceptions are 403, the rest bubble as 500
except (exception.NotFound, exception.NotAuthorized) as ex:
- LOG.audit(_("Authentication Failure: %s"), str(ex))
+ LOG.audit(_("Authentication Failure: %s"), ex.args[0])
raise webob.exc.HTTPForbidden()
# Authenticated!
@@ -314,17 +314,18 @@ class Executor(wsgi.Application):
try:
result = api_request.invoke(context)
except exception.NotFound as ex:
- LOG.info(_('NotFound raised: %s'), str(ex), context=context)
- return self._error(req, context, type(ex).__name__, str(ex))
+ LOG.info(_('NotFound raised: %s'), ex.args[0], context=context)
+ return self._error(req, context, type(ex).__name__, ex.args[0])
except exception.ApiError as ex:
- LOG.exception(_('ApiError raised: %s'), str(ex), context=context)
+ LOG.exception(_('ApiError raised: %s'), ex.args[0],
+ context=context)
if ex.code:
- return self._error(req, context, ex.code, str(ex))
+ return self._error(req, context, ex.code, ex.args[0])
else:
- return self._error(req, context, type(ex).__name__, str(ex))
+ return self._error(req, context, type(ex).__name__, ex.args[0])
except Exception as ex:
extra = {'environment': req.environ}
- LOG.exception(_('Unexpected error raised: %s'), str(ex),
+ LOG.exception(_('Unexpected error raised: %s'), ex.args[0],
extra=extra, context=context)
return self._error(req,
context,
@@ -347,7 +348,8 @@ class Executor(wsgi.Application):
'<Response><Errors><Error><Code>%s</Code>'
'<Message>%s</Message></Error></Errors>'
'<RequestID>%s</RequestID></Response>' %
- (code, message, context.request_id))
+ (utils.utf8(code), utils.utf8(message),
+ utils.utf8(context.request_id)))
return resp
diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py
index 78ff1b3e0..d7e899d12 100644
--- a/nova/api/ec2/admin.py
+++ b/nova/api/ec2/admin.py
@@ -26,6 +26,7 @@ from nova import db
from nova import exception
from nova import log as logging
from nova.auth import manager
+from nova.compute import instance_types
LOG = logging.getLogger('nova.api.ec2.admin')
@@ -62,6 +63,14 @@ def host_dict(host):
return {}
+def instance_dict(name, inst):
+ return {'name': name,
+ 'memory_mb': inst['memory_mb'],
+ 'vcpus': inst['vcpus'],
+ 'disk_gb': inst['local_gb'],
+ 'flavor_id': inst['flavorid']}
+
+
class AdminController(object):
"""
API Controller for users, hosts, nodes, and workers.
@@ -70,6 +79,10 @@ class AdminController(object):
def __str__(self):
return 'AdminController'
+ def describe_instance_types(self, _context, **_kwargs):
+ return {'instanceTypeSet': [instance_dict(n, v) for n, v in
+ instance_types.INSTANCE_TYPES.iteritems()]}
+
def describe_user(self, _context, name, **_kwargs):
"""Returns user data, including access and secret keys."""
return user_dict(manager.AuthManager().get_user(name))
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 3b228bf1a..22b8c19cb 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -529,11 +529,18 @@ class CloudController(object):
def describe_volumes(self, context, volume_id=None, **kwargs):
if volume_id:
- volume_id = [ec2_id_to_id(x) for x in volume_id]
- volumes = self.volume_api.get_all(context)
- # NOTE(vish): volume_id is an optional list of volume ids to filter by.
- volumes = [self._format_volume(context, v) for v in volumes
- if volume_id is None or v['id'] in volume_id]
+ volumes = []
+ for ec2_id in volume_id:
+ internal_id = ec2_id_to_id(ec2_id)
+ try:
+ volume = self.volume_api.get(context, internal_id)
+ volumes.append(volume)
+ except exception.NotFound:
+ raise exception.NotFound(_("Volume %s not found")
+ % ec2_id)
+ else:
+ volumes = self.volume_api.get_all(context)
+ volumes = [self._format_volume(context, v) for v in volumes]
return {'volumeSet': volumes}
def _format_volume(self, context, volume):
@@ -658,8 +665,15 @@ class CloudController(object):
reservations = {}
# NOTE(vish): instance_id is an optional list of ids to filter by
if instance_id:
- instance_id = [ec2_id_to_id(x) for x in instance_id]
- instances = [self.compute_api.get(context, x) for x in instance_id]
+ instances = []
+ for ec2_id in instance_id:
+ internal_id = ec2_id_to_id(ec2_id)
+ try:
+ instance = self.compute_api.get(context, internal_id)
+ instances.append(instance)
+ except exception.NotFound:
+ raise exception.NotFound(_("Instance %s not found")
+ % ec2_id)
else:
instances = self.compute_api.get_all(context, **kwargs)
for instance in instances:
diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py
index f2caac483..c70bb39ed 100644
--- a/nova/api/openstack/__init__.py
+++ b/nova/api/openstack/__init__.py
@@ -38,9 +38,6 @@ from nova.api.openstack import shared_ip_groups
LOG = logging.getLogger('nova.api.openstack')
FLAGS = flags.FLAGS
-flags.DEFINE_string('os_krm_mapping_file',
- 'krm_mapping.json',
- 'Location of OpenStack Flavor/OS:EC2 Kernel/Ramdisk/Machine JSON file.')
flags.DEFINE_bool('allow_admin_api',
False,
'When True, this API service will accept admin operations.')
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 22b4797c9..9d308ea24 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -124,17 +124,22 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPNotFound())
return exc.HTTPAccepted()
- def _get_kernel_ramdisk_from_image(self, image_id):
- mapping_filename = FLAGS.os_krm_mapping_file
-
- with open(mapping_filename) as f:
- mapping = json.load(f)
- if image_id in mapping:
- return mapping[image_id]
+ def _get_kernel_ramdisk_from_image(self, req, image_id):
+ """
+ Machine images are associated with Kernels and Ramdisk images via
+ metadata stored in Glance as 'image_properties'
+ """
+ def lookup(param):
+ _image_id = image_id
+ try:
+ return image['properties'][param]
+ except KeyError:
+ raise exception.NotFound(
+ _("%(param)s property not found for image %(_image_id)s") %
+ locals())
- msg = _("No entry for image '%(image_id)s'"
- " in mapping file '%(mapping_filename)s'") % locals()
- raise exception.NotFound(msg)
+ image = self._image_service.show(req.environ['nova.context'], image_id)
+ return lookup('kernel_id'), lookup('ramdisk_id')
def create(self, req):
""" Creates a new server for a given user """
@@ -146,7 +151,8 @@ class Controller(wsgi.Controller):
req.environ['nova.context'])[0]
image_id = common.get_image_id_from_image_hash(self._image_service,
req.environ['nova.context'], env['server']['imageId'])
- kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image(image_id)
+ kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image(
+ req, image_id)
instances = self.compute_api.create(
req.environ['nova.context'],
instance_types.get_by_flavor_id(env['server']['flavorId']),
diff --git a/nova/auth/ldapdriver.py b/nova/auth/ldapdriver.py
index 342fa40ac..e652f1caa 100644
--- a/nova/auth/ldapdriver.py
+++ b/nova/auth/ldapdriver.py
@@ -585,10 +585,11 @@ class LdapDriver(object):
else:
return None
- @staticmethod
- def __dn_to_uid(dn):
+ def __dn_to_uid(self, dn):
"""Convert user dn to uid"""
- return dn.split(',')[0].split('=')[1]
+ query = '(objectclass=novaUser)'
+ user = self.__find_object(dn, query)
+ return user[FLAGS.ldap_user_id_attribute][0]
class FakeLdapDriver(LdapDriver):
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 376b1ed68..0f9bf301f 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -118,7 +118,7 @@ class ComputeManager(manager.Manager):
"""Do any initialization that needs to be run if this is a
standalone service.
"""
- self.driver.init_host()
+ self.driver.init_host(host=self.host)
def _update_state(self, context, instance_id):
"""Update the state of an instance from the driver info."""
diff --git a/nova/db/api.py b/nova/db/api.py
index f9d561587..c6c03fb0e 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -71,7 +71,6 @@ class NoMoreTargets(exception.Error):
"""No more available blades"""
pass
-
###################
@@ -351,6 +350,11 @@ def instance_get_all_by_project(context, project_id):
return IMPL.instance_get_all_by_project(context, project_id)
+def instance_get_all_by_host(context, host):
+ """Get all instance belonging to a host."""
+ return IMPL.instance_get_all_by_host(context, host)
+
+
def instance_get_all_by_reservation(context, reservation_id):
"""Get all instance belonging to a reservation."""
return IMPL.instance_get_all_by_reservation(context, reservation_id)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 370ca651a..fa060228f 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -724,6 +724,17 @@ def instance_get_all_by_user(context, user_id):
all()
+@require_admin_context
+def instance_get_all_by_host(context, host):
+ session = get_session()
+ return session.query(models.Instance).\
+ options(joinedload_all('fixed_ip.floating_ips')).\
+ options(joinedload('security_groups')).\
+ filter_by(host=host).\
+ filter_by(deleted=can_read_deleted(context)).\
+ all()
+
+
@require_context
def instance_get_all_by_project(context, project_id):
authorize_project_context(context, project_id)
@@ -1396,11 +1407,13 @@ def volume_get(context, volume_id, session=None):
if is_admin_context(context):
result = session.query(models.Volume).\
+ options(joinedload('instance')).\
filter_by(id=volume_id).\
filter_by(deleted=can_read_deleted(context)).\
first()
elif is_user_context(context):
result = session.query(models.Volume).\
+ options(joinedload('instance')).\
filter_by(project_id=context.project_id).\
filter_by(id=volume_id).\
filter_by(deleted=False).\
diff --git a/nova/db/sqlalchemy/session.py b/nova/db/sqlalchemy/session.py
index c3876c02a..dc885f138 100644
--- a/nova/db/sqlalchemy/session.py
+++ b/nova/db/sqlalchemy/session.py
@@ -22,6 +22,7 @@ Session Handling for SQLAlchemy backend
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
+from nova import exception
from nova import flags
FLAGS = flags.FLAGS
@@ -43,4 +44,6 @@ def get_session(autocommit=True, expire_on_commit=False):
autocommit=autocommit,
expire_on_commit=expire_on_commit))
session = _MAKER()
+ session.query = exception.wrap_db_error(session.query)
+ session.flush = exception.wrap_db_error(session.flush)
return session
diff --git a/nova/exception.py b/nova/exception.py
index 2320e2214..f604fd63a 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -81,6 +81,24 @@ class TimeoutException(Error):
pass
+class DBError(Error):
+ """Wraps an implementation specific exception"""
+ def __init__(self, inner_exception):
+ self.inner_exception = inner_exception
+ super(DBError, self).__init__(str(inner_exception))
+
+
+def wrap_db_error(f):
+ def _wrap(*args, **kwargs):
+ try:
+ return f(*args, **kwargs)
+ except Exception, e:
+ LOG.exception(_('DB exception wrapped'))
+ raise DBError(e)
+ return _wrap
+ _wrap.func_name = f.func_name
+
+
def wrap_exception(f):
def _wrap(*args, **kw):
try:
diff --git a/nova/network/manager.py b/nova/network/manager.py
index 14a424a5b..fe99f2612 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -83,7 +83,7 @@ flags.DEFINE_string('floating_range', '4.4.4.0/24',
'Floating IP address block')
flags.DEFINE_string('fixed_range', '10.0.0.0/8', 'Fixed IP address block')
flags.DEFINE_string('fixed_range_v6', 'fd00::/48', 'Fixed IPv6 address block')
-flags.DEFINE_integer('cnt_vpn_clients', 5,
+flags.DEFINE_integer('cnt_vpn_clients', 0,
'Number of addresses reserved for vpn clients')
flags.DEFINE_string('network_driver', 'nova.network.linux_net',
'Driver to use for network creation')
@@ -395,6 +395,7 @@ class FlatDHCPManager(FlatManager):
standalone service.
"""
super(FlatDHCPManager, self).init_host()
+ self.driver.init_host()
self.driver.metadata_forward()
def setup_compute_network(self, context, instance_id):
@@ -460,8 +461,8 @@ class VlanManager(NetworkManager):
standalone service.
"""
super(VlanManager, self).init_host()
- self.driver.metadata_forward()
self.driver.init_host()
+ self.driver.metadata_forward()
def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
"""Gets a fixed ip from the pool."""
diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py
index f6800e3d9..0b9b847a0 100644
--- a/nova/tests/test_virt.py
+++ b/nova/tests/test_virt.py
@@ -256,7 +256,7 @@ class IptablesFirewallTestCase(test.TestCase):
':FORWARD ACCEPT [0:0]',
':OUTPUT ACCEPT [349256:75777230]',
'COMMIT',
- '# Completed on Tue Jan 18 23:47:56 2011'
+ '# Completed on Tue Jan 18 23:47:56 2011',
]
def test_static_filters(self):
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index f8b3c7807..161445b86 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -76,9 +76,10 @@ class FakeConnection(object):
cls._instance = cls()
return cls._instance
- def init_host(self):
+ def init_host(self, host):
"""
- Initialize anything that is necessary for the driver to function
+ Initialize anything that is necessary for the driver to function,
+ including catching up with currently running VM's on the given host.
"""
return
diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py
index 5facb7aff..5afa3221d 100644
--- a/nova/virt/hyperv.py
+++ b/nova/virt/hyperv.py
@@ -113,7 +113,7 @@ class HyperVConnection(object):
self._conn = wmi.WMI(moniker='//./root/virtualization')
self._cim_conn = wmi.WMI(moniker='//./root/cimv2')
- def init_host(self):
+ def init_host(self, host):
#FIXME(chiradeep): implement this
LOG.debug(_('In init host'))
pass
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 259e19a69..bd5c9c4ee 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -157,8 +157,31 @@ class LibvirtConnection(object):
else:
self.firewall_driver = utils.import_object(FLAGS.firewall_driver)
- def init_host(self):
- pass
+ def init_host(self, host):
+ # Adopt existing VM's running here
+ ctxt = context.get_admin_context()
+ for instance in db.instance_get_all_by_host(ctxt, host):
+ try:
+ LOG.debug(_('Checking state of %s'), instance['name'])
+ state = self.get_info(instance['name'])['state']
+ except exception.NotFound:
+ state = power_state.SHUTOFF
+
+ LOG.debug(_('Current state of %(name)s was %(state)s.'),
+ {'name': instance['name'], 'state': state})
+ db.instance_set_state(ctxt, instance['id'], state)
+
+ if state == power_state.SHUTOFF:
+ # TODO(soren): This is what the compute manager does when you
+ # terminate # an instance. At some point I figure we'll have a
+ # "terminated" state and some sort of cleanup job that runs
+ # occasionally, cleaning them out.
+ db.instance_destroy(ctxt, instance['id'])
+
+ if state != power_state.RUNNING:
+ continue
+ self.firewall_driver.prepare_instance_filter(instance)
+ self.firewall_driver.apply_instance_filter(instance)
def _get_connection(self):
if not self._wrapped_conn or not self._test_connection():
@@ -1228,6 +1251,7 @@ class IptablesFirewallDriver(FirewallDriver):
our_chains += [':nova-local - [0:0]']
our_rules += ['-A FORWARD -j nova-local']
+ our_rules += ['-A OUTPUT -j nova-local']
security_groups = {}
# Add our chains
@@ -1268,13 +1292,22 @@ class IptablesFirewallDriver(FirewallDriver):
if(ip_version == 4):
# Allow DHCP responses
dhcp_server = self._dhcp_server_for_instance(instance)
- our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68' %
- (chain_name, dhcp_server)]
+ our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68 '
+ '-j ACCEPT ' % (chain_name, dhcp_server)]
+ #Allow project network traffic
+ if (FLAGS.allow_project_net_traffic):
+ cidr = self._project_cidr_for_instance(instance)
+ our_rules += ['-A %s -s %s -j ACCEPT' % (chain_name, cidr)]
elif(ip_version == 6):
# Allow RA responses
ra_server = self._ra_server_for_instance(instance)
- our_rules += ['-A %s -s %s -p icmpv6' %
- (chain_name, ra_server)]
+ our_rules += ['-A %s -s %s -p icmpv6 '
+ '-j ACCEPT' % (chain_name, ra_server)]
+ #Allow project network traffic
+ if (FLAGS.allow_project_net_traffic):
+ cidrv6 = self._project_cidrv6_for_instance(instance)
+ our_rules += ['-A %s -s %s -j ACCEPT' %
+ (chain_name, cidrv6)]
# If nothing matches, jump to the fallback chain
our_rules += ['-A %s -j nova-fallback' % (chain_name,)]
@@ -1369,3 +1402,13 @@ class IptablesFirewallDriver(FirewallDriver):
network = db.network_get_by_instance(context.get_admin_context(),
instance['id'])
return network['ra_server']
+
+ def _project_cidr_for_instance(self, instance):
+ network = db.network_get_by_instance(context.get_admin_context(),
+ instance['id'])
+ return network['cidr']
+
+ def _project_cidrv6_for_instance(self, instance):
+ network = db.network_get_by_instance(context.get_admin_context(),
+ instance['id'])
+ return network['cidr_v6']
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index 78f0d14b9..a0b0499b8 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -141,7 +141,7 @@ class XenAPIConnection(object):
self._vmops = VMOps(session)
self._volumeops = VolumeOps(session)
- def init_host(self):
+ def init_host(self, host):
#FIXME(armando): implement this
#NOTE(armando): would we need a method
#to call when shutting down the host?
diff --git a/nova/volume/api.py b/nova/volume/api.py
index bb2e47aff..478c83486 100644
--- a/nova/volume/api.py
+++ b/nova/volume/api.py
@@ -47,7 +47,6 @@ class API(base.Base):
raise quota.QuotaError(_("Volume quota exceeded. You cannot "
"create a volume of size %sG") % size)
-
options = {
'size': size,
'user_id': context.user.id,