From 79779eae788dee00af8523a1f6a0fb9dce07a68e Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Fri, 27 May 2011 11:09:20 +0900 Subject: db: add a table for block device mapping This patch adds a new table for block device mapping and helper APIs for it. --- nova/db/api.py | 28 +++++++ nova/db/sqlalchemy/api.py | 56 ++++++++++++++ .../versions/021_add_block_device_mapping.py | 85 ++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 40 ++++++++++ 4 files changed, 209 insertions(+) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/021_add_block_device_mapping.py (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 3597732b9..858c8eb10 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -920,6 +920,34 @@ def snapshot_update(context, snapshot_id, values): #################### +def block_device_mapping_create(context, values): + """Create an entry of block device mapping""" + return IMPL.block_device_mapping_create(context, values) + +def block_device_mapping_update(context, bdm_id, values): + """Create an entry of block device mapping""" + return IMPL.block_device_mapping_update(context, bdm_id, values) + +def block_device_mapping_get_all_by_instance(context, instance_id): + """Get all block device mapping blonging to a instance""" + return IMPL.block_device_mapping_get_all_by_instance(context, instance_id) + + +def block_device_mapping_destroy(context, bdm_id): + """Destroy the block device mapping.""" + return IMPL.block_device_mapping_destroy(context, bdm_id) + + +def block_device_mapping_destroy_by_instance_and_volume(context, instance_id, + volume_id): + """Destroy the block device mapping or raise if it does not exist.""" + return IMPL.block_device_mapping_destroy_by_instance_and_volume( + context, instance_id, volume_id) + + +#################### + + 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 cf8fc62db..e0904b3c6 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1864,6 +1864,62 @@ def snapshot_update(context, snapshot_id, values): ################### +@require_context +def block_device_mapping_create(context, values): + bdm_ref = models.BlockDeviceMapping() + bdm_ref.update(values) + + session = get_session() + with session.begin(): + bdm_ref.save(session=session) + +@require_context +def block_device_mapping_update(context, bdm_id, values): + session = get_session() + with session.begin(): + session.query(models.BlockDeviceMapping).\ + filter_by(id=bdm_id).\ + filter_by(deleted=False).\ + update(values) + +@require_context +def block_device_mapping_get_all_by_instance(context, instance_id): + session = get_session() + result = session.query(models.BlockDeviceMapping).\ + filter_by(instance_id=instance_id).\ + filter_by(deleted=False).\ + all() + if not result: + raise exception.NotFound() + return result + +@require_context +def block_device_mapping_destroy(context, bdm_id): + session = get_session() + with session.begin(): + session.query(models.BlockDeviceMapping).\ + filter_by(id=bdm_id).\ + update({'deleted': 1, + 'deleted_at': datetime.datetime.utcnow(), + 'updated_at': literal_column('updated_at')}) + +@require_context +def block_device_mapping_destroy_by_instance_and_volume(context, instance_id, + volume_id): + session = get_session() + with session.begin(): + session.query(models.BlockDeviceMapping).\ + filter_by(instance_id=instance_id).\ + filter_by(volume_id=volume_id).\ + filter_by(deleted=False).\ + update({'deleted': 1, + 'deleted_at': datetime.datetime.utcnow(), + 'updated_at': literal_column('updated_at')}) + + +################### + + @require_context def security_group_get_all(context): session = get_session() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/021_add_block_device_mapping.py b/nova/db/sqlalchemy/migrate_repo/versions/021_add_block_device_mapping.py new file mode 100644 index 000000000..ed4296334 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/021_add_block_device_mapping.py @@ -0,0 +1,85 @@ +# Copyright 2011 OpenStack LLC. +# Copyright 2011 Isaku Yamahata +# +# 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 MetaData, Table, Column +from sqlalchemy import DateTime, Boolean, Integer, String +from sqlalchemy import 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 instances or services. +instances = Table('instances', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +volumes = Table('volumes', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +snapshots = Table('snapshots', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + + +block_device_mapping = Table('block_device_mapping', 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, autoincrement=True), + Column('instance_id', + Integer(), + ForeignKey('instances.id'), + nullable=False), + Column('device_name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + nullable=False), + Column('delete_on_termination', + Boolean(create_constraint=True, name=None), + default=False), + Column('virtual_name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + nullable=True), + Column('snapshot_id', + Integer(), + ForeignKey('snapshots.id'), + nullable=True), + Column('volume_id', Integer(), ForeignKey('volumes.id'), nullable=True), + Column('volume_size', Integer(), nullable=True), + Column('no_device', + Boolean(create_constraint=True, name=None), + 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 + try: + block_device_mapping.create() + except Exception: + logging.info(repr(block_device_mapping)) + logging.exception('Exception while creating table') + meta.drop_all(tables=[block_device_mapping]) + raise + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + block_device_mapping.drop() diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 32838d386..a74db811f 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -355,6 +355,46 @@ class Snapshot(BASE, NovaBase): display_name = Column(String(255)) display_description = Column(String(255)) + +class BlockDeviceMapping(BASE, NovaBase): + """Represents block device mapping that is defined by EC2""" + __tablename__ = "block_device_mapping" + id = Column(Integer, primary_key=True, autoincrement=True) + + instance_id = Column(Integer, ForeignKey('instances.id'), nullable=False) + instance = relationship(Instance, + backref=backref('balock_device_mapping'), + foreign_keys=instance_id, + primaryjoin='and_(BlockDeviceMapping.instance_id==' + 'Instance.id,' + 'BlockDeviceMapping.deleted==' + 'False)') + device_name = Column(String(255), nullable=False) + + # default=False for compatilibity of the existing code. + # With EC2 API, + # default True for ami specified device. + # default False for created with other timing. + delete_on_termination = Column(Boolean, default=False) + + # for ephemeral device + virtual_name = Column(String(255), nullable=True) + + # for snapshot or volume + snapshot_id = Column(Integer, ForeignKey('snapshots.id'), nullable=True) + # outer join + snapshot = relationship(Snapshot, + foreign_keys=snapshot_id) + + volume_id = Column(Integer, ForeignKey('volumes.id'), nullable=True) + volume = relationship(Volume, + foreign_keys=volume_id) + volume_size = Column(Integer, nullable=True) + + # for no device to supress devices. + no_device = Column(Boolean, nullable=True) + + class ExportDevice(BASE, NovaBase): """Represates a shelf and blade that a volume can be exported on.""" __tablename__ = 'export_devices' -- cgit From ab938bf376efe7a93b54e4ca595d3102d04b0080 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Fri, 27 May 2011 11:10:24 +0900 Subject: compute: implement ec2 stop/start instances This patch implements ec2 stop/start instances with block device mapping support. --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 858c8eb10..7fb7f336f 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -414,6 +414,11 @@ def instance_destroy(context, instance_id): return IMPL.instance_destroy(context, instance_id) +def instance_stop(context, instance_id): + """Stop the instance or raise if it does not exist.""" + return IMPL.instance_stop(context, instance_id) + + def instance_get(context, instance_id): """Get an instance or raise if it does not exist.""" return IMPL.instance_get(context, instance_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e0904b3c6..be47e2c2e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -831,6 +831,24 @@ def instance_destroy(context, instance_id): 'deleted_at': datetime.datetime.utcnow(), 'updated_at': literal_column('updated_at')}) +@require_context +def instance_stop(context, instance_id): + session = get_session() + with session.begin(): + from nova.compute import power_state + session.query(models.Instance).\ + filter_by(id=instance_id).\ + update({'host': None, + 'state': power_state.SHUTOFF, + 'state_description': 'stopped', + 'updated_at': literal_column('updated_at')}) + session.query(models.SecurityGroupInstanceAssociation).\ + filter_by(instance_id=instance_id).\ + update({'updated_at': literal_column('updated_at')}) + session.query(models.InstanceMetadata).\ + filter_by(instance_id=instance_id).\ + update({'updated_at': literal_column('updated_at')}) + @require_context def instance_get(context, instance_id, session=None): -- cgit From a66ae006e0a6103ee6db49ad2b8dc4506969178e Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Wed, 8 Jun 2011 15:45:23 +0000 Subject: Look for vm_mode property on images and use that if it exists to determine if image should be run in PV or HVM mode. If it doesn't exist, fall back to existing logic --- .../versions/022_add_vm_mode_to_instances.py | 43 ++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 1 + 2 files changed, 44 insertions(+) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/022_add_vm_mode_to_instances.py (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/022_add_vm_mode_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/022_add_vm_mode_to_instances.py new file mode 100644 index 000000000..5b6a25e41 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/022_add_vm_mode_to_instances.py @@ -0,0 +1,43 @@ +# 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 + +meta = MetaData() + +instances = Table('instances', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +instances_vm_mode = Column('vm_mode', + 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 + + instances.create_column(instances_vm_mode) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + instances.drop_column('vm_mode') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 239f6e96a..612ccc93f 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -232,6 +232,7 @@ class Instance(BASE, NovaBase): locked = Column(Boolean) os_type = Column(String(255)) + vm_mode = Column(String(255)) # TODO(vish): see Ewan's email about state improvements, probably # should be in a driver base class or some such -- cgit From 467bda72a05a0fd9fa4d7d417da422eea04de220 Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Thu, 9 Jun 2011 18:51:21 +0000 Subject: 022 migration has already been added, so make ours 023 now --- .../versions/022_add_vm_mode_to_instances.py | 43 ---------------------- .../versions/023_add_vm_mode_to_instances.py | 43 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 43 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/022_add_vm_mode_to_instances.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/022_add_vm_mode_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/022_add_vm_mode_to_instances.py deleted file mode 100644 index 5b6a25e41..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/022_add_vm_mode_to_instances.py +++ /dev/null @@ -1,43 +0,0 @@ -# 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 - -meta = MetaData() - -instances = Table('instances', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - -instances_vm_mode = Column('vm_mode', - 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 - - instances.create_column(instances_vm_mode) - - -def downgrade(migrate_engine): - meta.bind = migrate_engine - - instances.drop_column('vm_mode') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py new file mode 100644 index 000000000..5b6a25e41 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py @@ -0,0 +1,43 @@ +# 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 + +meta = MetaData() + +instances = Table('instances', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +instances_vm_mode = Column('vm_mode', + 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 + + instances.create_column(instances_vm_mode) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + instances.drop_column('vm_mode') -- cgit From a86523d5ae17b4e5507b14fade0a87c5434f2cac Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Fri, 10 Jun 2011 17:26:25 +0000 Subject: Fix copyright year --- .../db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py index 5b6a25e41..16b9826d9 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py @@ -1,6 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2010 OpenStack LLC. +# Copyright 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 -- cgit From d9c2a7112ba239fb64ecc76ce844caed9146a5dc Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Mon, 13 Jun 2011 20:46:25 +0000 Subject: Load table schema automatically instead of stubbing out --- .../sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py index 16b9826d9..2f7bfddcb 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py @@ -18,9 +18,7 @@ from sqlalchemy import Column, Integer, MetaData, String, Table meta = MetaData() -instances = Table('instances', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) +instances = Table('instances', meta, autoload=True) instances_vm_mode = Column('vm_mode', String(length=255, convert_unicode=False, -- cgit From 70bb9494639ec26f12b71dc22052d3e5b343890f Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Tue, 14 Jun 2011 15:36:07 +0000 Subject: autoload with the appropriate engine during upgrade/downgrade --- .../migrate_repo/versions/023_add_vm_mode_to_instances.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py index 2f7bfddcb..0c587f569 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/023_add_vm_mode_to_instances.py @@ -18,8 +18,6 @@ from sqlalchemy import Column, Integer, MetaData, String, Table meta = MetaData() -instances = Table('instances', meta, autoload=True) - instances_vm_mode = Column('vm_mode', String(length=255, convert_unicode=False, assert_unicode=None, unicode_error=None, @@ -32,10 +30,16 @@ def upgrade(migrate_engine): # bind migrate_engine to your metadata meta.bind = migrate_engine + instances = Table('instances', meta, autoload=True, + autoload_with=migrate_engine) + instances.create_column(instances_vm_mode) def downgrade(migrate_engine): meta.bind = migrate_engine + instances = Table('instances', meta, autoload=True, + autoload_with=migrate_engine) + instances.drop_column('vm_mode') -- cgit From b0fdb4a2326f6e7c92bba80e6b80857ba2a61612 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 15 Jun 2011 22:58:22 +0900 Subject: typo --- nova/db/api.py | 2 +- nova/db/sqlalchemy/models.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 215fa5009..3f5e9a54a 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -934,7 +934,7 @@ def block_device_mapping_update(context, bdm_id, values): return IMPL.block_device_mapping_update(context, bdm_id, values) def block_device_mapping_get_all_by_instance(context, instance_id): - """Get all block device mapping blonging to a instance""" + """Get all block device mapping belonging to a instance""" return IMPL.block_device_mapping_get_all_by_instance(context, instance_id) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index a74db811f..0c3ec40c7 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -371,7 +371,7 @@ class BlockDeviceMapping(BASE, NovaBase): 'False)') device_name = Column(String(255), nullable=False) - # default=False for compatilibity of the existing code. + # default=False for compatibility of the existing code. # With EC2 API, # default True for ami specified device. # default False for created with other timing. @@ -391,7 +391,7 @@ class BlockDeviceMapping(BASE, NovaBase): foreign_keys=volume_id) volume_size = Column(Integer, nullable=True) - # for no device to supress devices. + # for no device to suppress devices. no_device = Column(Boolean, nullable=True) -- cgit From f48f35183f6bc30c0e053ea9569f5348799ed451 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 15 Jun 2011 23:11:03 +0900 Subject: pep8 --- nova/db/api.py | 2 ++ nova/db/sqlalchemy/api.py | 5 +++++ .../migrate_repo/versions/021_add_block_device_mapping.py | 6 ++++-- nova/db/sqlalchemy/models.py | 4 ++-- 4 files changed, 13 insertions(+), 4 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 3f5e9a54a..cf58e87e5 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -929,10 +929,12 @@ def block_device_mapping_create(context, values): """Create an entry of block device mapping""" return IMPL.block_device_mapping_create(context, values) + def block_device_mapping_update(context, bdm_id, values): """Create an entry of block device mapping""" return IMPL.block_device_mapping_update(context, bdm_id, values) + def block_device_mapping_get_all_by_instance(context, instance_id): """Get all block device mapping belonging to a instance""" return IMPL.block_device_mapping_get_all_by_instance(context, instance_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 9385519df..915b34016 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -832,6 +832,7 @@ def instance_destroy(context, instance_id): 'deleted_at': datetime.datetime.utcnow(), 'updated_at': literal_column('updated_at')}) + @require_context def instance_stop(context, instance_id): session = get_session() @@ -1892,6 +1893,7 @@ def block_device_mapping_create(context, values): with session.begin(): bdm_ref.save(session=session) + @require_context def block_device_mapping_update(context, bdm_id, values): session = get_session() @@ -1901,6 +1903,7 @@ def block_device_mapping_update(context, bdm_id, values): filter_by(deleted=False).\ update(values) + @require_context def block_device_mapping_get_all_by_instance(context, instance_id): session = get_session() @@ -1912,6 +1915,7 @@ def block_device_mapping_get_all_by_instance(context, instance_id): raise exception.NotFound() return result + @require_context def block_device_mapping_destroy(context, bdm_id): session = get_session() @@ -1922,6 +1926,7 @@ def block_device_mapping_destroy(context, bdm_id): 'deleted_at': datetime.datetime.utcnow(), 'updated_at': literal_column('updated_at')}) + @require_context def block_device_mapping_destroy_by_instance_and_volume(context, instance_id, volume_id): diff --git a/nova/db/sqlalchemy/migrate_repo/versions/021_add_block_device_mapping.py b/nova/db/sqlalchemy/migrate_repo/versions/021_add_block_device_mapping.py index ed4296334..6e9b806cb 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/021_add_block_device_mapping.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/021_add_block_device_mapping.py @@ -60,7 +60,8 @@ block_device_mapping = Table('block_device_mapping', meta, Integer(), ForeignKey('snapshots.id'), nullable=True), - Column('volume_id', Integer(), ForeignKey('volumes.id'), nullable=True), + Column('volume_id', Integer(), ForeignKey('volumes.id'), + nullable=True), Column('volume_size', Integer(), nullable=True), Column('no_device', Boolean(create_constraint=True, name=None), @@ -79,7 +80,8 @@ def upgrade(migrate_engine): logging.exception('Exception while creating table') meta.drop_all(tables=[block_device_mapping]) raise - + + def downgrade(migrate_engine): # Operations to reverse the above upgrade go here. block_device_mapping.drop() diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 0c3ec40c7..104f31143 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -385,12 +385,12 @@ class BlockDeviceMapping(BASE, NovaBase): # outer join snapshot = relationship(Snapshot, foreign_keys=snapshot_id) - + volume_id = Column(Integer, ForeignKey('volumes.id'), nullable=True) volume = relationship(Volume, foreign_keys=volume_id) volume_size = Column(Integer, nullable=True) - + # for no device to suppress devices. no_device = Column(Boolean, nullable=True) -- cgit From a9800765f7eb8430c67d15953bed202752c2e199 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Thu, 16 Jun 2011 00:32:03 +0900 Subject: db/block_device_mapping_get_all_by_instance: don't raise. Make db.block_device_mapping_get_all_by_instance() not raise, but returns empty list when no column found as all users catch notfound exception and ignore it. Thus ugly 'catch NotFound: pass' is eliminated. --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 915b34016..ddaae8ca5 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1912,7 +1912,7 @@ def block_device_mapping_get_all_by_instance(context, instance_id): filter_by(deleted=False).\ all() if not result: - raise exception.NotFound() + return [] return result -- cgit From e6eae8d21a7c261dae498f52430dbee60b28840e Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 15 Jun 2011 17:35:31 -0400 Subject: Added metadata joinedloads --- nova/db/sqlalchemy/api.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 73870d2f3..7119f43eb 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -907,6 +907,7 @@ def instance_get_all_by_host(context, host): 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(host=host).\ filter_by(deleted=can_read_deleted(context)).\ @@ -922,6 +923,7 @@ def instance_get_all_by_project(context, project_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(project_id=project_id).\ filter_by(deleted=can_read_deleted(context)).\ @@ -937,6 +939,7 @@ def instance_get_all_by_reservation(context, reservation_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(reservation_id=reservation_id).\ filter_by(deleted=can_read_deleted(context)).\ @@ -946,6 +949,7 @@ def instance_get_all_by_reservation(context, reservation_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(project_id=context.project_id).\ filter_by(reservation_id=reservation_id).\ @@ -959,6 +963,8 @@ def instance_get_project_vpn(context, project_id): return session.query(models.Instance).\ 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(project_id=project_id).\ filter_by(image_ref=str(FLAGS.vpn_image_id)).\ -- cgit From e2fa70fb9d2b6684823328a491e18c0f98184665 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 17 Jun 2011 17:40:48 -0400 Subject: moving instance existance logic down to api layer --- nova/db/sqlalchemy/api.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 73870d2f3..7cea3ba70 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -18,7 +18,7 @@ """ Implementation of SQLAlchemy backend. """ - +import traceback import warnings from nova import db @@ -2609,7 +2609,17 @@ def zone_get_all(context): #################### + +def require_instance_exists(func): + def new_func(context, instance_id, *args, **kwargs): + db.api.instance_get(context, instance_id) + return func(context, instance_id, *args, **kwargs) + new_func.__name__ = func.__name__ + return new_func + + @require_context +@require_instance_exists def instance_metadata_get(context, instance_id): session = get_session() @@ -2625,6 +2635,7 @@ def instance_metadata_get(context, instance_id): @require_context +@require_instance_exists def instance_metadata_delete(context, instance_id, key): session = get_session() session.query(models.InstanceMetadata).\ @@ -2637,6 +2648,7 @@ def instance_metadata_delete(context, instance_id, key): @require_context +@require_instance_exists def instance_metadata_delete_all(context, instance_id): session = get_session() session.query(models.InstanceMetadata).\ @@ -2648,6 +2660,7 @@ def instance_metadata_delete_all(context, instance_id): @require_context +@require_instance_exists def instance_metadata_get_item(context, instance_id, key): session = get_session() @@ -2664,6 +2677,7 @@ def instance_metadata_get_item(context, instance_id, key): @require_context +@require_instance_exists def instance_metadata_update_or_create(context, instance_id, metadata): session = get_session() -- cgit