summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorJason Cannavale <jason.cannavale@rackspace.com>2011-05-31 11:51:24 -0500
committerJason Cannavale <jason.cannavale@rackspace.com>2011-05-31 11:51:24 -0500
commit14b6bb455e94e150925677a17c5ccbcf86696dee (patch)
treeb41c9d728f8a85d8a326158ccb4209d6ee52c09f /nova/db
parente16ac0dbe6d1ca73ef6bb8f906c2dfdf2269ab6d (diff)
parentf903911a078f4356b91cb7d0965456612b26698c (diff)
downloadnova-14b6bb455e94e150925677a17c5ccbcf86696dee.tar.gz
nova-14b6bb455e94e150925677a17c5ccbcf86696dee.tar.xz
nova-14b6bb455e94e150925677a17c5ccbcf86696dee.zip
Cleaned up text conflict.
Diffstat (limited to 'nova/db')
-rw-r--r--nova/db/api.py41
-rw-r--r--nova/db/sqlalchemy/api.py87
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/017_make_instance_type_id_an_integer.py68
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/018_rename_server_management_url.py60
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/019_add_volume_snapshot_support.py70
-rw-r--r--nova/db/sqlalchemy/models.py29
6 files changed, 348 insertions, 7 deletions
diff --git a/nova/db/api.py b/nova/db/api.py
index ef8aa1143..4e0aa60a2 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -47,6 +47,8 @@ flags.DEFINE_string('instance_name_template', 'instance-%08x',
'Template string to be used to generate instance names')
flags.DEFINE_string('volume_name_template', 'volume-%08x',
'Template string to be used to generate instance names')
+flags.DEFINE_string('snapshot_name_template', 'snapshot-%08x',
+ 'Template string to be used to generate snapshot names')
IMPL = utils.LazyPluggable(FLAGS['db_backend'],
@@ -403,7 +405,7 @@ def instance_create(context, values):
def instance_data_get_for_project(context, project_id):
- """Get (instance_count, core_count) for project."""
+ """Get (instance_count, total_cores, total_ram) for project."""
return IMPL.instance_data_get_for_project(context, project_id)
@@ -881,6 +883,43 @@ def volume_update(context, volume_id, values):
####################
+def snapshot_create(context, values):
+ """Create a snapshot from the values dictionary."""
+ return IMPL.snapshot_create(context, values)
+
+
+def snapshot_destroy(context, snapshot_id):
+ """Destroy the snapshot or raise if it does not exist."""
+ return IMPL.snapshot_destroy(context, snapshot_id)
+
+
+def snapshot_get(context, snapshot_id):
+ """Get a snapshot or raise if it does not exist."""
+ return IMPL.snapshot_get(context, snapshot_id)
+
+
+def snapshot_get_all(context):
+ """Get all snapshots."""
+ return IMPL.snapshot_get_all(context)
+
+
+def snapshot_get_all_by_project(context, project_id):
+ """Get all snapshots belonging to a project."""
+ return IMPL.snapshot_get_all_by_project(context, project_id)
+
+
+def snapshot_update(context, snapshot_id, values):
+ """Set the given properties on an snapshot and update it.
+
+ Raises NotFound if snapshot does not exist.
+
+ """
+ return IMPL.snapshot_update(context, snapshot_id, values)
+
+
+####################
+
+
def security_group_get_all(context):
"""Get all security groups."""
return IMPL.security_group_get_all(context)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 3681f30db..d53b76f4a 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -803,12 +803,13 @@ def instance_create(context, values):
def instance_data_get_for_project(context, project_id):
session = get_session()
result = session.query(func.count(models.Instance.id),
- func.sum(models.Instance.vcpus)).\
+ func.sum(models.Instance.vcpus),
+ func.sum(models.Instance.memory_mb)).\
filter_by(project_id=project_id).\
filter_by(deleted=False).\
first()
# NOTE(vish): convert None to 0
- return (result[0] or 0, result[1] or 0)
+ return (result[0] or 0, result[1] or 0, result[2] or 0)
@require_context
@@ -873,6 +874,7 @@ def instance_get_all(context):
options(joinedload_all('fixed_ip.floating_ips')).\
options(joinedload('security_groups')).\
options(joinedload_all('fixed_ip.network')).\
+ options(joinedload('metadata')).\
options(joinedload('instance_type')).\
filter_by(deleted=can_read_deleted(context)).\
all()
@@ -885,6 +887,7 @@ def instance_get_all_by_user(context, user_id):
options(joinedload_all('fixed_ip.floating_ips')).\
options(joinedload('security_groups')).\
options(joinedload_all('fixed_ip.network')).\
+ options(joinedload('metadata')).\
options(joinedload('instance_type')).\
filter_by(deleted=can_read_deleted(context)).\
filter_by(user_id=user_id).\
@@ -1497,7 +1500,7 @@ def auth_token_create(_context, token):
###################
-@require_admin_context
+@require_context
def quota_get(context, project_id, resource, session=None):
if not session:
session = get_session()
@@ -1511,7 +1514,7 @@ def quota_get(context, project_id, resource, session=None):
return result
-@require_admin_context
+@require_context
def quota_get_all_by_project(context, project_id):
session = get_session()
result = {'project_id': project_id}
@@ -1787,6 +1790,82 @@ def volume_update(context, volume_id, values):
@require_context
+def snapshot_create(context, values):
+ snapshot_ref = models.Snapshot()
+ snapshot_ref.update(values)
+
+ session = get_session()
+ with session.begin():
+ snapshot_ref.save(session=session)
+ return snapshot_ref
+
+
+@require_admin_context
+def snapshot_destroy(context, snapshot_id):
+ session = get_session()
+ with session.begin():
+ session.query(models.Snapshot).\
+ filter_by(id=snapshot_id).\
+ update({'deleted': 1,
+ 'deleted_at': datetime.datetime.utcnow(),
+ 'updated_at': literal_column('updated_at')})
+
+
+@require_context
+def snapshot_get(context, snapshot_id, session=None):
+ if not session:
+ session = get_session()
+ result = None
+
+ if is_admin_context(context):
+ result = session.query(models.Snapshot).\
+ filter_by(id=snapshot_id).\
+ filter_by(deleted=can_read_deleted(context)).\
+ first()
+ elif is_user_context(context):
+ result = session.query(models.Snapshot).\
+ filter_by(project_id=context.project_id).\
+ filter_by(id=snapshot_id).\
+ filter_by(deleted=False).\
+ first()
+ if not result:
+ raise exception.SnapshotNotFound(snapshot_id=snapshot_id)
+
+ return result
+
+
+@require_admin_context
+def snapshot_get_all(context):
+ session = get_session()
+ return session.query(models.Snapshot).\
+ filter_by(deleted=can_read_deleted(context)).\
+ all()
+
+
+@require_context
+def snapshot_get_all_by_project(context, project_id):
+ authorize_project_context(context, project_id)
+
+ session = get_session()
+ return session.query(models.Snapshot).\
+ filter_by(project_id=project_id).\
+ filter_by(deleted=can_read_deleted(context)).\
+ all()
+
+
+@require_context
+def snapshot_update(context, snapshot_id, values):
+ session = get_session()
+ with session.begin():
+ snapshot_ref = snapshot_get(context, snapshot_id, session=session)
+ snapshot_ref.update(values)
+ snapshot_ref.save(session=session)
+
+
+###################
+
+
+@require_context
def security_group_get_all(context):
session = get_session()
return session.query(models.SecurityGroup).\
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/017_make_instance_type_id_an_integer.py b/nova/db/sqlalchemy/migrate_repo/versions/017_make_instance_type_id_an_integer.py
new file mode 100644
index 000000000..cda890c94
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/017_make_instance_type_id_an_integer.py
@@ -0,0 +1,68 @@
+from sqlalchemy import Column, Integer, MetaData, String, Table
+from nova import log as logging
+
+meta = MetaData()
+
+
+def upgrade(migrate_engine):
+ meta.bind = migrate_engine
+ instances = Table('instances', meta, autoload=True,
+ autoload_with=migrate_engine)
+
+ types = {}
+ for instance in migrate_engine.execute(instances.select()):
+ if instance.instance_type_id is None:
+ types[instance.id] = None
+ continue
+ try:
+ types[instance.id] = int(instance.instance_type_id)
+ except ValueError:
+ logging.warn("Instance %s did not have instance_type_id "
+ "converted to an integer because its value is %s" %
+ (instance.id, instance.instance_type_id))
+ types[instance.id] = None
+
+ integer_column = Column('instance_type_id_int', Integer(), nullable=True)
+ string_column = instances.c.instance_type_id
+
+ integer_column.create(instances)
+ for instance_id, instance_type_id in types.iteritems():
+ update = instances.update().\
+ where(instances.c.id == instance_id).\
+ values(instance_type_id_int=instance_type_id)
+ migrate_engine.execute(update)
+
+ string_column.alter(name='instance_type_id_str')
+ integer_column.alter(name='instance_type_id')
+ string_column.drop()
+
+
+def downgrade(migrate_engine):
+ meta.bind = migrate_engine
+ instances = Table('instances', meta, autoload=True,
+ autoload_with=migrate_engine)
+
+ integer_column = instances.c.instance_type_id
+ string_column = Column('instance_type_id_str',
+ String(length=255, convert_unicode=False,
+ assert_unicode=None, unicode_error=None,
+ _warn_on_bytestring=False),
+ nullable=True)
+
+ types = {}
+ for instance in migrate_engine.execute(instances.select()):
+ if instance.instance_type_id is None:
+ types[instance.id] = None
+ else:
+ types[instance.id] = str(instance.instance_type_id)
+
+ string_column.create(instances)
+ for instance_id, instance_type_id in types.iteritems():
+ update = instances.update().\
+ where(instances.c.id == instance_id).\
+ values(instance_type_id_str=instance_type_id)
+ migrate_engine.execute(update)
+
+ integer_column.alter(name='instance_type_id_int')
+ string_column.alter(name='instance_type_id')
+ integer_column.drop()
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/018_rename_server_management_url.py b/nova/db/sqlalchemy/migrate_repo/versions/018_rename_server_management_url.py
new file mode 100644
index 000000000..a169afb40
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/018_rename_server_management_url.py
@@ -0,0 +1,60 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 OpenStack LLC.
+#
+# 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.
+
+from sqlalchemy import Column, Integer, MetaData, String, Table
+#from nova import log as logging
+
+meta = MetaData()
+
+c_manageent = Column('server_manageent_url',
+ String(length=255, convert_unicode=False,
+ assert_unicode=None, unicode_error=None,
+ _warn_on_bytestring=False),
+ nullable=True)
+
+c_management = Column('server_management_url',
+ String(length=255, convert_unicode=False,
+ assert_unicode=None, unicode_error=None,
+ _warn_on_bytestring=False),
+ nullable=True)
+
+
+def upgrade(migrate_engine):
+ # Upgrade operations go here. Don't create your own engine;
+ # bind migrate_engine to your metadata
+ meta.bind = migrate_engine
+
+ tokens = Table('auth_tokens', meta, autoload=True,
+ autoload_with=migrate_engine)
+
+ tokens.create_column(c_management)
+ migrate_engine.execute(tokens.update()
+ .values(server_management_url=tokens.c.server_manageent_url))
+
+ tokens.c.server_manageent_url.drop()
+
+
+def downgrade(migrate_engine):
+ meta.bind = migrate_engine
+
+ tokens = Table('auth_tokens', meta, autoload=True,
+ autoload_with=migrate_engine)
+
+ tokens.create_column(c_manageent)
+ migrate_engine.execute(tokens.update()
+ .values(server_manageent_url=tokens.c.server_management_url))
+
+ tokens.c.server_management_url.drop()
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/019_add_volume_snapshot_support.py b/nova/db/sqlalchemy/migrate_repo/versions/019_add_volume_snapshot_support.py
new file mode 100644
index 000000000..f16d6db56
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/019_add_volume_snapshot_support.py
@@ -0,0 +1,70 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 MORITA Kazutaka.
+# 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.
+
+from sqlalchemy import Column, Table, MetaData
+from sqlalchemy import Integer, DateTime, Boolean, String
+
+from nova import log as logging
+
+meta = MetaData()
+
+snapshots = Table('snapshots', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('volume_id', Integer(), nullable=False),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('status',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('progress',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('volume_size', Integer()),
+ Column('scheduled_at', DateTime(timezone=False)),
+ Column('display_name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('display_description',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)))
+
+
+def upgrade(migrate_engine):
+ # Upgrade operations go here. Don't create your own engine;
+ # bind migrate_engine to your metadata
+ meta.bind = migrate_engine
+
+ try:
+ snapshots.create()
+ except Exception:
+ logging.info(repr(snapshots))
+ logging.exception('Exception while creating table')
+ meta.drop_all(tables=[snapshots])
+ raise
+
+
+def downgrade(migrate_engine):
+ # Operations to reverse the above upgrade go here.
+ snapshots.drop()
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index 0b46d5a05..480f62399 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -209,7 +209,7 @@ class Instance(BASE, NovaBase):
hostname = Column(String(255))
host = Column(String(255)) # , ForeignKey('hosts.id'))
- instance_type_id = Column(String(255))
+ instance_type_id = Column(Integer)
user_data = Column(Text)
@@ -329,6 +329,31 @@ class Quota(BASE, NovaBase):
hard_limit = Column(Integer, nullable=True)
+class Snapshot(BASE, NovaBase):
+ """Represents a block storage device that can be attached to a vm."""
+ __tablename__ = 'snapshots'
+ id = Column(Integer, primary_key=True, autoincrement=True)
+
+ @property
+ def name(self):
+ return FLAGS.snapshot_name_template % self.id
+
+ @property
+ def volume_name(self):
+ return FLAGS.volume_name_template % self.volume_id
+
+ user_id = Column(String(255))
+ project_id = Column(String(255))
+
+ volume_id = Column(Integer)
+ status = Column(String(255))
+ progress = Column(String(255))
+ volume_size = Column(Integer)
+
+ display_name = Column(String(255))
+ display_description = Column(String(255))
+
+
class ExportDevice(BASE, NovaBase):
"""Represates a shelf and blade that a volume can be exported on."""
__tablename__ = 'export_devices'
@@ -495,7 +520,7 @@ class AuthToken(BASE, NovaBase):
__tablename__ = 'auth_tokens'
token_hash = Column(String(255), primary_key=True)
user_id = Column(String(255))
- server_manageent_url = Column(String(255))
+ server_management_url = Column(String(255))
storage_url = Column(String(255))
cdn_management_url = Column(String(255))