From b814f9fef3efa1bdcb7e03a9161e08721b7bc8c4 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Fri, 15 Jul 2011 17:56:27 -0700 Subject: VSA: first cut. merged with 1279 --- nova/db/api.py | 88 ++++++- nova/db/sqlalchemy/api.py | 291 +++++++++++++++++++++ .../migrate_repo/versions/032_add_vsa_data.py | 152 +++++++++++ nova/db/sqlalchemy/migration.py | 3 +- nova/db/sqlalchemy/models.py | 95 +++++++ 5 files changed, 627 insertions(+), 2 deletions(-) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/032_add_vsa_data.py (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index b7c5700e5..9147f136b 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -49,7 +49,8 @@ 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') - +flags.DEFINE_string('vsa_name_template', 'vsa-%08x', + 'Template string to be used to generate VSA names') IMPL = utils.LazyPluggable(FLAGS['db_backend'], sqlalchemy='nova.db.sqlalchemy.api') @@ -509,6 +510,13 @@ def instance_get_all_by_project(context, project_id): return IMPL.instance_get_all_by_project(context, project_id) +def instance_get_all_by_project_and_vsa(context, project_id, vsa_id): + """Get all instance spawned by a given VSA belonging to a project.""" + return IMPL.instance_get_all_by_project_and_vsa(context, + project_id, + vsa_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) @@ -914,6 +922,16 @@ def volume_get_all_by_project(context, project_id): return IMPL.volume_get_all_by_project(context, project_id) +def volume_get_all_assigned_to_vsa(context, vsa_id): + """Get all volumes assigned to particular VSA.""" + return IMPL.volume_get_all_assigned_to_vsa(context, vsa_id) + + +def volume_get_all_assigned_from_vsa(context, vsa_id): + """Get all volumes created from particular VSA.""" + return IMPL.volume_get_all_assigned_from_vsa(context, vsa_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) @@ -1422,3 +1440,71 @@ def instance_type_extra_specs_update_or_create(context, instance_type_id, key/value pairs specified in the extra specs dict argument""" IMPL.instance_type_extra_specs_update_or_create(context, instance_type_id, extra_specs) + + +#################### + + +def drive_type_create(context, values): + """Creates drive type record.""" + return IMPL.drive_type_create(context, values) + + +def drive_type_update(context, name, values): + """Updates drive type record.""" + return IMPL.drive_type_update(context, name, values) + + +def drive_type_destroy(context, name): + """Deletes drive type record.""" + return IMPL.drive_type_destroy(context, name) + + +def drive_type_get(context, drive_type_id): + """Get drive type record by id.""" + return IMPL.drive_type_get(context, drive_type_id) + + +def drive_type_get_by_name(context, name): + """Get drive type record by name.""" + return IMPL.drive_type_get_by_name(context, name) + + +def drive_type_get_all(context, visible=None): + """Returns all (or only visible) drive types.""" + return IMPL.drive_type_get_all(context, visible) + + +def vsa_create(context, values): + """Creates Virtual Storage Array record.""" + return IMPL.vsa_create(context, values) + + +def vsa_update(context, vsa_id, values): + """Updates Virtual Storage Array record.""" + return IMPL.vsa_update(context, vsa_id, values) + + +def vsa_destroy(context, vsa_id): + """Deletes Virtual Storage Array record.""" + return IMPL.vsa_destroy(context, vsa_id) + + +def vsa_get(context, vsa_id): + """Get Virtual Storage Array record by ID.""" + return IMPL.vsa_get(context, vsa_id) + + +def vsa_get_all(context): + """Get all Virtual Storage Array records.""" + return IMPL.vsa_get_all(context) + + +def vsa_get_all_by_project(context, project_id): + """Get all Virtual Storage Array records by project ID.""" + return IMPL.vsa_get_all_by_project(context, project_id) + + +def vsa_get_vc_ips_list(context, vsa_id): + """Retrieves IPs of instances associated with Virtual Storage Array.""" + return IMPL.vsa_get_vc_ips_list(context, vsa_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index a831516a8..aa5a6e052 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1217,6 +1217,35 @@ def instance_get_all_by_project(context, project_id): all() +@require_context +def instance_get_all_by_project_and_vsa(context, project_id, vsa_id): + authorize_project_context(context, project_id) + + session = get_session() + return session.query(models.Instance).\ + options(joinedload_all('fixed_ips.floating_ips')).\ + options(joinedload('security_groups')).\ + options(joinedload_all('fixed_ips.network')).\ + options(joinedload('instance_type')).\ + filter_by(project_id=project_id).\ + filter_by(vsa_id=vsa_id).\ + filter_by(deleted=can_read_deleted(context)).\ + all() + + +@require_admin_context +def instance_get_all_by_vsa(context, vsa_id): + session = get_session() + return session.query(models.Instance).\ + options(joinedload_all('fixed_ips.floating_ips')).\ + options(joinedload('security_groups')).\ + options(joinedload_all('fixed_ips.network')).\ + options(joinedload('instance_type')).\ + filter_by(vsa_id=vsa_id).\ + filter_by(deleted=can_read_deleted(context)).\ + all() + + @require_context def instance_get_all_by_reservation(context, reservation_id): session = get_session() @@ -2018,12 +2047,14 @@ def volume_get(context, volume_id, session=None): if is_admin_context(context): result = session.query(models.Volume).\ options(joinedload('instance')).\ + options(joinedload('drive_type')).\ 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')).\ + options(joinedload('drive_type')).\ filter_by(project_id=context.project_id).\ filter_by(id=volume_id).\ filter_by(deleted=False).\ @@ -2039,6 +2070,7 @@ def volume_get_all(context): session = get_session() return session.query(models.Volume).\ options(joinedload('instance')).\ + options(joinedload('drive_type')).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -2048,6 +2080,7 @@ def volume_get_all_by_host(context, host): session = get_session() return session.query(models.Volume).\ options(joinedload('instance')).\ + options(joinedload('drive_type')).\ filter_by(host=host).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -2057,6 +2090,7 @@ def volume_get_all_by_host(context, host): def volume_get_all_by_instance(context, instance_id): session = get_session() result = session.query(models.Volume).\ + options(joinedload('drive_type')).\ filter_by(instance_id=instance_id).\ filter_by(deleted=False).\ all() @@ -2065,6 +2099,28 @@ def volume_get_all_by_instance(context, instance_id): return result +@require_admin_context +def volume_get_all_assigned_to_vsa(context, vsa_id): + session = get_session() + result = session.query(models.Volume).\ + options(joinedload('drive_type')).\ + filter_by(to_vsa_id=vsa_id).\ + filter_by(deleted=False).\ + all() + return result + + +@require_admin_context +def volume_get_all_assigned_from_vsa(context, vsa_id): + session = get_session() + result = session.query(models.Volume).\ + options(joinedload('drive_type')).\ + filter_by(from_vsa_id=vsa_id).\ + filter_by(deleted=False).\ + all() + return result + + @require_context def volume_get_all_by_project(context, project_id): authorize_project_context(context, project_id) @@ -2072,6 +2128,7 @@ def volume_get_all_by_project(context, project_id): session = get_session() return session.query(models.Volume).\ options(joinedload('instance')).\ + options(joinedload('drive_type')).\ filter_by(project_id=project_id).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -2084,6 +2141,7 @@ def volume_get_instance(context, volume_id): filter_by(id=volume_id).\ filter_by(deleted=can_read_deleted(context)).\ options(joinedload('instance')).\ + options(joinedload('drive_type')).\ first() if not result: raise exception.VolumeNotFound(volume_id=volume_id) @@ -3286,3 +3344,236 @@ def instance_type_extra_specs_update_or_create(context, instance_type_id, "deleted": 0}) spec_ref.save(session=session) return specs + + + #################### + + +@require_admin_context +def drive_type_create(context, values): + """ + Creates drive type record. + """ + try: + drive_type_ref = models.DriveTypes() + drive_type_ref.update(values) + drive_type_ref.save() + except Exception, e: + raise exception.DBError(e) + return drive_type_ref + + +@require_admin_context +def drive_type_update(context, name, values): + """ + Updates drive type record. + """ + session = get_session() + with session.begin(): + drive_type_ref = drive_type_get_by_name(context, name, session=session) + drive_type_ref.update(values) + drive_type_ref.save(session=session) + return drive_type_ref + + +@require_admin_context +def drive_type_destroy(context, name): + """ + Deletes drive type record. + """ + session = get_session() + drive_type_ref = session.query(models.DriveTypes).\ + filter_by(name=name) + records = drive_type_ref.delete() + if records == 0: + raise exception.VirtualDiskTypeNotFoundByName(name=name) + else: + return drive_type_ref + + +@require_context +def drive_type_get(context, drive_type_id, session=None): + """ + Get drive type record by id. + """ + if not session: + session = get_session() + + result = session.query(models.DriveTypes).\ + filter_by(id=drive_type_id).\ + filter_by(deleted=can_read_deleted(context)).\ + first() + if not result: + raise exception.VirtualDiskTypeNotFound(id=drive_type_id) + + return result + + +@require_context +def drive_type_get_by_name(context, name, session=None): + """ + Get drive type record by name. + """ + if not session: + session = get_session() + + result = session.query(models.DriveTypes).\ + filter_by(name=name).\ + filter_by(deleted=can_read_deleted(context)).\ + first() + if not result: + raise exception.VirtualDiskTypeNotFoundByName(name=name) + + return result + + +@require_context +def drive_type_get_all(context, visible=False): + """ + Returns all (or only visible) drive types. + """ + session = get_session() + if not visible: + drive_types = session.query(models.DriveTypes).\ + filter_by(deleted=can_read_deleted(context)).\ + order_by("name").\ + all() + else: + drive_types = session.query(models.DriveTypes).\ + filter_by(deleted=can_read_deleted(context)).\ + filter_by(visible=True).\ + order_by("name").\ + all() + return drive_types + + + #################### + + +@require_admin_context +def vsa_create(context, values): + """ + Creates Virtual Storage Array record. + """ + try: + vsa_ref = models.VirtualStorageArray() + vsa_ref.update(values) + vsa_ref.save() + except Exception, e: + raise exception.DBError(e) + return vsa_ref + + +@require_admin_context +def vsa_update(context, vsa_id, values): + """ + Updates Virtual Storage Array record. + """ + session = get_session() + with session.begin(): + vsa_ref = vsa_get(context, vsa_id, session=session) + vsa_ref.update(values) + vsa_ref.save(session=session) + return vsa_ref + + +@require_admin_context +def vsa_destroy(context, vsa_id): + """ + Deletes Virtual Storage Array record. + """ + session = get_session() + with session.begin(): + #vsa_ref = vsa_get(context, vsa_id, session=session) + #vsa_ref.delete(session=session) + session.query(models.VirtualStorageArray).\ + filter_by(id=vsa_id).\ + update({'deleted': True, + 'deleted_at': utils.utcnow(), + 'updated_at': literal_column('updated_at')}) + + +@require_context +def vsa_get(context, vsa_id, session=None): + """ + Get Virtual Storage Array record by ID. + """ + if not session: + session = get_session() + result = None + + if is_admin_context(context): + result = session.query(models.VirtualStorageArray).\ + options(joinedload('vsa_instance_type')).\ + filter_by(id=vsa_id).\ + filter_by(deleted=can_read_deleted(context)).\ + first() + elif is_user_context(context): + result = session.query(models.VirtualStorageArray).\ + options(joinedload('vsa_instance_type')).\ + filter_by(project_id=context.project_id).\ + filter_by(id=vsa_id).\ + filter_by(deleted=False).\ + first() + if not result: + raise exception.VirtualStorageArrayNotFound(id=vsa_id) + + return result + + +@require_admin_context +def vsa_get_all(context): + """ + Get all Virtual Storage Array records. + """ + session = get_session() + return session.query(models.VirtualStorageArray).\ + options(joinedload('vsa_instance_type')).\ + filter_by(deleted=can_read_deleted(context)).\ + all() + + +@require_context +def vsa_get_all_by_project(context, project_id): + """ + Get all Virtual Storage Array records by project ID. + """ + authorize_project_context(context, project_id) + + session = get_session() + return session.query(models.VirtualStorageArray).\ + options(joinedload('vsa_instance_type')).\ + filter_by(project_id=project_id).\ + filter_by(deleted=can_read_deleted(context)).\ + all() + + +@require_context +def vsa_get_vc_ips_list(context, vsa_id): + """ + Retrieves IPs of instances associated with Virtual Storage Array. + """ + result = [] + session = get_session() + vc_instances = session.query(models.Instance).\ + options(joinedload_all('fixed_ips.floating_ips')).\ + options(joinedload('security_groups')).\ + options(joinedload_all('fixed_ips.network')).\ + options(joinedload('instance_type')).\ + filter_by(vsa_id=vsa_id).\ + filter_by(deleted=False).\ + all() + for vc_instance in vc_instances: + if vc_instance['fixed_ips']: + for fixed in vc_instance['fixed_ips']: + # insert the [floating,fixed] (if exists) in the head, + # otherwise append the [none,fixed] in the tail + ip = {} + ip['fixed'] = fixed['address'] + if fixed['floating_ips']: + ip['floating'] = fixed['floating_ips'][0]['address'] + result.append(ip) + + return result + + #################### diff --git a/nova/db/sqlalchemy/migrate_repo/versions/032_add_vsa_data.py b/nova/db/sqlalchemy/migrate_repo/versions/032_add_vsa_data.py new file mode 100644 index 000000000..7fc8f955c --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/032_add_vsa_data.py @@ -0,0 +1,152 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# 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, DateTime, Integer, MetaData, String, Table +from sqlalchemy import Text, Boolean, ForeignKey + +from nova import log as logging + +meta = MetaData() + +# Just for the ForeignKey and column creation to succeed, these are not the +# actual definitions of tables . +# + +instances = Table('instances', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +volumes = Table('volumes', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +vsa_id = Column('vsa_id', Integer(), nullable=True) +to_vsa_id = Column('to_vsa_id', Integer(), nullable=True) +from_vsa_id = Column('from_vsa_id', Integer(), nullable=True) +drive_type_id = Column('drive_type_id', Integer(), nullable=True) + + +# New Tables +# + +virtual_storage_arrays = Table('virtual_storage_arrays', 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('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)), + Column('project_id', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('availability_zone', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('instance_type_id', Integer(), nullable=False), + Column('image_ref', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('vc_count', Integer(), nullable=False), + Column('vol_count', Integer(), nullable=False), + Column('status', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + ) + +drive_types = Table('drive_types', 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('name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + unique=True), + Column('type', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('size_gb', Integer(), nullable=False), + Column('rpm', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('capabilities', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('visible', Boolean(create_constraint=True, name=None)), + ) + +#vsa_disk_association = Table('vsa_disk_association', 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('drive_type_id', Integer(), ForeignKey('drive_types.id')), +# Column('vsa_id', Integer(), ForeignKey('virtual_storage_arrays.id')), +# Column('disk_num', Integer(), nullable=False), +# ) + +#new_tables = (virtual_storage_arrays, drive_types, vsa_disk_association) +new_tables = (virtual_storage_arrays, drive_types) + +# +# Tables to alter +# + + +def upgrade(migrate_engine): + + from nova import context + from nova import db + from nova import flags + + FLAGS = flags.FLAGS + + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + + for table in new_tables: + try: + table.create() + except Exception: + logging.info(repr(table)) + logging.exception('Exception while creating table') + raise + + instances.create_column(vsa_id) + volumes.create_column(to_vsa_id) + volumes.create_column(from_vsa_id) + volumes.create_column(drive_type_id) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + instances.drop_column(vsa_id) + volumes.drop_column(to_vsa_id) + volumes.drop_column(from_vsa_id) + volumes.drop_column(drive_type_id) + + for table in new_tables: + table.drop() diff --git a/nova/db/sqlalchemy/migration.py b/nova/db/sqlalchemy/migration.py index d9e303599..9b64671a3 100644 --- a/nova/db/sqlalchemy/migration.py +++ b/nova/db/sqlalchemy/migration.py @@ -64,7 +64,8 @@ def db_version(): 'users', 'user_project_association', 'user_project_role_association', 'user_role_association', - 'volumes'): + 'volumes', + 'virtual_storage_arrays', 'drive_types'): assert table in meta.tables return db_version_control(1) except AssertionError: diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index d29d3d6f1..7f2e9d39c 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -247,6 +247,43 @@ class Instance(BASE, NovaBase): # assert(state in ['nostate', 'running', 'blocked', 'paused', # 'shutdown', 'shutoff', 'crashed']) + vsa_id = Column(Integer, ForeignKey('virtual_storage_arrays.id'), + nullable=True) + + +class VirtualStorageArray(BASE, NovaBase): + """ + Represents a virtual storage array supplying block storage to instances. + """ + __tablename__ = 'virtual_storage_arrays' + + id = Column(Integer, primary_key=True, autoincrement=True) + + @property + def name(self): + return FLAGS.vsa_name_template % self.id + + # User editable field for display in user-facing UIs + display_name = Column(String(255)) + display_description = Column(String(255)) + + project_id = Column(String(255)) + availability_zone = Column(String(255)) + + instance_type_id = Column(Integer, ForeignKey('instance_types.id')) + image_ref = Column(String(255)) + vc_count = Column(Integer, default=0) # number of requested VC instances + vol_count = Column(Integer, default=0) # total number of BE volumes + status = Column(String(255)) + + #admin_pass = Column(String(255)) + + #disks = relationship(VsaDiskAssociation, + # backref=backref('vsa', uselist=False), + # foreign_keys=id, + # primaryjoin='and_(VsaDiskAssociation.vsa_id == ' + # 'VirtualStorageArray.id)') + class InstanceActions(BASE, NovaBase): """Represents a guest VM's actions and results""" @@ -277,6 +314,12 @@ class InstanceTypes(BASE, NovaBase): primaryjoin='and_(Instance.instance_type_id == ' 'InstanceTypes.id)') + vsas = relationship(VirtualStorageArray, + backref=backref('vsa_instance_type', uselist=False), + foreign_keys=id, + primaryjoin='and_(VirtualStorageArray.instance_type_id' + ' == InstanceTypes.id)') + class Volume(BASE, NovaBase): """Represents a block storage device that can be attached to a vm.""" @@ -316,6 +359,57 @@ class Volume(BASE, NovaBase): provider_location = Column(String(255)) provider_auth = Column(String(255)) + to_vsa_id = Column(Integer, + ForeignKey('virtual_storage_arrays.id'), nullable=True) + from_vsa_id = Column(Integer, + ForeignKey('virtual_storage_arrays.id'), nullable=True) + drive_type_id = Column(Integer, + ForeignKey('drive_types.id'), nullable=True) + + +class DriveTypes(BASE, NovaBase): + """Represents the known drive types (storage media).""" + __tablename__ = 'drive_types' + + id = Column(Integer, primary_key=True, autoincrement=True) + + """ + @property + def name(self): + if self.capabilities: + return FLAGS.drive_type_template_long % \ + (self.type, str(self.size_gb), self.rpm, self.capabilities) + else: + return FLAGS.drive_type_template_short % \ + (self.type, str(self.size_gb), self.rpm) + """ + + name = Column(String(255), unique=True) + type = Column(String(255)) + size_gb = Column(Integer) + rpm = Column(String(255)) + capabilities = Column(String(255)) + + visible = Column(Boolean, default=True) + + volumes = relationship(Volume, + backref=backref('drive_type', uselist=False), + foreign_keys=id, + primaryjoin='and_(Volume.drive_type_id == ' + 'DriveTypes.id)') + +# +#class VsaDiskAssociation(BASE, NovaBase): +# """associates drive types with Virtual Storage Arrays.""" +# __tablename__ = 'vsa_disk_association' +# +# id = Column(Integer, primary_key=True, autoincrement=True) +# +# drive_type_id = Column(Integer, ForeignKey('drive_types.id')) +# vsa_id = Column(Integer, ForeignKey('virtual_storage_arrays.id')) +# +# disk_num = Column(Integer, nullable=False) # number of disks + class Quota(BASE, NovaBase): """Represents a single quota override for a project. @@ -785,6 +879,7 @@ def register_models(): Network, SecurityGroup, SecurityGroupIngressRule, SecurityGroupInstanceAssociation, AuthToken, User, Project, Certificate, ConsolePool, Console, Zone, + VirtualStorageArray, DriveTypes, AgentBuild, InstanceMetadata, InstanceTypeExtraSpecs, Migration) engine = create_engine(FLAGS.sql_connection, echo=False) for model in models: -- cgit From f6844960dd062154244c706283cf1916ee7194ff Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Fri, 15 Jul 2011 18:11:13 -0700 Subject: added missing instance_get_all_by_vsa --- nova/db/api.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 9147f136b..fde229099 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -522,6 +522,11 @@ def instance_get_all_by_host(context, host): return IMPL.instance_get_all_by_host(context, host) +def instance_get_all_by_vsa(context, vsa_id): + """Get all instance belonging to a VSA.""" + return IMPL.instance_get_all_by_vsa(context, vsa_id) + + 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) -- cgit From 9e74803d5eb8a70ba829ac0569f1cd6cd372a6f2 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Fri, 22 Jul 2011 15:14:29 -0700 Subject: Reverted volume driver part --- nova/db/api.py | 10 +++++----- nova/db/sqlalchemy/api.py | 19 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index fde229099..a3a6d47c4 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1455,14 +1455,14 @@ def drive_type_create(context, values): return IMPL.drive_type_create(context, values) -def drive_type_update(context, name, values): +def drive_type_update(context, drive_type_id, values): """Updates drive type record.""" - return IMPL.drive_type_update(context, name, values) + return IMPL.drive_type_update(context, drive_type_id, values) -def drive_type_destroy(context, name): +def drive_type_destroy(context, drive_type_id): """Deletes drive type record.""" - return IMPL.drive_type_destroy(context, name) + return IMPL.drive_type_destroy(context, drive_type_id) def drive_type_get(context, drive_type_id): @@ -1475,7 +1475,7 @@ def drive_type_get_by_name(context, name): return IMPL.drive_type_get_by_name(context, name) -def drive_type_get_all(context, visible=None): +def drive_type_get_all(context, visible): """Returns all (or only visible) drive types.""" return IMPL.drive_type_get_all(context, visible) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index aa5a6e052..c08524265 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3364,31 +3364,30 @@ def drive_type_create(context, values): @require_admin_context -def drive_type_update(context, name, values): +def drive_type_update(context, drive_type_id, values): """ Updates drive type record. """ session = get_session() with session.begin(): - drive_type_ref = drive_type_get_by_name(context, name, session=session) + drive_type_ref = drive_type_get(context, drive_type_id, + session=session) drive_type_ref.update(values) drive_type_ref.save(session=session) return drive_type_ref @require_admin_context -def drive_type_destroy(context, name): +def drive_type_destroy(context, drive_type_id): """ Deletes drive type record. """ session = get_session() drive_type_ref = session.query(models.DriveTypes).\ - filter_by(name=name) + filter_by(id=drive_type_id) records = drive_type_ref.delete() if records == 0: - raise exception.VirtualDiskTypeNotFoundByName(name=name) - else: - return drive_type_ref + raise exception.VirtualDiskTypeNotFound(id=drive_type_id) @require_context @@ -3428,20 +3427,20 @@ def drive_type_get_by_name(context, name, session=None): @require_context -def drive_type_get_all(context, visible=False): +def drive_type_get_all(context, visible): """ Returns all (or only visible) drive types. """ session = get_session() - if not visible: + if visible: drive_types = session.query(models.DriveTypes).\ filter_by(deleted=can_read_deleted(context)).\ + filter_by(visible=True).\ order_by("name").\ all() else: drive_types = session.query(models.DriveTypes).\ filter_by(deleted=can_read_deleted(context)).\ - filter_by(visible=True).\ order_by("name").\ all() return drive_types -- cgit From c500eac4589e9cb22e5e71b900164a151290ec03 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Mon, 25 Jul 2011 16:26:23 -0700 Subject: some cleanup. VSA flag status changes. returned some files --- nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py b/nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py index 7fc8f955c..5d2e56a7e 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py @@ -1,6 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 OpenStack LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may -- cgit From a0a3f0157d6f4e8563a5a1e4ee1bde92388f25fc Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Mon, 25 Jul 2011 16:58:09 -0700 Subject: volume name change. some cleanup --- nova/db/sqlalchemy/models.py | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index fbc8e9e19..42b97867d 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -279,14 +279,6 @@ class VirtualStorageArray(BASE, NovaBase): vol_count = Column(Integer, default=0) # total number of BE volumes status = Column(String(255)) - #admin_pass = Column(String(255)) - - #disks = relationship(VsaDiskAssociation, - # backref=backref('vsa', uselist=False), - # foreign_keys=id, - # primaryjoin='and_(VsaDiskAssociation.vsa_id == ' - # 'VirtualStorageArray.id)') - class InstanceActions(BASE, NovaBase): """Represents a guest VM's actions and results""" @@ -401,18 +393,6 @@ class DriveTypes(BASE, NovaBase): primaryjoin='and_(Volume.drive_type_id == ' 'DriveTypes.id)') -# -#class VsaDiskAssociation(BASE, NovaBase): -# """associates drive types with Virtual Storage Arrays.""" -# __tablename__ = 'vsa_disk_association' -# -# id = Column(Integer, primary_key=True, autoincrement=True) -# -# drive_type_id = Column(Integer, ForeignKey('drive_types.id')) -# vsa_id = Column(Integer, ForeignKey('virtual_storage_arrays.id')) -# -# disk_num = Column(Integer, nullable=False) # number of disks - class Quota(BASE, NovaBase): """Represents a single quota override for a project. -- cgit From a72f2e29e2a35791a1c53f4f606948572ab52280 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Tue, 26 Jul 2011 13:25:34 -0700 Subject: VSA volume creation/deletion changes --- nova/db/sqlalchemy/api.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 3b14f114a..50037e259 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2205,6 +2205,7 @@ def volume_update(context, volume_id, values): volume_ref = volume_get(context, volume_id, session=session) volume_ref.update(values) volume_ref.save(session=session) + return volume_ref ################### -- cgit From b4159d95c32382d124c3f3f0a49f8ad9f2d41036 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Thu, 28 Jul 2011 00:27:16 -0700 Subject: some minor cosmetic work. addressed some dead code section --- nova/db/sqlalchemy/api.py | 2 -- nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py | 12 ------------ 2 files changed, 14 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e17859f69..d71d8787b 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3526,8 +3526,6 @@ def vsa_destroy(context, vsa_id): """ session = get_session() with session.begin(): - #vsa_ref = vsa_get(context, vsa_id, session=session) - #vsa_ref.delete(session=session) session.query(models.VirtualStorageArray).\ filter_by(id=vsa_id).\ update({'deleted': True, diff --git a/nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py b/nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py index 5d2e56a7e..3b39ff493 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/036_add_vsa_data.py @@ -96,18 +96,6 @@ drive_types = Table('drive_types', meta, Column('visible', Boolean(create_constraint=True, name=None)), ) -#vsa_disk_association = Table('vsa_disk_association', 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('drive_type_id', Integer(), ForeignKey('drive_types.id')), -# Column('vsa_id', Integer(), ForeignKey('virtual_storage_arrays.id')), -# Column('disk_num', Integer(), nullable=False), -# ) - -#new_tables = (virtual_storage_arrays, drive_types, vsa_disk_association) new_tables = (virtual_storage_arrays, drive_types) # -- cgit From 820d28dcf09088b5878d4cd5dcb5f4765e0b4992 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Tue, 9 Aug 2011 18:14:41 -0700 Subject: Dropped vsa_id from instances --- nova/db/api.py | 12 --------- nova/db/sqlalchemy/api.py | 30 +--------------------- .../migrate_repo/versions/037_add_vsa_data.py | 7 ----- nova/db/sqlalchemy/models.py | 3 --- 4 files changed, 1 insertion(+), 51 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 59baf94dd..0b6995f90 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -512,23 +512,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_project_and_vsa(context, project_id, vsa_id): - """Get all instance spawned by a given VSA belonging to a project.""" - return IMPL.instance_get_all_by_project_and_vsa(context, - project_id, - vsa_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_vsa(context, vsa_id): - """Get all instance belonging to a VSA.""" - return IMPL.instance_get_all_by_vsa(context, vsa_id) - - def instance_get_all_by_reservation(context, reservation_id): """Get all instances 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 ff6d756a1..bc1a3046c 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1321,35 +1321,6 @@ def instance_get_all_by_project(context, project_id): all() -@require_context -def instance_get_all_by_project_and_vsa(context, project_id, vsa_id): - authorize_project_context(context, project_id) - - session = get_session() - return session.query(models.Instance).\ - options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload('security_groups')).\ - options(joinedload_all('fixed_ips.network')).\ - options(joinedload('instance_type')).\ - filter_by(project_id=project_id).\ - filter_by(vsa_id=vsa_id).\ - filter_by(deleted=can_read_deleted(context)).\ - all() - - -@require_admin_context -def instance_get_all_by_vsa(context, vsa_id): - session = get_session() - return session.query(models.Instance).\ - options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload('security_groups')).\ - options(joinedload_all('fixed_ips.network')).\ - options(joinedload('instance_type')).\ - filter_by(vsa_id=vsa_id).\ - filter_by(deleted=can_read_deleted(context)).\ - all() - - @require_context def instance_get_all_by_reservation(context, reservation_id): session = get_session() @@ -3748,6 +3719,7 @@ def vsa_get_vc_ips_list(context, vsa_id): """ result = [] session = get_session() + """ VP-TODO: CHANGE THIS!!! Need to perform a search based on meta-data """ vc_instances = session.query(models.Instance).\ options(joinedload_all('fixed_ips.floating_ips')).\ options(joinedload('security_groups')).\ diff --git a/nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py b/nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py index 3b39ff493..5a80f4e7a 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py @@ -27,15 +27,10 @@ meta = MetaData() # actual definitions of tables . # -instances = Table('instances', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - volumes = Table('volumes', meta, Column('id', Integer(), primary_key=True, nullable=False), ) -vsa_id = Column('vsa_id', Integer(), nullable=True) to_vsa_id = Column('to_vsa_id', Integer(), nullable=True) from_vsa_id = Column('from_vsa_id', Integer(), nullable=True) drive_type_id = Column('drive_type_id', Integer(), nullable=True) @@ -123,7 +118,6 @@ def upgrade(migrate_engine): logging.exception('Exception while creating table') raise - instances.create_column(vsa_id) volumes.create_column(to_vsa_id) volumes.create_column(from_vsa_id) volumes.create_column(drive_type_id) @@ -132,7 +126,6 @@ def upgrade(migrate_engine): def downgrade(migrate_engine): meta.bind = migrate_engine - instances.drop_column(vsa_id) volumes.drop_column(to_vsa_id) volumes.drop_column(from_vsa_id) volumes.drop_column(drive_type_id) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index f80029e97..236f148e4 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -243,9 +243,6 @@ class Instance(BASE, NovaBase): # assert(state in ['nostate', 'running', 'blocked', 'paused', # 'shutdown', 'shutoff', 'crashed']) - vsa_id = Column(Integer, ForeignKey('virtual_storage_arrays.id'), - nullable=True) - class VirtualStorageArray(BASE, NovaBase): """ -- cgit From 57b8f976f18b1f45de16ef8e87a6e215c009d228 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Thu, 11 Aug 2011 12:04:03 -0700 Subject: moved vsa_id to metadata. Added search my meta --- nova/db/sqlalchemy/api.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index bc1a3046c..b77f11abb 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1175,6 +1175,19 @@ def instance_get_all_by_filters(context, filters): return True return False + def _regexp_filter_by_metadata(instance, meta): + inst_metadata = [{node['key']: node['value']} \ + for node in instance['metadata']] + if isinstance(meta, list): + for node in meta: + if node not in inst_metadata: + return False + elif isinstance(meta, dict): + for k, v in meta.iteritems(): + if {k: v} not in inst_metadata: + return False + return True + def _regexp_filter_by_column(instance, filter_name, filter_re): try: v = getattr(instance, filter_name) @@ -1232,7 +1245,9 @@ def instance_get_all_by_filters(context, filters): query_prefix = _exact_match_filter(query_prefix, filter_name, filters.pop(filter_name)) - instances = query_prefix.all() + instances = query_prefix.\ + filter_by(deleted=can_read_deleted(context)).\ + all() if not instances: return [] @@ -1248,6 +1263,9 @@ def instance_get_all_by_filters(context, filters): filter_re = re.compile(str(filters[filter_name])) if filter_func: filter_l = lambda instance: filter_func(instance, filter_re) + elif filter_name == 'metadata': + filter_l = lambda instance: _regexp_filter_by_metadata(instance, + filters[filter_name]) else: filter_l = lambda instance: _regexp_filter_by_column(instance, filter_name, filter_re) @@ -3718,16 +3736,9 @@ def vsa_get_vc_ips_list(context, vsa_id): Retrieves IPs of instances associated with Virtual Storage Array. """ result = [] - session = get_session() - """ VP-TODO: CHANGE THIS!!! Need to perform a search based on meta-data """ - vc_instances = session.query(models.Instance).\ - options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload('security_groups')).\ - options(joinedload_all('fixed_ips.network')).\ - options(joinedload('instance_type')).\ - filter_by(vsa_id=vsa_id).\ - filter_by(deleted=False).\ - all() + + vc_instances = instance_get_all_by_filters(context, + search_opts={'metadata': dict(vsa_id=str(vsa_id))}) for vc_instance in vc_instances: if vc_instance['fixed_ips']: for fixed in vc_instance['fixed_ips']: -- cgit From 48cd9689de31e408c792052747f714a9dbe1f8f7 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Wed, 24 Aug 2011 15:51:29 -0700 Subject: added virtio flag; associate address for VSA; cosmetic changes. Prior to volume_types merge --- nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py | 1 - nova/db/sqlalchemy/session.py | 2 -- 2 files changed, 3 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py b/nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py index 5a80f4e7a..8a57bd234 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/037_add_vsa_data.py @@ -2,7 +2,6 @@ # Copyright (c) 2011 Zadara Storage Inc. # Copyright (c) 2011 OpenStack LLC. -# 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 diff --git a/nova/db/sqlalchemy/session.py b/nova/db/sqlalchemy/session.py index 07f281938..c678cb543 100644 --- a/nova/db/sqlalchemy/session.py +++ b/nova/db/sqlalchemy/session.py @@ -30,11 +30,9 @@ import nova.exception import nova.flags import nova.log - FLAGS = nova.flags.FLAGS LOG = nova.log.getLogger("nova.db.sqlalchemy") - try: import MySQLdb except ImportError: -- cgit From 4834b920e3186712ab56e65a88c2e8c838d16f9c Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Thu, 25 Aug 2011 18:38:35 -0700 Subject: VSA code redesign. Drive types completely replaced by Volume types --- nova/db/api.py | 45 ------ nova/db/sqlalchemy/api.py | 153 +-------------------- .../migrate_repo/versions/042_add_vsa_data.py | 133 ------------------ .../migrate_repo/versions/043_add_vsa_data.py | 75 ++++++++++ nova/db/sqlalchemy/models.py | 43 +----- nova/db/sqlalchemy/session.py | 2 + 6 files changed, 81 insertions(+), 370 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/042_add_vsa_data.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/043_add_vsa_data.py (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 354a90571..a2e581fe9 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -918,16 +918,6 @@ def volume_get_all_by_project(context, project_id): return IMPL.volume_get_all_by_project(context, project_id) -def volume_get_all_assigned_to_vsa(context, vsa_id): - """Get all volumes assigned to particular VSA.""" - return IMPL.volume_get_all_assigned_to_vsa(context, vsa_id) - - -def volume_get_all_assigned_from_vsa(context, vsa_id): - """Get all volumes created from particular VSA.""" - return IMPL.volume_get_all_assigned_from_vsa(context, vsa_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) @@ -1528,36 +1518,6 @@ def volume_type_extra_specs_update_or_create(context, volume_type_id, #################### -def drive_type_create(context, values): - """Creates drive type record.""" - return IMPL.drive_type_create(context, values) - - -def drive_type_update(context, drive_type_id, values): - """Updates drive type record.""" - return IMPL.drive_type_update(context, drive_type_id, values) - - -def drive_type_destroy(context, drive_type_id): - """Deletes drive type record.""" - return IMPL.drive_type_destroy(context, drive_type_id) - - -def drive_type_get(context, drive_type_id): - """Get drive type record by id.""" - return IMPL.drive_type_get(context, drive_type_id) - - -def drive_type_get_by_name(context, name): - """Get drive type record by name.""" - return IMPL.drive_type_get_by_name(context, name) - - -def drive_type_get_all(context, visible): - """Returns all (or only visible) drive types.""" - return IMPL.drive_type_get_all(context, visible) - - def vsa_create(context, values): """Creates Virtual Storage Array record.""" return IMPL.vsa_create(context, values) @@ -1586,8 +1546,3 @@ def vsa_get_all(context): def vsa_get_all_by_project(context, project_id): """Get all Virtual Storage Array records by project ID.""" return IMPL.vsa_get_all_by_project(context, project_id) - - -def vsa_get_vc_ips_list(context, vsa_id): - """Retrieves IPs of instances associated with Virtual Storage Array.""" - return IMPL.vsa_get_vc_ips_list(context, vsa_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 7a572f55a..65b09a65d 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2226,7 +2226,6 @@ def volume_get(context, volume_id, session=None): options(joinedload('instance')).\ options(joinedload('volume_metadata')).\ options(joinedload('volume_type')).\ - options(joinedload('drive_type')).\ filter_by(id=volume_id).\ filter_by(deleted=can_read_deleted(context)).\ first() @@ -2235,7 +2234,6 @@ def volume_get(context, volume_id, session=None): options(joinedload('instance')).\ options(joinedload('volume_metadata')).\ options(joinedload('volume_type')).\ - options(joinedload('drive_type')).\ filter_by(project_id=context.project_id).\ filter_by(id=volume_id).\ filter_by(deleted=False).\ @@ -2253,7 +2251,6 @@ def volume_get_all(context): options(joinedload('instance')).\ options(joinedload('volume_metadata')).\ options(joinedload('volume_type')).\ - options(joinedload('drive_type')).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -2265,7 +2262,6 @@ def volume_get_all_by_host(context, host): options(joinedload('instance')).\ options(joinedload('volume_metadata')).\ options(joinedload('volume_type')).\ - options(joinedload('drive_type')).\ filter_by(host=host).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -2277,7 +2273,6 @@ def volume_get_all_by_instance(context, instance_id): result = session.query(models.Volume).\ options(joinedload('volume_metadata')).\ options(joinedload('volume_type')).\ - options(joinedload('drive_type')).\ filter_by(instance_id=instance_id).\ filter_by(deleted=False).\ all() @@ -2286,28 +2281,6 @@ def volume_get_all_by_instance(context, instance_id): return result -@require_admin_context -def volume_get_all_assigned_to_vsa(context, vsa_id): - session = get_session() - result = session.query(models.Volume).\ - options(joinedload('drive_type')).\ - filter_by(to_vsa_id=vsa_id).\ - filter_by(deleted=False).\ - all() - return result - - -@require_admin_context -def volume_get_all_assigned_from_vsa(context, vsa_id): - session = get_session() - result = session.query(models.Volume).\ - options(joinedload('drive_type')).\ - filter_by(from_vsa_id=vsa_id).\ - filter_by(deleted=False).\ - all() - return result - - @require_context def volume_get_all_by_project(context, project_id): authorize_project_context(context, project_id) @@ -2317,7 +2290,6 @@ def volume_get_all_by_project(context, project_id): options(joinedload('instance')).\ options(joinedload('volume_metadata')).\ options(joinedload('volume_type')).\ - options(joinedload('drive_type')).\ filter_by(project_id=project_id).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -2332,7 +2304,6 @@ def volume_get_instance(context, volume_id): options(joinedload('instance')).\ options(joinedload('volume_metadata')).\ options(joinedload('volume_type')).\ - options(joinedload('drive_type')).\ first() if not result: raise exception.VolumeNotFound(volume_id=volume_id) @@ -2377,7 +2348,7 @@ def volume_update(context, volume_id, values): volume_ref = volume_get(context, volume_id, session=session) volume_ref.update(values) volume_ref.save(session=session) - return volume_ref + #################### @@ -3871,106 +3842,6 @@ def volume_type_extra_specs_update_or_create(context, volume_type_id, #################### -@require_admin_context -def drive_type_create(context, values): - """ - Creates drive type record. - """ - try: - drive_type_ref = models.DriveTypes() - drive_type_ref.update(values) - drive_type_ref.save() - except Exception, e: - raise exception.DBError(e) - return drive_type_ref - - -@require_admin_context -def drive_type_update(context, drive_type_id, values): - """ - Updates drive type record. - """ - session = get_session() - with session.begin(): - drive_type_ref = drive_type_get(context, drive_type_id, - session=session) - drive_type_ref.update(values) - drive_type_ref.save(session=session) - return drive_type_ref - - -@require_admin_context -def drive_type_destroy(context, drive_type_id): - """ - Deletes drive type record. - """ - session = get_session() - drive_type_ref = session.query(models.DriveTypes).\ - filter_by(id=drive_type_id) - records = drive_type_ref.delete() - if records == 0: - raise exception.VirtualDiskTypeNotFound(id=drive_type_id) - - -@require_context -def drive_type_get(context, drive_type_id, session=None): - """ - Get drive type record by id. - """ - if not session: - session = get_session() - - result = session.query(models.DriveTypes).\ - filter_by(id=drive_type_id).\ - filter_by(deleted=can_read_deleted(context)).\ - first() - if not result: - raise exception.VirtualDiskTypeNotFound(id=drive_type_id) - - return result - - -@require_context -def drive_type_get_by_name(context, name, session=None): - """ - Get drive type record by name. - """ - if not session: - session = get_session() - - result = session.query(models.DriveTypes).\ - filter_by(name=name).\ - filter_by(deleted=can_read_deleted(context)).\ - first() - if not result: - raise exception.VirtualDiskTypeNotFoundByName(name=name) - - return result - - -@require_context -def drive_type_get_all(context, visible): - """ - Returns all (or only visible) drive types. - """ - session = get_session() - if visible: - drive_types = session.query(models.DriveTypes).\ - filter_by(deleted=can_read_deleted(context)).\ - filter_by(visible=True).\ - order_by("name").\ - all() - else: - drive_types = session.query(models.DriveTypes).\ - filter_by(deleted=can_read_deleted(context)).\ - order_by("name").\ - all() - return drive_types - - - #################### - - @require_admin_context def vsa_create(context, values): """ @@ -4067,26 +3938,4 @@ def vsa_get_all_by_project(context, project_id): all() -@require_context -def vsa_get_vc_ips_list(context, vsa_id): - """ - Retrieves IPs of instances associated with Virtual Storage Array. - """ - result = [] - - vc_instances = instance_get_all_by_filters(context, - search_opts={'metadata': dict(vsa_id=str(vsa_id))}) - for vc_instance in vc_instances: - if vc_instance['fixed_ips']: - for fixed in vc_instance['fixed_ips']: - # insert the [floating,fixed] (if exists) in the head, - # otherwise append the [none,fixed] in the tail - ip = {} - ip['fixed'] = fixed['address'] - if fixed['floating_ips']: - ip['floating'] = fixed['floating_ips'][0]['address'] - result.append(ip) - - return result - #################### diff --git a/nova/db/sqlalchemy/migrate_repo/versions/042_add_vsa_data.py b/nova/db/sqlalchemy/migrate_repo/versions/042_add_vsa_data.py deleted file mode 100644 index 8a57bd234..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/042_add_vsa_data.py +++ /dev/null @@ -1,133 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2011 Zadara Storage Inc. -# Copyright (c) 2011 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, DateTime, Integer, MetaData, String, Table -from sqlalchemy import Text, Boolean, ForeignKey - -from nova import log as logging - -meta = MetaData() - -# Just for the ForeignKey and column creation to succeed, these are not the -# actual definitions of tables . -# - -volumes = Table('volumes', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - -to_vsa_id = Column('to_vsa_id', Integer(), nullable=True) -from_vsa_id = Column('from_vsa_id', Integer(), nullable=True) -drive_type_id = Column('drive_type_id', Integer(), nullable=True) - - -# New Tables -# - -virtual_storage_arrays = Table('virtual_storage_arrays', 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('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)), - Column('project_id', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('availability_zone', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('instance_type_id', Integer(), nullable=False), - Column('image_ref', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('vc_count', Integer(), nullable=False), - Column('vol_count', Integer(), nullable=False), - Column('status', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - ) - -drive_types = Table('drive_types', 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('name', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False), - unique=True), - Column('type', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('size_gb', Integer(), nullable=False), - Column('rpm', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('capabilities', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('visible', Boolean(create_constraint=True, name=None)), - ) - -new_tables = (virtual_storage_arrays, drive_types) - -# -# Tables to alter -# - - -def upgrade(migrate_engine): - - from nova import context - from nova import db - from nova import flags - - FLAGS = flags.FLAGS - - # Upgrade operations go here. Don't create your own engine; - # bind migrate_engine to your metadata - meta.bind = migrate_engine - - for table in new_tables: - try: - table.create() - except Exception: - logging.info(repr(table)) - logging.exception('Exception while creating table') - raise - - volumes.create_column(to_vsa_id) - volumes.create_column(from_vsa_id) - volumes.create_column(drive_type_id) - - -def downgrade(migrate_engine): - meta.bind = migrate_engine - - volumes.drop_column(to_vsa_id) - volumes.drop_column(from_vsa_id) - volumes.drop_column(drive_type_id) - - for table in new_tables: - table.drop() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/043_add_vsa_data.py b/nova/db/sqlalchemy/migrate_repo/versions/043_add_vsa_data.py new file mode 100644 index 000000000..844643704 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/043_add_vsa_data.py @@ -0,0 +1,75 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 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, DateTime, Integer, MetaData, String, Table +from sqlalchemy import Text, Boolean, ForeignKey + +from nova import log as logging + +meta = MetaData() + +# +# New Tables +# + +virtual_storage_arrays = Table('virtual_storage_arrays', 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('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)), + Column('project_id', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('availability_zone', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('instance_type_id', Integer(), nullable=False), + Column('image_ref', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('vc_count', Integer(), nullable=False), + Column('vol_count', Integer(), nullable=False), + Column('status', + 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: + virtual_storage_arrays.create() + except Exception: + logging.info(repr(table)) + logging.exception('Exception while creating table') + raise + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + virtual_storage_arrays.drop() diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 65464ece5..f8feb0b4f 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -352,13 +352,6 @@ class Volume(BASE, NovaBase): volume_type_id = Column(Integer) - to_vsa_id = Column(Integer, - ForeignKey('virtual_storage_arrays.id'), nullable=True) - from_vsa_id = Column(Integer, - ForeignKey('virtual_storage_arrays.id'), nullable=True) - drive_type_id = Column(Integer, - ForeignKey('drive_types.id'), nullable=True) - class VolumeMetadata(BASE, NovaBase): """Represents a metadata key/value pair for a volume""" @@ -402,38 +395,6 @@ class VolumeTypeExtraSpecs(BASE, NovaBase): 'VolumeTypeExtraSpecs.deleted == False)') -class DriveTypes(BASE, NovaBase): - """Represents the known drive types (storage media).""" - __tablename__ = 'drive_types' - - id = Column(Integer, primary_key=True, autoincrement=True) - - """ - @property - def name(self): - if self.capabilities: - return FLAGS.drive_type_template_long % \ - (self.type, str(self.size_gb), self.rpm, self.capabilities) - else: - return FLAGS.drive_type_template_short % \ - (self.type, str(self.size_gb), self.rpm) - """ - - name = Column(String(255), unique=True) - type = Column(String(255)) - size_gb = Column(Integer) - rpm = Column(String(255)) - capabilities = Column(String(255)) - - visible = Column(Boolean, default=True) - - volumes = relationship(Volume, - backref=backref('drive_type', uselist=False), - foreign_keys=id, - primaryjoin='and_(Volume.drive_type_id == ' - 'DriveTypes.id)') - - class Quota(BASE, NovaBase): """Represents a single quota override for a project. @@ -918,7 +879,9 @@ def register_models(): Network, SecurityGroup, SecurityGroupIngressRule, SecurityGroupInstanceAssociation, AuthToken, User, Project, Certificate, ConsolePool, Console, Zone, - AgentBuild, InstanceMetadata, InstanceTypeExtraSpecs, Migration) + VolumeMetadata, VolumeTypes, VolumeTypeExtraSpecs, + AgentBuild, InstanceMetadata, InstanceTypeExtraSpecs, Migration, + VirtualStorageArray) engine = create_engine(FLAGS.sql_connection, echo=False) for model in models: model.metadata.create_all(engine) diff --git a/nova/db/sqlalchemy/session.py b/nova/db/sqlalchemy/session.py index 7b717115c..643e2338e 100644 --- a/nova/db/sqlalchemy/session.py +++ b/nova/db/sqlalchemy/session.py @@ -30,9 +30,11 @@ import nova.exception import nova.flags import nova.log + FLAGS = nova.flags.FLAGS LOG = nova.log.getLogger("nova.db.sqlalchemy") + try: import MySQLdb except ImportError: -- cgit