summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@yahoo.com>2010-09-28 21:11:11 -0700
committerVishvananda Ishaya <vishvananda@yahoo.com>2010-09-28 21:11:11 -0700
commit9b7d69b3575da4e54a7e2bcb1f13ced39b199d10 (patch)
treed2aa2a97863f468936349344e7b8318e9a413168 /nova/db
parentb952e1ef61a6ed73e34c6dd0318cd4d52faf47dc (diff)
parent43ce84290964b433fd9d9898772d29bffc385dd8 (diff)
downloadnova-9b7d69b3575da4e54a7e2bcb1f13ced39b199d10.tar.gz
nova-9b7d69b3575da4e54a7e2bcb1f13ced39b199d10.tar.xz
nova-9b7d69b3575da4e54a7e2bcb1f13ced39b199d10.zip
merged trunk
Diffstat (limited to 'nova/db')
-rw-r--r--nova/db/api.py43
-rw-r--r--nova/db/sqlalchemy/api.py105
-rw-r--r--nova/db/sqlalchemy/models.py27
3 files changed, 136 insertions, 39 deletions
diff --git a/nova/db/api.py b/nova/db/api.py
index 1e2738b99..6184b3a35 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -161,10 +161,15 @@ def floating_ip_get_all(context):
def floating_ip_get_all_by_host(context, host):
- """Get all floating ips."""
+ """Get all floating ips by host."""
return IMPL.floating_ip_get_all_by_host(context, host)
+def floating_ip_get_all_by_project(context, project_id):
+ """Get all floating ips by project."""
+ return IMPL.floating_ip_get_all_by_project(context, project_id)
+
+
def floating_ip_get_by_address(context, address):
"""Get a floating ip by address or raise if it doesn't exist."""
return IMPL.floating_ip_get_by_address(context, address)
@@ -251,15 +256,18 @@ def instance_get_all(context):
"""Get all instances."""
return IMPL.instance_get_all(context)
+def instance_get_all_by_user(context, user_id):
+ """Get all instances."""
+ return IMPL.instance_get_all(context, user_id)
-def instance_get_by_project(context, project_id):
+def instance_get_all_by_project(context, project_id):
"""Get all instance belonging to a project."""
- return IMPL.instance_get_by_project(context, project_id)
+ return IMPL.instance_get_all_by_project(context, project_id)
-def instance_get_by_reservation(context, reservation_id):
+def instance_get_all_by_reservation(context, reservation_id):
"""Get all instance belonging to a reservation."""
- return IMPL.instance_get_by_reservation(context, reservation_id)
+ return IMPL.instance_get_all_by_reservation(context, reservation_id)
def instance_get_fixed_address(context, instance_id):
@@ -272,9 +280,9 @@ def instance_get_floating_address(context, instance_id):
return IMPL.instance_get_floating_address(context, instance_id)
-def instance_get_by_str(context, str_id):
- """Get an instance by string id."""
- return IMPL.instance_get_by_str(context, str_id)
+def instance_get_by_ec2_id(context, ec2_id):
+ """Get an instance by ec2 id."""
+ return IMPL.instance_get_by_ec2_id(context, ec2_id)
def instance_is_vpn(context, instance_id):
@@ -398,9 +406,12 @@ def network_index_count(context):
return IMPL.network_index_count(context)
-def network_index_create(context, values):
- """Create a network index from the values dict"""
- return IMPL.network_index_create(context, values)
+def network_index_create_safe(context, values):
+ """Create a network index from the values dict
+
+ The index is not returned. If the create violates the unique
+ constraints because the index already exists, no exception is raised."""
+ return IMPL.network_index_create_safe(context, values)
def network_set_cidr(context, network_id, cidr):
@@ -537,14 +548,14 @@ def volume_get_instance(context, volume_id):
return IMPL.volume_get_instance(context, volume_id)
-def volume_get_by_project(context, project_id):
+def volume_get_all_by_project(context, project_id):
"""Get all volumes belonging to a project."""
- return IMPL.volume_get_by_project(context, project_id)
+ return IMPL.volume_get_all_by_project(context, project_id)
-def volume_get_by_str(context, str_id):
- """Get a volume by string id."""
- return IMPL.volume_get_by_str(context, str_id)
+def volume_get_by_ec2_id(context, ec2_id):
+ """Get a volume by ec2 id."""
+ return IMPL.volume_get_by_ec2_id(context, ec2_id)
def volume_get_shelf_and_blade(context, volume_id):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index fcdf945eb..dad544cdb 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -19,14 +19,18 @@
Implementation of SQLAlchemy backend
"""
+import sys
+
from nova import db
from nova import exception
from nova import flags
+from nova import utils
from nova.db.sqlalchemy import models
from nova.db.sqlalchemy.session import get_session
from sqlalchemy import or_
+from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import contains_eager, eagerload, joinedload_all
-from sqlalchemy.sql import func
+from sqlalchemy.sql import exists, func
FLAGS = flags.FLAGS
@@ -61,6 +65,7 @@ def service_get_all_by_topic(context, topic):
session = get_session()
return session.query(models.Service
).filter_by(deleted=False
+ ).filter_by(disabled=False
).filter_by(topic=topic
).all()
@@ -70,6 +75,7 @@ def _service_get_all_topic_subquery(_context, session, topic, subq, label):
return session.query(models.Service, func.coalesce(sort_value, 0)
).filter_by(topic=topic
).filter_by(deleted=False
+ ).filter_by(disabled=False
).outerjoin((subq, models.Service.host == subq.c.host)
).order_by(sort_value
).all()
@@ -163,6 +169,7 @@ def floating_ip_allocate_address(_context, host, project_id):
floating_ip_ref = session.query(models.FloatingIp
).filter_by(host=host
).filter_by(fixed_ip_id=None
+ ).filter_by(project_id=None
).filter_by(deleted=False
).with_lockmode('update'
).first()
@@ -250,6 +257,14 @@ def floating_ip_get_all_by_host(_context, host):
).filter_by(deleted=False
).all()
+def floating_ip_get_all_by_project(_context, project_id):
+ session = get_session()
+ return session.query(models.FloatingIp
+ ).options(joinedload_all('fixed_ip.instance')
+ ).filter_by(project_id=project_id
+ ).filter_by(deleted=False
+ ).all()
+
def floating_ip_get_by_address(_context, address):
return models.FloatingIp.find_by_str(address)
@@ -325,7 +340,17 @@ def fixed_ip_disassociate(_context, address):
def fixed_ip_get_by_address(_context, address):
- return models.FixedIp.find_by_str(address)
+ session = get_session()
+ with session.begin():
+ try:
+ return session.query(models.FixedIp
+ ).options(joinedload_all('instance')
+ ).filter_by(address=address
+ ).filter_by(deleted=False
+ ).one()
+ except exc.NoResultFound:
+ new_exc = exception.NotFound("No model for address %s" % address)
+ raise new_exc.__class__, new_exc, sys.exc_info()[2]
def fixed_ip_get_instance(_context, address):
@@ -356,9 +381,15 @@ def instance_create(_context, values):
instance_ref = models.Instance()
for (key, value) in values.iteritems():
instance_ref[key] = value
- instance_ref.save()
- return instance_ref
+ session = get_session()
+ with session.begin():
+ while instance_ref.ec2_id == None:
+ ec2_id = utils.generate_uid(instance_ref.__prefix__)
+ if not instance_ec2_id_exists(_context, ec2_id, session=session):
+ instance_ref.ec2_id = ec2_id
+ instance_ref.save(session=session)
+ return instance_ref
def instance_data_get_for_project(_context, project_id):
session = get_session()
@@ -390,8 +421,15 @@ def instance_get_all(context):
).filter_by(deleted=_deleted(context)
).all()
+def instance_get_all_by_user(context, user_id):
+ session = get_session()
+ return session.query(models.Instance
+ ).options(joinedload_all('fixed_ip.floating_ips')
+ ).filter_by(deleted=_deleted(context)
+ ).filter_by(user_id=user_id
+ ).all()
-def instance_get_by_project(context, project_id):
+def instance_get_all_by_project(context, project_id):
session = get_session()
return session.query(models.Instance
).options(joinedload_all('fixed_ip.floating_ips')
@@ -400,7 +438,7 @@ def instance_get_by_project(context, project_id):
).all()
-def instance_get_by_reservation(_context, reservation_id):
+def instance_get_all_by_reservation(_context, reservation_id):
session = get_session()
return session.query(models.Instance
).options(joinedload_all('fixed_ip.floating_ips')
@@ -409,8 +447,22 @@ def instance_get_by_reservation(_context, reservation_id):
).all()
-def instance_get_by_str(context, str_id):
- return models.Instance.find_by_str(str_id, deleted=_deleted(context))
+def instance_get_by_ec2_id(context, ec2_id):
+ session = get_session()
+ instance_ref = session.query(models.Instance
+ ).filter_by(ec2_id=ec2_id
+ ).filter_by(deleted=_deleted(context)
+ ).first()
+ if not instance_ref:
+ raise exception.NotFound('Instance %s not found' % (ec2_id))
+
+ return instance_ref
+
+
+def instance_ec2_id_exists(context, ec2_id, session=None):
+ if not session:
+ session = get_session()
+ return session.query(exists().where(models.Instance.id==ec2_id)).one()[0]
def instance_get_fixed_address(_context, instance_id):
@@ -582,6 +634,7 @@ def network_get(_context, network_id):
def network_get_associated_fixed_ips(_context, network_id):
session = get_session()
return session.query(models.FixedIp
+ ).options(joinedload_all('instance')
).filter_by(network_id=network_id
).filter(models.FixedIp.instance_id != None
).filter_by(deleted=False
@@ -619,11 +672,14 @@ def network_index_count(_context):
return models.NetworkIndex.count()
-def network_index_create(_context, values):
+def network_index_create_safe(_context, values):
network_index_ref = models.NetworkIndex()
for (key, value) in values.iteritems():
network_index_ref[key] = value
- network_index_ref.save()
+ try:
+ network_index_ref.save()
+ except IntegrityError:
+ pass
def network_set_host(_context, network_id, host_id):
@@ -780,7 +836,14 @@ def volume_create(_context, values):
volume_ref = models.Volume()
for (key, value) in values.iteritems():
volume_ref[key] = value
- volume_ref.save()
+
+ session = get_session()
+ with session.begin():
+ while volume_ref.ec2_id == None:
+ ec2_id = utils.generate_uid(volume_ref.__prefix__)
+ if not volume_ec2_id_exists(_context, ec2_id, session=session):
+ volume_ref.ec2_id = ec2_id
+ volume_ref.save(session=session)
return volume_ref
@@ -825,7 +888,7 @@ def volume_get_all(context):
return models.Volume.all(deleted=_deleted(context))
-def volume_get_by_project(context, project_id):
+def volume_get_all_by_project(context, project_id):
session = get_session()
return session.query(models.Volume
).filter_by(project_id=project_id
@@ -833,8 +896,22 @@ def volume_get_by_project(context, project_id):
).all()
-def volume_get_by_str(context, str_id):
- return models.Volume.find_by_str(str_id, deleted=_deleted(context))
+def volume_get_by_ec2_id(context, ec2_id):
+ session = get_session()
+ volume_ref = session.query(models.Volume
+ ).filter_by(ec2_id=ec2_id
+ ).filter_by(deleted=_deleted(context)
+ ).first()
+ if not volume_ref:
+ raise exception.NotFound('Volume %s not found' % (ec2_id))
+
+ return volume_ref
+
+
+def volume_ec2_id_exists(context, ec2_id, session=None):
+ if not session:
+ session = get_session()
+ return session.query(exists().where(models.Volume.id==ec2_id)).one()[0]
def volume_get_instance(_context, volume_id):
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index 9ce146f1d..d4caf0b52 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -130,6 +130,7 @@ class NovaBase(object):
# __tablename__ = 'images'
# __prefix__ = 'ami'
# id = Column(Integer, primary_key=True)
+# ec2_id = Column(String(12), unique=True)
# user_id = Column(String(255))
# project_id = Column(String(255))
# image_type = Column(String(255))
@@ -177,6 +178,7 @@ class Service(BASE, NovaBase):
binary = Column(String(255))
topic = Column(String(255))
report_count = Column(Integer, nullable=False, default=0)
+ disabled = Column(Boolean, default=False)
@classmethod
def find_by_args(cls, host, binary, session=None, deleted=False):
@@ -199,6 +201,7 @@ class Instance(BASE, NovaBase):
__tablename__ = 'instances'
__prefix__ = 'i'
id = Column(Integer, primary_key=True)
+ ec2_id = Column(String(10), unique=True)
user_id = Column(String(255))
project_id = Column(String(255))
@@ -213,12 +216,14 @@ class Instance(BASE, NovaBase):
@property
def name(self):
- return self.str_id
+ return self.ec2_id
image_id = Column(String(255))
kernel_id = Column(String(255))
ramdisk_id = Column(String(255))
+ server_name = Column(String(255))
+
# image_id = Column(Integer, ForeignKey('images.id'), nullable=True)
# kernel_id = Column(Integer, ForeignKey('images.id'), nullable=True)
# ramdisk_id = Column(Integer, ForeignKey('images.id'), nullable=True)
@@ -237,7 +242,6 @@ class Instance(BASE, NovaBase):
vcpus = Column(Integer)
local_gb = Column(Integer)
-
hostname = Column(String(255))
host = Column(String(255)) # , ForeignKey('hosts.id'))
@@ -251,6 +255,10 @@ class Instance(BASE, NovaBase):
scheduled_at = Column(DateTime)
launched_at = Column(DateTime)
terminated_at = Column(DateTime)
+
+ display_name = Column(String(255))
+ display_description = Column(String(255))
+
# TODO(vish): see Ewan's email about state improvements, probably
# should be in a driver base class or some such
# vmstate_state = running, halted, suspended, paused
@@ -268,6 +276,7 @@ class Volume(BASE, NovaBase):
__tablename__ = 'volumes'
__prefix__ = 'vol'
id = Column(Integer, primary_key=True)
+ ec2_id = Column(String(12), unique=True)
user_id = Column(String(255))
project_id = Column(String(255))
@@ -286,6 +295,10 @@ class Volume(BASE, NovaBase):
launched_at = Column(DateTime)
terminated_at = Column(DateTime)
+ display_name = Column(String(255))
+ display_description = Column(String(255))
+
+
class Quota(BASE, NovaBase):
"""Represents quota overrides for a project"""
__tablename__ = 'quotas'
@@ -447,14 +460,14 @@ class NetworkIndex(BASE, NovaBase):
"""
__tablename__ = 'network_indexes'
id = Column(Integer, primary_key=True)
- index = Column(Integer)
+ index = Column(Integer, unique=True)
network_id = Column(Integer, ForeignKey('networks.id'), nullable=True)
network = relationship(Network, backref=backref('network_index',
uselist=False))
class AuthToken(BASE, NovaBase):
- """Represents an authorization token for all API transactions. Fields
- are a string representing the actual token and a user id for mapping
+ """Represents an authorization token for all API transactions. Fields
+ are a string representing the actual token and a user id for mapping
to the actual user"""
__tablename__ = 'auth_tokens'
token_hash = Column(String(255), primary_key=True)
@@ -509,10 +522,6 @@ class FloatingIp(BASE, NovaBase):
project_id = Column(String(255))
host = Column(String(255)) # , ForeignKey('hosts.id'))
- @property
- def str_id(self):
- return self.address
-
@classmethod
def find_by_str(cls, str_id, session=None, deleted=False):
if not session: