From a776844e38c7e747397785a6ce6b1de1b043d850 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Tue, 1 Feb 2011 18:34:46 -0800 Subject: initial support for dynamic instance_types: db migration and model, stub tests and stub methods. --- nova/compute/instance_types.py | 12 ++++ .../sqlalchemy/migrate_repo/versions/003_cactus.py | 76 ++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 10 +++ nova/tests/api/openstack/test_flavors.py | 10 +++ 4 files changed, 108 insertions(+) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 196d6a8df..1b3d0d0eb 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -48,3 +48,15 @@ def get_by_flavor_id(flavor_id): if details['flavorid'] == flavor_id: return instance_type return FLAGS.default_instance_type + + +def list_flavors(): + return instance_type + + +def create_flavor(): + return instance_type + + +def delete_flavor(): + return instance_type diff --git a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py new file mode 100644 index 000000000..cc4a7aec0 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py @@ -0,0 +1,76 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# 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 * +from migrate import * + + +from nova import log as logging + + +meta = MetaData() + + +# +# New Tables +# +# Here are the old static instance types +# INSTANCE_TYPES = { +# 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), +# 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), +# 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), +# 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), +# 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} +instance_types = Table('instance_types', meta, + Column('created_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('memory_mb', Integer(), nullable=False), + Column('vcpus', Integer(), nullable=False), + Column('local_gb', Integer(), nullable=False), + Column('flavorid', Integer(), nullable=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: + instance_types.create() + except Exception: + logging.info(repr(table)) + logging.exception('Exception while creating table') + raise + + # TODO(ken-pepple) fix this to pre-populate the default EC2 types + #INSTANCE_TYPES = { + # 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + # 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + # 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + # 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + # 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + # for instance_type in INSTANCE_TYPES: + # try: + # prepopulate tables with EC2 types + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + # # Operations to reverse the above upgrade go here. + # for table in (instance_types): + # table.drop() + pass diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index c54ebe3ba..762425670 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -210,6 +210,16 @@ class InstanceActions(BASE, NovaBase): error = Column(Text) +class InstanceTypes(BASE, NovaBase): + """Represent possible instance_types or flavor of VM offered""" + __tablename__ = "instance_types" + id = Column(Integer, primary_key=True) + memory_mb = Column(Integer) + vcpus = Column(Integer) + local_gb = Column(Integer) + flavorid = Column(Integer) + + class Volume(BASE, NovaBase): """Represents a block storage device that can be attached to a vm.""" __tablename__ = 'volumes' diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 1bdaea161..05624c5a9 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -44,5 +44,15 @@ class FlavorsTest(unittest.TestCase): def test_get_flavor_by_id(self): pass + def test_create_favor(self): + pass + + def test_delete_flavor(self): + pass + + def test_list_flavors(self): + pass + + if __name__ == '__main__': unittest.main() -- cgit From 563a77fd4aa80da9bddac5cf7f8f27ed2dedb39d Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 3 Feb 2011 17:52:19 -0800 Subject: added seed data to migration --- .../sqlalchemy/migrate_repo/versions/003_cactus.py | 53 ++++++++++++---------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py index cc4a7aec0..c7e61dc05 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py @@ -15,9 +15,11 @@ from sqlalchemy import * from migrate import * - +from nova import api +from nova import db from nova import log as logging +import time meta = MetaData() @@ -25,17 +27,14 @@ meta = MetaData() # # New Tables # -# Here are the old static instance types -# INSTANCE_TYPES = { -# 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), -# 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), -# 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), -# 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), -# 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} instance_types = Table('instance_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('name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), Column('id', Integer(), primary_key=True, nullable=False), Column('memory_mb', Integer(), nullable=False), Column('vcpus', Integer(), nullable=False), @@ -53,24 +52,32 @@ def upgrade(migrate_engine): instance_types.create() except Exception: logging.info(repr(table)) - logging.exception('Exception while creating table') + logging.exception('Exception while creating instance_types table') raise - # TODO(ken-pepple) fix this to pre-populate the default EC2 types - #INSTANCE_TYPES = { - # 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - # 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - # 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), - # 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), - # 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} - # for instance_type in INSTANCE_TYPES: - # try: - # prepopulate tables with EC2 types + # Here are the old static instance types + INSTANCE_TYPES = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + try: + i = instance_types.insert() + for name, values in INSTANCE_TYPES.iteritems(): + # FIXME(kpepple) should we be seeding created_at / updated_at ? + # the_time = time.strftime("%Y-%m-%d %H:%M:%S") + i.execute({'name': name, 'memory_mb': values["memory_mb"], + 'vcpus': values["vcpus"], + 'local_gb': values["local_gb"], + 'flavorid': values["flavorid"]}) + except Exception: + logging.info(repr(table)) + logging.exception('Exception while seeding instance_types table') + raise def downgrade(migrate_engine): # Operations to reverse the above upgrade go here. - # # Operations to reverse the above upgrade go here. - # for table in (instance_types): - # table.drop() - pass + for table in (instance_types): + table.drop() -- cgit From 9be0770208b0e75c7d93ba10165b82d5be11be27 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 3 Feb 2011 17:57:46 -0800 Subject: flagged all INSTANCE_TYPES usage with FIXME comment. Added basic usage to nova-manage (needs formatting). created api methods. --- nova/api/ec2/admin.py | 1 + nova/api/openstack/flavors.py | 2 ++ nova/compute/api.py | 2 ++ nova/compute/instance_types.py | 17 ++++------------- nova/db/api.py | 20 ++++++++++++++++++++ nova/db/sqlalchemy/api.py | 31 +++++++++++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 1 + nova/tests/api/openstack/test_flavors.py | 30 +++++++++++++++++++----------- nova/tests/db/fakes.py | 1 + nova/tests/test_quota.py | 3 +++ nova/tests/test_xenapi.py | 1 + nova/virt/libvirt_conn.py | 2 ++ nova/virt/xenapi/vm_utils.py | 1 + 13 files changed, 88 insertions(+), 24 deletions(-) (limited to 'nova') diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index d7e899d12..55cca1041 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -79,6 +79,7 @@ class AdminController(object): def __str__(self): return 'AdminController' + # FIX-ME(kpepple) for dynamic flavors def describe_instance_types(self, _context, **_kwargs): return {'instanceTypeSet': [instance_dict(n, v) for n, v in instance_types.INSTANCE_TYPES.iteritems()]} diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index f620d4107..1f5185134 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -45,6 +45,7 @@ class Controller(wsgi.Controller): def show(self, req, id): """Return data about the given flavor id.""" + # FIX-ME(kpepple) for dynamic flavors for name, val in instance_types.INSTANCE_TYPES.iteritems(): if val['flavorid'] == int(id): item = dict(ram=val['memory_mb'], disk=val['local_gb'], @@ -54,4 +55,5 @@ class Controller(wsgi.Controller): def _all_ids(self): """Return the list of all flavorids.""" + # FIX-ME(kpepple) for dynamic flavors return [i['flavorid'] for i in instance_types.INSTANCE_TYPES.values()] diff --git a/nova/compute/api.py b/nova/compute/api.py index 1d8b9d79f..3ae722226 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -89,6 +89,8 @@ class API(base.Base): """Create the number of instances requested if quota and other arguments check out ok.""" + # FIXME(kpepple) this needs to be changed from using the old constant + #type_data = db.instance_type_get_by_name(context.get_admin_context(), instance_type) type_data = instance_types.INSTANCE_TYPES[instance_type] num_instances = quota.allowed_instances(context, max_count, type_data) if num_instances < min_count: diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 1b3d0d0eb..0594aa063 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -25,6 +25,7 @@ from nova import flags from nova import exception FLAGS = flags.FLAGS +# FIX-ME(kpepple) for dynamic flavors INSTANCE_TYPES = { 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), @@ -35,8 +36,9 @@ INSTANCE_TYPES = { def get_by_type(instance_type): """Build instance data structure and save it to the data store.""" + # FIX-ME(kpepple) for dynamic flavors if instance_type is None: - return FLAGS.default_instance_type + return FLAGS.default_instance_type if instance_type not in INSTANCE_TYPES: raise exception.ApiError(_("Unknown instance type: %s"), instance_type) @@ -44,19 +46,8 @@ def get_by_type(instance_type): def get_by_flavor_id(flavor_id): + # FIX-ME(kpepple) for dynamic flavors for instance_type, details in INSTANCE_TYPES.iteritems(): if details['flavorid'] == flavor_id: return instance_type return FLAGS.default_instance_type - - -def list_flavors(): - return instance_type - - -def create_flavor(): - return instance_type - - -def delete_flavor(): - return instance_type diff --git a/nova/db/api.py b/nova/db/api.py index c6c03fb0e..ffb1d08ce 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -985,3 +985,23 @@ def console_get_all_by_instance(context, instance_id): def console_get(context, console_id, instance_id=None): """Get a specific console (possibly on a given instance).""" return IMPL.console_get(context, console_id, instance_id) + + + ################## + + +def instance_type_create(context, values): + """Create a new instance type""" + return IMPL.instance_type_create(context, values) + +def instance_type_get_all(context): + """Get all instance types""" + return IMPL.instance_type_get_all(context) + +def instance_type_get_by_name(context, name): + """Get instance type by name""" + return IMPL.instance_type_get_by_name(context, name) + +def instance_type_destroy(context, name): + """Delete a instance type""" + return IMPL.instance_type_destroy(context,name) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index fa060228f..aa6434b65 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2018,3 +2018,34 @@ def console_get(context, console_id, instance_id=None): raise exception.NotFound(_("No console with id %(console_id)s" " %(idesc)s") % locals()) return result + + + ################## + + +@require_admin_context +def instance_type_create(context, values): + instance_type_ref = models.InstanceTypes() + instance_type_ref.update(values) + instance_type_ref.save() + return instance_type_ref + +def instance_type_get_all(context): + session = get_session() + return session.query(models.InstanceTypes).\ + filter_by(deleted=0) + +def instance_type_get_by_name(context, name): + session = get_session() + return session.query(models.InstanceTypes).\ + filter_by(name=name).\ + first() + +@require_admin_context +def instance_type_destroy(context,name): + session = get_session() + instance_type_ref = session.query(models.InstanceTypes).\ + filter_by(name=name) + rows = instance_type_ref.update(dict(deleted=1)) + return instance_type_ref + diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 762425670..44583861b 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -214,6 +214,7 @@ class InstanceTypes(BASE, NovaBase): """Represent possible instance_types or flavor of VM offered""" __tablename__ = "instance_types" id = Column(Integer, primary_key=True) + name = Column(String(255), unique=True) memory_mb = Column(Integer) vcpus = Column(Integer) local_gb = Column(Integer) diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 05624c5a9..0f0ed2e84 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -21,6 +21,8 @@ import stubout import webob import nova.api +from nova import context +from nova import db from nova.api.openstack import flavors from nova.tests.api.openstack import fakes @@ -33,6 +35,7 @@ class FlavorsTest(unittest.TestCase): fakes.stub_out_networking(self.stubs) fakes.stub_out_rate_limiting(self.stubs) fakes.stub_out_auth(self.stubs) + self.context = context.get_admin_context() def tearDown(self): self.stubs.UnsetAll() @@ -41,17 +44,22 @@ class FlavorsTest(unittest.TestCase): req = webob.Request.blank('/v1.0/flavors') res = req.get_response(fakes.wsgi_app()) - def test_get_flavor_by_id(self): - pass - - def test_create_favor(self): - pass - - def test_delete_flavor(self): - pass - - def test_list_flavors(self): - pass + def test_create_list_delete_favor(self): + # create a new flavor + starting_flavors = db.instance_type_get_all(self.context) + new_instance_type = dict(name="os1.big",memory_mb=512, vcpus=1, local_gb=120, flavorid=25) + new_flavor = db.instance_type_create(self.context, new_instance_type) + self.assertEqual(new_flavor["name"], new_instance_type["name"]) + # retrieve the newly created flavor + retrieved_new_flavor = db.instance_type_get_by_name(self.context, new_instance_type["name"]) + # self.assertEqual(len(tuple(retrieved_new_flavor)),1) + self.assertEqual(retrieved_new_flavor["memory_mb"], new_instance_type["memory_mb"]) + flavors = db.instance_type_get_all(self.context) + self.assertNotEqual(starting_flavors, flavors) + # delete the newly created flavor + delete_query = db.instance_type_destroy(self.context,new_instance_type["name"]) + retrieve_deleted_flavor = db.instance_type_get_by_name(self.context, new_instance_type["name"]) + self.assertEqual(retrieve_deleted_flavor["deleted"], 1) if __name__ == '__main__': diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 05bdd172e..6cf917d76 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -44,6 +44,7 @@ def stub_out_db_instance_api(stubs): def fake_instance_create(values): """ Stubs out the db.instance_create method """ + # FIX-ME(kpepple) for dynamic flavors type_data = instance_types.INSTANCE_TYPES[values['instance_type']] base_options = { diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py index 9548a8c13..f2c9c456f 100644 --- a/nova/tests/test_quota.py +++ b/nova/tests/test_quota.py @@ -75,15 +75,18 @@ class QuotaTestCase(test.TestCase): def test_quota_overrides(self): """Make sure overriding a projects quotas works""" + # FIX-ME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 2) db.quota_create(self.context, {'project_id': self.project.id, 'instances': 10}) + # FIX-ME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 4) db.quota_update(self.context, self.project.id, {'cores': 100}) + # FIX-ME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 10) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 9f5b266f3..e38bd4dab 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -225,6 +225,7 @@ class XenAPIVMTestCase(test.TestCase): vm = vms[0] # Check that m1.large above turned into the right thing. + # FIX-ME(kpepple) for dynamic flavors instance_type = instance_types.INSTANCE_TYPES['m1.large'] mem_kib = long(instance_type['memory_mb']) << 10 mem_bytes = str(mem_kib << 10) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index bd5c9c4ee..9ed6d4a71 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -611,6 +611,7 @@ class LibvirtConnection(object): user=user, project=project, size=size) + # FIX-ME(kpepple) for dynamic flavors type_data = instance_types.INSTANCE_TYPES[inst['instance_type']] if type_data['local_gb']: @@ -671,6 +672,7 @@ class LibvirtConnection(object): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) # FIXME(vish): stick this in db + # FIX-ME(kpepple) for dynamic flavors instance_type = instance['instance_type'] instance_type = instance_types.INSTANCE_TYPES[instance_type] ip_address = db.instance_get_fixed_address(context.get_admin_context(), diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 4afd28dd8..4d09b2afa 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -82,6 +82,7 @@ class VMHelper(HelperBase): the pv_kernel flag indicates whether the guest is HVM or PV """ + # FIX-ME(kpepple) for dynamic flavors instance_type = instance_types.INSTANCE_TYPES[instance.instance_type] mem = str(long(instance_type['memory_mb']) * 1024 * 1024) vcpus = str(instance_type['vcpus']) -- cgit From 25a5afbb783e28bd5303853bf09e4b254c938302 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 5 Feb 2011 01:14:45 -0800 Subject: added FIXME(kpepple) comments for all constant usage of INSTANCE_TYPES. updated api/ec2/admin.py to use the new instance_types db table --- nova/api/ec2/admin.py | 19 ++++++++++++++----- nova/api/openstack/flavors.py | 4 ++-- nova/compute/api.py | 3 ++- nova/compute/instance_types.py | 8 ++++---- nova/db/api.py | 5 ++++- nova/db/sqlalchemy/api.py | 9 ++++++--- .../db/sqlalchemy/migrate_repo/versions/003_cactus.py | 2 +- nova/tests/api/openstack/test_flavors.py | 18 ++++++++++++------ nova/tests/db/fakes.py | 2 +- nova/tests/test_quota.py | 6 +++--- nova/tests/test_xenapi.py | 2 +- nova/virt/libvirt_conn.py | 4 ++-- nova/virt/xenapi/vm_utils.py | 2 +- 13 files changed, 53 insertions(+), 31 deletions(-) (limited to 'nova') diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index 55cca1041..5a9e22bf7 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -63,8 +63,8 @@ def host_dict(host): return {} -def instance_dict(name, inst): - return {'name': name, +def instance_dict(inst): + return {'name': inst['name'], 'memory_mb': inst['memory_mb'], 'vcpus': inst['vcpus'], 'disk_gb': inst['local_gb'], @@ -79,10 +79,19 @@ class AdminController(object): def __str__(self): return 'AdminController' - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) this is untested code path. def describe_instance_types(self, _context, **_kwargs): - return {'instanceTypeSet': [instance_dict(n, v) for n, v in - instance_types.INSTANCE_TYPES.iteritems()]} + """Returns all active instance types data (vcpus, memory, etc.)""" + # return {'instanceTypeSet': [instance_dict(n, v) for n, v in + # instance_types.INSTANCE_TYPES.iteritems()]} + return {'instanceTypeSet': + [for i in db.instance_type_get_all(): instance_dict(i)]} + + # FIXME(kpepple) this is untested code path. + def describe_instance_type(self, _context, name, **_kwargs): + """Returns a specific active instance types data""" + return {'instanceTypeSet': + [instance_dict(db.instance_type_get_by_name(name))]} def describe_user(self, _context, name, **_kwargs): """Returns user data, including access and secret keys.""" diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 1f5185134..2416088f9 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -45,7 +45,7 @@ class Controller(wsgi.Controller): def show(self, req, id): """Return data about the given flavor id.""" - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors for name, val in instance_types.INSTANCE_TYPES.iteritems(): if val['flavorid'] == int(id): item = dict(ram=val['memory_mb'], disk=val['local_gb'], @@ -55,5 +55,5 @@ class Controller(wsgi.Controller): def _all_ids(self): """Return the list of all flavorids.""" - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors return [i['flavorid'] for i in instance_types.INSTANCE_TYPES.values()] diff --git a/nova/compute/api.py b/nova/compute/api.py index 3ae722226..78a34dff2 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -90,7 +90,8 @@ class API(base.Base): other arguments check out ok.""" # FIXME(kpepple) this needs to be changed from using the old constant - #type_data = db.instance_type_get_by_name(context.get_admin_context(), instance_type) + #type_data = db.instance_type_get_by_name(context.get_admin_context(), + # instance_type) type_data = instance_types.INSTANCE_TYPES[instance_type] num_instances = quota.allowed_instances(context, max_count, type_data) if num_instances < min_count: diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 0594aa063..449ec1d2e 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -25,7 +25,7 @@ from nova import flags from nova import exception FLAGS = flags.FLAGS -# FIX-ME(kpepple) for dynamic flavors +# FIXME(kpepple) for dynamic flavors INSTANCE_TYPES = { 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), @@ -36,9 +36,9 @@ INSTANCE_TYPES = { def get_by_type(instance_type): """Build instance data structure and save it to the data store.""" - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors if instance_type is None: - return FLAGS.default_instance_type + return FLAGS.default_instance_type if instance_type not in INSTANCE_TYPES: raise exception.ApiError(_("Unknown instance type: %s"), instance_type) @@ -46,7 +46,7 @@ def get_by_type(instance_type): def get_by_flavor_id(flavor_id): - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors for instance_type, details in INSTANCE_TYPES.iteritems(): if details['flavorid'] == flavor_id: return instance_type diff --git a/nova/db/api.py b/nova/db/api.py index ffb1d08ce..d5091794b 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -994,14 +994,17 @@ def instance_type_create(context, values): """Create a new instance type""" return IMPL.instance_type_create(context, values) + def instance_type_get_all(context): """Get all instance types""" return IMPL.instance_type_get_all(context) + def instance_type_get_by_name(context, name): """Get instance type by name""" return IMPL.instance_type_get_by_name(context, name) + def instance_type_destroy(context, name): """Delete a instance type""" - return IMPL.instance_type_destroy(context,name) + return IMPL.instance_type_destroy(context, name) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index aa6434b65..142b1aa33 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2030,10 +2030,13 @@ def instance_type_create(context, values): instance_type_ref.save() return instance_type_ref + def instance_type_get_all(context): session = get_session() return session.query(models.InstanceTypes).\ - filter_by(deleted=0) + filter_by(deleted=0).\ + all() + def instance_type_get_by_name(context, name): session = get_session() @@ -2041,11 +2044,11 @@ def instance_type_get_by_name(context, name): filter_by(name=name).\ first() + @require_admin_context -def instance_type_destroy(context,name): +def instance_type_destroy(context, name): session = get_session() instance_type_ref = session.query(models.InstanceTypes).\ filter_by(name=name) rows = instance_type_ref.update(dict(deleted=1)) return instance_type_ref - diff --git a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py index c7e61dc05..6523b6b38 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py @@ -68,7 +68,7 @@ def upgrade(migrate_engine): # FIXME(kpepple) should we be seeding created_at / updated_at ? # the_time = time.strftime("%Y-%m-%d %H:%M:%S") i.execute({'name': name, 'memory_mb': values["memory_mb"], - 'vcpus': values["vcpus"], + 'vcpus': values["vcpus"], 'deleted': 0, 'local_gb': values["local_gb"], 'flavorid': values["flavorid"]}) except Exception: diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 0f0ed2e84..b416e02d6 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -47,19 +47,25 @@ class FlavorsTest(unittest.TestCase): def test_create_list_delete_favor(self): # create a new flavor starting_flavors = db.instance_type_get_all(self.context) - new_instance_type = dict(name="os1.big",memory_mb=512, vcpus=1, local_gb=120, flavorid=25) + new_instance_type = dict(name="os1.big", memory_mb=512, + vcpus=1, local_gb=120, flavorid=25) new_flavor = db.instance_type_create(self.context, new_instance_type) self.assertEqual(new_flavor["name"], new_instance_type["name"]) # retrieve the newly created flavor - retrieved_new_flavor = db.instance_type_get_by_name(self.context, new_instance_type["name"]) + retrieved_new_flavor = db.instance_type_get_by_name( + self.context, + new_instance_type["name"]) # self.assertEqual(len(tuple(retrieved_new_flavor)),1) - self.assertEqual(retrieved_new_flavor["memory_mb"], new_instance_type["memory_mb"]) + self.assertEqual(retrieved_new_flavor["memory_mb"], + new_instance_type["memory_mb"]) flavors = db.instance_type_get_all(self.context) self.assertNotEqual(starting_flavors, flavors) # delete the newly created flavor - delete_query = db.instance_type_destroy(self.context,new_instance_type["name"]) - retrieve_deleted_flavor = db.instance_type_get_by_name(self.context, new_instance_type["name"]) - self.assertEqual(retrieve_deleted_flavor["deleted"], 1) + delete_query = db.instance_type_destroy(self.context, + new_instance_type["name"]) + deleted_flavor = db.instance_type_get_by_name(self.context, + new_instance_type["name"]) + self.assertEqual(deleted_flavor["deleted"], 1) if __name__ == '__main__': diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 6cf917d76..3b47fc867 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -44,7 +44,7 @@ def stub_out_db_instance_api(stubs): def fake_instance_create(values): """ Stubs out the db.instance_create method """ - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors type_data = instance_types.INSTANCE_TYPES[values['instance_type']] base_options = { diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py index f2c9c456f..c70803e05 100644 --- a/nova/tests/test_quota.py +++ b/nova/tests/test_quota.py @@ -75,18 +75,18 @@ class QuotaTestCase(test.TestCase): def test_quota_overrides(self): """Make sure overriding a projects quotas works""" - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 2) db.quota_create(self.context, {'project_id': self.project.id, 'instances': 10}) - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 4) db.quota_update(self.context, self.project.id, {'cores': 100}) - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 10) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index e38bd4dab..1d42f8da3 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -225,7 +225,7 @@ class XenAPIVMTestCase(test.TestCase): vm = vms[0] # Check that m1.large above turned into the right thing. - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors instance_type = instance_types.INSTANCE_TYPES['m1.large'] mem_kib = long(instance_type['memory_mb']) << 10 mem_bytes = str(mem_kib << 10) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 9ed6d4a71..e66115464 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -611,7 +611,7 @@ class LibvirtConnection(object): user=user, project=project, size=size) - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors type_data = instance_types.INSTANCE_TYPES[inst['instance_type']] if type_data['local_gb']: @@ -672,7 +672,7 @@ class LibvirtConnection(object): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) # FIXME(vish): stick this in db - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors instance_type = instance['instance_type'] instance_type = instance_types.INSTANCE_TYPES[instance_type] ip_address = db.instance_get_fixed_address(context.get_admin_context(), diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 4d09b2afa..3f0112609 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -82,7 +82,7 @@ class VMHelper(HelperBase): the pv_kernel flag indicates whether the guest is HVM or PV """ - # FIX-ME(kpepple) for dynamic flavors + # FIXME(kpepple) for dynamic flavors instance_type = instance_types.INSTANCE_TYPES[instance.instance_type] mem = str(long(instance_type['memory_mb']) * 1024 * 1024) vcpus = str(instance_type['vcpus']) -- cgit From 79ea4533df3bd8c58b96177c2979fab2987a842a Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 5 Feb 2011 02:45:53 -0800 Subject: converted openstack flavors over to use instance_types table. a few pep changes. --- nova/api/openstack/flavors.py | 22 ++++++++++++++-------- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 7 +++++++ .../sqlalchemy/migrate_repo/versions/003_cactus.py | 4 ++-- 4 files changed, 28 insertions(+), 10 deletions(-) (limited to 'nova') diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 2416088f9..7440af0b4 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -17,6 +17,8 @@ from webob import exc +from nova import db +from nova import context from nova.api.openstack import faults from nova.api.openstack import common from nova.compute import instance_types @@ -45,15 +47,19 @@ class Controller(wsgi.Controller): def show(self, req, id): """Return data about the given flavor id.""" - # FIXME(kpepple) for dynamic flavors - for name, val in instance_types.INSTANCE_TYPES.iteritems(): - if val['flavorid'] == int(id): - item = dict(ram=val['memory_mb'], disk=val['local_gb'], - id=val['flavorid'], name=name) - return dict(flavor=item) + # FIXME(kpepple) do we need admin context here ? + ctxt = context.get_admin_context() + val = db.instance_type_get_by_flavor_id(ctxt, id) + item = dict(ram=val['memory_mb'], disk=val['local_gb'], + id=val['flavorid'], name=val['name']) + return dict(flavor=item) raise faults.Fault(exc.HTTPNotFound()) def _all_ids(self): """Return the list of all flavorids.""" - # FIXME(kpepple) for dynamic flavors - return [i['flavorid'] for i in instance_types.INSTANCE_TYPES.values()] + # FIXME(kpepple) do we need admin context here ? + ctxt = context.get_admin_context() + flavor_ids = [] + for i in db.instance_type_get_all(ctxt): + flavor_ids.append(i['flavorid']) + return flavor_ids diff --git a/nova/db/api.py b/nova/db/api.py index d5091794b..2f1903ade 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1005,6 +1005,11 @@ def instance_type_get_by_name(context, name): return IMPL.instance_type_get_by_name(context, name) +def instance_type_get_by_flavor_id(context, id): + """Get instance type by name""" + return IMPL.instance_type_get_by_flavor_id(context, id) + + def instance_type_destroy(context, name): """Delete a instance type""" return IMPL.instance_type_destroy(context, name) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 142b1aa33..6c9af6e19 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2045,6 +2045,13 @@ def instance_type_get_by_name(context, name): first() +def instance_type_get_by_flavor_id(context, id): + session = get_session() + return session.query(models.InstanceTypes).\ + filter_by(flavorid=int(id)).\ + first() + + @require_admin_context def instance_type_destroy(context, name): session = get_session() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py index 6523b6b38..c5ae9ea72 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py @@ -19,7 +19,7 @@ from nova import api from nova import db from nova import log as logging -import time +import datetime meta = MetaData() @@ -66,7 +66,7 @@ def upgrade(migrate_engine): i = instance_types.insert() for name, values in INSTANCE_TYPES.iteritems(): # FIXME(kpepple) should we be seeding created_at / updated_at ? - # the_time = time.strftime("%Y-%m-%d %H:%M:%S") + # now = datetime.datatime.utcnow() i.execute({'name': name, 'memory_mb': values["memory_mb"], 'vcpus': values["vcpus"], 'deleted': 0, 'local_gb': values["local_gb"], -- cgit From fcd0a7b245470054718c94adf0da6a528a01f173 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 5 Feb 2011 13:49:38 -0800 Subject: corrected db.instance_types to return expect dict instead of lists. updated openstack flavors to expect dicts instead of lists. added deleted column to returned dict. --- nova/api/openstack/flavors.py | 12 +++++---- nova/db/sqlalchemy/api.py | 42 ++++++++++++++++++++++++++++---- nova/tests/api/openstack/test_flavors.py | 5 ++-- 3 files changed, 46 insertions(+), 13 deletions(-) (limited to 'nova') diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 7440af0b4..da38dd34d 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -17,7 +17,7 @@ from webob import exc -from nova import db +from nova import db from nova import context from nova.api.openstack import faults from nova.api.openstack import common @@ -50,8 +50,9 @@ class Controller(wsgi.Controller): # FIXME(kpepple) do we need admin context here ? ctxt = context.get_admin_context() val = db.instance_type_get_by_flavor_id(ctxt, id) - item = dict(ram=val['memory_mb'], disk=val['local_gb'], - id=val['flavorid'], name=val['name']) + v = val.values()[0] + item = dict(ram=v['memory_mb'], disk=v['local_gb'], + id=v['flavorid'], name=val.keys()[0]) return dict(flavor=item) raise faults.Fault(exc.HTTPNotFound()) @@ -60,6 +61,7 @@ class Controller(wsgi.Controller): # FIXME(kpepple) do we need admin context here ? ctxt = context.get_admin_context() flavor_ids = [] - for i in db.instance_type_get_all(ctxt): - flavor_ids.append(i['flavorid']) + inst_types = db.instance_type_get_all(ctxt) + for i in inst_types.keys(): + flavor_ids.append(inst_types[i]['flavorid']) return flavor_ids diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 6c9af6e19..83c88a3a0 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2032,24 +2032,56 @@ def instance_type_create(context, values): def instance_type_get_all(context): + """Returns a dict of all instance_types: + { 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3)} + """ session = get_session() - return session.query(models.InstanceTypes).\ + inst_types = session.query(models.InstanceTypes).\ filter_by(deleted=0).\ all() + inst_dict = {} + for i in inst_types: + inst_dict[i['name']] = dict(memory_mb=i['memory_mb'], + vcpus=i['vcpus'], + local_gb=i['local_gb'], + flavorid=i['flavorid'], + deleted=i['deleted']) + + return inst_dict def instance_type_get_by_name(context, name): + """ + Returns a dict of specific instance_type: + {'m1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1)} + """ session = get_session() - return session.query(models.InstanceTypes).\ + inst_type = session.query(models.InstanceTypes).\ filter_by(name=name).\ first() + return {inst_type['name']: dict(memory_mb=inst_type['memory_mb'], + vcpus=inst_type['vcpus'], + local_gb=inst_type['local_gb'], + flavorid=inst_type['flavorid'], + deleted=inst_type['deleted'])} def instance_type_get_by_flavor_id(context, id): + """ + Returns a dict of specific flavor_id: + {'m1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1)} + """ session = get_session() - return session.query(models.InstanceTypes).\ - filter_by(flavorid=int(id)).\ - first() + inst_type = session.query(models.InstanceTypes).\ + filter_by(flavorid=int(id)).\ + first() + return {inst_type['name']: dict(memory_mb=inst_type['memory_mb'], + vcpus=inst_type['vcpus'], + local_gb=inst_type['local_gb'], + flavorid=inst_type['flavorid'], + deleted=inst_type['deleted'])} @require_admin_context diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index b416e02d6..9287e8adf 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -55,8 +55,7 @@ class FlavorsTest(unittest.TestCase): retrieved_new_flavor = db.instance_type_get_by_name( self.context, new_instance_type["name"]) - # self.assertEqual(len(tuple(retrieved_new_flavor)),1) - self.assertEqual(retrieved_new_flavor["memory_mb"], + self.assertEqual(retrieved_new_flavor.values()[0]["memory_mb"], new_instance_type["memory_mb"]) flavors = db.instance_type_get_all(self.context) self.assertNotEqual(starting_flavors, flavors) @@ -65,7 +64,7 @@ class FlavorsTest(unittest.TestCase): new_instance_type["name"]) deleted_flavor = db.instance_type_get_by_name(self.context, new_instance_type["name"]) - self.assertEqual(deleted_flavor["deleted"], 1) + self.assertEqual(deleted_flavor.values()[0]["deleted"], 1) if __name__ == '__main__': -- cgit From 5cd5d4e9682848cba60a8dec352fe0f74aaa9eac Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 5 Feb 2011 18:23:01 -0800 Subject: flavorid and name need to be unique in the database for the ec2 and openstack apis, repectively --- nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py index c5ae9ea72..f95996042 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py @@ -34,12 +34,13 @@ instance_types = Table('instance_types', meta, Column('deleted', Boolean(create_constraint=True, name=None)), Column('name', String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), + unicode_error=None, _warn_on_bytestring=False), + unique=True), Column('id', Integer(), primary_key=True, nullable=False), Column('memory_mb', Integer(), nullable=False), Column('vcpus', Integer(), nullable=False), Column('local_gb', Integer(), nullable=False), - Column('flavorid', Integer(), nullable=False), + Column('flavorid', Integer(), nullable=False, unique=True), ) -- cgit From d5a5324fee480152fd4e77f19fce5b025e1b4987 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 5 Feb 2011 18:26:53 -0800 Subject: instance_types should return in predicatable order (by name currently) --- nova/db/sqlalchemy/api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 83c88a3a0..0e2675a9f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2040,6 +2040,7 @@ def instance_type_get_all(context): session = get_session() inst_types = session.query(models.InstanceTypes).\ filter_by(deleted=0).\ + order_by("name").\ all() inst_dict = {} for i in inst_types: @@ -2090,4 +2091,4 @@ def instance_type_destroy(context, name): instance_type_ref = session.query(models.InstanceTypes).\ filter_by(name=name) rows = instance_type_ref.update(dict(deleted=1)) - return instance_type_ref + return rows -- cgit From 2acc31a293b067644f26877dc52bacb7ef9e9bd1 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 5 Feb 2011 18:28:26 -0800 Subject: added preliminary testing for bin/nova-manage while i am somewhat conflicted about the path these tests have taken, i think it is better than no tests at all --- nova/tests/test_nova_manage.py | 72 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 nova/tests/test_nova_manage.py (limited to 'nova') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py new file mode 100644 index 000000000..09ed8163b --- /dev/null +++ b/nova/tests/test_nova_manage.py @@ -0,0 +1,72 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# 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. +""" +Tests For Nova-Manage +""" + +import os +import subprocess + +from nova import test + + +class NovaManageTestCase(test.TestCase): + """Test case for nova-manage""" + def setUp(self): + super(NovaManageTestCase, self).setUp() + + def teardown(self): + fnull.close() + + def test_create_and_delete_instance_types(self): + fnull = open(os.devnull, 'w') + retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + "create", "test", "256", "1",\ + "120", "99"], stdout=fnull) + self.assertEqual(0, retcode) + retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + "delete", "test"], stdout=fnull) + self.assertEqual(0, retcode) + + def test_list_instance_types(self): + fnull = open(os.devnull, 'w') + retcode = subprocess.call(["bin/nova-manage", "instance_type", \ + "list"], stdout=fnull) + self.assertEqual(0, retcode) + + def test_list_specific_instance_type(self): + fnull = open(os.devnull, 'w') + retcode = subprocess.call(["bin/nova-manage", "instance_type", "list", + "m1.medium"], stdout=fnull) + self.assertEqual(0, retcode) + + def test_should_raise_on_bad_create_args(self): + fnull = open(os.devnull, 'w') + retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + "create", "test", "256", "0",\ + "120", "99"], stdout=fnull) + self.assertEqual(1, retcode) + + def test_should_fail_on_duplicate_flavorid(self): + fnull = open(os.devnull, 'w') + retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + "create", "test", "256", "1",\ + "120", "1"], stdout=fnull) + self.assertEqual(1, retcode) + + def test_instance_type_delete_should_fail_without_valid_name(self): + fnull = open(os.devnull, 'w') + retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + "delete", "saefasff"], stdout=fnull) + self.assertEqual(1, retcode) -- cgit From 555e5b5a0d3ae30f5d8b77d6b2dc47a953b4a81b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 5 Feb 2011 18:54:56 -0800 Subject: updated api.create to use instance_type table --- nova/compute/api.py | 7 +++---- nova/db/sqlalchemy/api.py | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'nova') diff --git a/nova/compute/api.py b/nova/compute/api.py index 78a34dff2..006db880e 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -89,10 +89,9 @@ class API(base.Base): """Create the number of instances requested if quota and other arguments check out ok.""" - # FIXME(kpepple) this needs to be changed from using the old constant - #type_data = db.instance_type_get_by_name(context.get_admin_context(), - # instance_type) - type_data = instance_types.INSTANCE_TYPES[instance_type] + # FIXME(kpepple) this needs to be factored for api.py:2065 refactor + type_data = db.instance_type_get_by_name(context,\ + instance_type)[instance_type] num_instances = quota.allowed_instances(context, max_count, type_data) if num_instances < min_count: pid = context.project_id diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 0e2675a9f..eff03aa02 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2062,6 +2062,7 @@ def instance_type_get_by_name(context, name): inst_type = session.query(models.InstanceTypes).\ filter_by(name=name).\ first() + # FIXME(kpepple) this needs to be refactored to just return dict return {inst_type['name']: dict(memory_mb=inst_type['memory_mb'], vcpus=inst_type['vcpus'], local_gb=inst_type['local_gb'], @@ -2078,6 +2079,7 @@ def instance_type_get_by_flavor_id(context, id): inst_type = session.query(models.InstanceTypes).\ filter_by(flavorid=int(id)).\ first() + # FIXME(kpepple) this needs to be refactored to just return dict return {inst_type['name']: dict(memory_mb=inst_type['memory_mb'], vcpus=inst_type['vcpus'], local_gb=inst_type['local_gb'], -- cgit From ea5271ed69d72dcab8189c3bfc66220c7ff60862 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sun, 6 Feb 2011 10:56:05 -0800 Subject: refactor to remove ugly code in flavors --- nova/api/openstack/flavors.py | 9 ++++----- nova/tests/db/fakes.py | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'nova') diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index da38dd34d..3124c26b2 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -47,9 +47,10 @@ class Controller(wsgi.Controller): def show(self, req, id): """Return data about the given flavor id.""" - # FIXME(kpepple) do we need admin context here ? + # FIXME(kpepple) do we really need admin context here ? ctxt = context.get_admin_context() val = db.instance_type_get_by_flavor_id(ctxt, id) + # FIXME(kpepple) refactor db call to return dict v = val.values()[0] item = dict(ram=v['memory_mb'], disk=v['local_gb'], id=v['flavorid'], name=val.keys()[0]) @@ -58,10 +59,8 @@ class Controller(wsgi.Controller): def _all_ids(self): """Return the list of all flavorids.""" - # FIXME(kpepple) do we need admin context here ? + # FIXME(kpepple) do we really need admin context here ? ctxt = context.get_admin_context() - flavor_ids = [] inst_types = db.instance_type_get_all(ctxt) - for i in inst_types.keys(): - flavor_ids.append(inst_types[i]['flavorid']) + flavor_ids = [inst_types[i]['flavorid'] for i in inst_types.keys()] return flavor_ids diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 3b47fc867..859ed6edc 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -46,6 +46,8 @@ def stub_out_db_instance_api(stubs): # FIXME(kpepple) for dynamic flavors type_data = instance_types.INSTANCE_TYPES[values['instance_type']] + # type_data = db.instance_type_get_by_name(context,\ + # instance_type)[instance_type] base_options = { 'name': values['name'], -- cgit From 7dcdbcc546248c3384bd15975a721413e1d1f507 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sun, 6 Feb 2011 13:28:07 -0800 Subject: simplified instance_types db calls to return entire row - we may need these extra columns for some features and there seems to be little downside in including them. still need to fix testing calls. --- nova/api/ec2/admin.py | 5 ++-- nova/api/openstack/flavors.py | 10 ++++---- nova/compute/api.py | 2 +- nova/db/sqlalchemy/api.py | 41 +++++++++----------------------- nova/tests/api/openstack/test_flavors.py | 22 ----------------- nova/tests/db/fakes.py | 2 +- 6 files changed, 21 insertions(+), 61 deletions(-) (limited to 'nova') diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index 5a9e22bf7..4c0628e21 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -84,8 +84,9 @@ class AdminController(object): """Returns all active instance types data (vcpus, memory, etc.)""" # return {'instanceTypeSet': [instance_dict(n, v) for n, v in # instance_types.INSTANCE_TYPES.iteritems()]} - return {'instanceTypeSet': - [for i in db.instance_type_get_all(): instance_dict(i)]} + # return {'instanceTypeSet': + # [for i in db.instance_type_get_all(): instance_dict(i)]} + return {'instanceTypeSet': [db.instance_type_get_all(_context)]} # FIXME(kpepple) this is untested code path. def describe_instance_type(self, _context, name, **_kwargs): diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 3124c26b2..9b674afbd 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -49,12 +49,12 @@ class Controller(wsgi.Controller): """Return data about the given flavor id.""" # FIXME(kpepple) do we really need admin context here ? ctxt = context.get_admin_context() - val = db.instance_type_get_by_flavor_id(ctxt, id) + values = db.instance_type_get_by_flavor_id(ctxt, id) # FIXME(kpepple) refactor db call to return dict - v = val.values()[0] - item = dict(ram=v['memory_mb'], disk=v['local_gb'], - id=v['flavorid'], name=val.keys()[0]) - return dict(flavor=item) + # v = val.values()[0] + # item = dict(ram=v['memory_mb'], disk=v['local_gb'], + # id=v['flavorid'], name=val.keys()[0]) + return dict(flavor=values) raise faults.Fault(exc.HTTPNotFound()) def _all_ids(self): diff --git a/nova/compute/api.py b/nova/compute/api.py index 006db880e..fc18765f6 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -91,7 +91,7 @@ class API(base.Base): # FIXME(kpepple) this needs to be factored for api.py:2065 refactor type_data = db.instance_type_get_by_name(context,\ - instance_type)[instance_type] + instance_type) num_instances = quota.allowed_instances(context, max_count, type_data) if num_instances < min_count: pid = context.project_id diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index eff03aa02..f4e021ac8 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2032,10 +2032,11 @@ def instance_type_create(context, values): def instance_type_get_all(context): - """Returns a dict of all instance_types: - { 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3)} + """ + Returns a dict describing all instance_types with name as key: + {'m1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3)} """ session = get_session() inst_types = session.query(models.InstanceTypes).\ @@ -2044,51 +2045,31 @@ def instance_type_get_all(context): all() inst_dict = {} for i in inst_types: - inst_dict[i['name']] = dict(memory_mb=i['memory_mb'], - vcpus=i['vcpus'], - local_gb=i['local_gb'], - flavorid=i['flavorid'], - deleted=i['deleted']) - + inst_dict[i['name']] = dict(i) return inst_dict def instance_type_get_by_name(context, name): - """ - Returns a dict of specific instance_type: - {'m1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1)} - """ + """Returns a dict describing specific instance_type""" session = get_session() inst_type = session.query(models.InstanceTypes).\ filter_by(name=name).\ first() - # FIXME(kpepple) this needs to be refactored to just return dict - return {inst_type['name']: dict(memory_mb=inst_type['memory_mb'], - vcpus=inst_type['vcpus'], - local_gb=inst_type['local_gb'], - flavorid=inst_type['flavorid'], - deleted=inst_type['deleted'])} + return dict(inst_type) def instance_type_get_by_flavor_id(context, id): - """ - Returns a dict of specific flavor_id: - {'m1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1)} - """ + """Returns a dict describing specific flavor_id""" session = get_session() inst_type = session.query(models.InstanceTypes).\ filter_by(flavorid=int(id)).\ first() - # FIXME(kpepple) this needs to be refactored to just return dict - return {inst_type['name']: dict(memory_mb=inst_type['memory_mb'], - vcpus=inst_type['vcpus'], - local_gb=inst_type['local_gb'], - flavorid=inst_type['flavorid'], - deleted=inst_type['deleted'])} + return dict(inst_type) @require_admin_context def instance_type_destroy(context, name): + """ Marks specific instance_type as deleted""" session = get_session() instance_type_ref = session.query(models.InstanceTypes).\ filter_by(name=name) diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 9287e8adf..532b34e1b 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -44,28 +44,6 @@ class FlavorsTest(unittest.TestCase): req = webob.Request.blank('/v1.0/flavors') res = req.get_response(fakes.wsgi_app()) - def test_create_list_delete_favor(self): - # create a new flavor - starting_flavors = db.instance_type_get_all(self.context) - new_instance_type = dict(name="os1.big", memory_mb=512, - vcpus=1, local_gb=120, flavorid=25) - new_flavor = db.instance_type_create(self.context, new_instance_type) - self.assertEqual(new_flavor["name"], new_instance_type["name"]) - # retrieve the newly created flavor - retrieved_new_flavor = db.instance_type_get_by_name( - self.context, - new_instance_type["name"]) - self.assertEqual(retrieved_new_flavor.values()[0]["memory_mb"], - new_instance_type["memory_mb"]) - flavors = db.instance_type_get_all(self.context) - self.assertNotEqual(starting_flavors, flavors) - # delete the newly created flavor - delete_query = db.instance_type_destroy(self.context, - new_instance_type["name"]) - deleted_flavor = db.instance_type_get_by_name(self.context, - new_instance_type["name"]) - self.assertEqual(deleted_flavor.values()[0]["deleted"], 1) - if __name__ == '__main__': unittest.main() diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 859ed6edc..3aa7fcd22 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -47,7 +47,7 @@ def stub_out_db_instance_api(stubs): # FIXME(kpepple) for dynamic flavors type_data = instance_types.INSTANCE_TYPES[values['instance_type']] # type_data = db.instance_type_get_by_name(context,\ - # instance_type)[instance_type] + # instance_type) base_options = { 'name': values['name'], -- cgit From ea5ba79802321bb25f03dfb24fd7fb01866d9921 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sun, 6 Feb 2011 13:48:03 -0800 Subject: aliased flavor to instance_types in nova-manage. will probably need to make flavor a full fledged class as users will want to list flavors by flavor name --- nova/tests/test_nova_manage.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'nova') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 09ed8163b..487f172ff 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -39,11 +39,12 @@ class NovaManageTestCase(test.TestCase): "delete", "test"], stdout=fnull) self.assertEqual(0, retcode) - def test_list_instance_types(self): + def test_list_instance_types_or_flavors(self): fnull = open(os.devnull, 'w') - retcode = subprocess.call(["bin/nova-manage", "instance_type", \ - "list"], stdout=fnull) - self.assertEqual(0, retcode) + for c in ["instance_type", "flavor"]: + retcode = subprocess.call(["bin/nova-manage", c, \ + "list"], stdout=fnull) + self.assertEqual(0, retcode) def test_list_specific_instance_type(self): fnull = open(os.devnull, 'w') -- cgit From 5a5e96ae90187e1ebfe93262df47ec2c4be23ef1 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 7 Feb 2011 13:00:39 -0800 Subject: require user context for most flavor/instance_type read calls --- nova/db/sqlalchemy/api.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'nova') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index f4e021ac8..6065af9ca 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2031,6 +2031,7 @@ def instance_type_create(context, values): return instance_type_ref +@require_context def instance_type_get_all(context): """ Returns a dict describing all instance_types with name as key: @@ -2049,6 +2050,7 @@ def instance_type_get_all(context): return inst_dict +@require_context def instance_type_get_by_name(context, name): """Returns a dict describing specific instance_type""" session = get_session() @@ -2058,6 +2060,7 @@ def instance_type_get_by_name(context, name): return dict(inst_type) +@require_context def instance_type_get_by_flavor_id(context, id): """Returns a dict describing specific flavor_id""" session = get_session() -- cgit From 346087804dd923bcaa0faf433dc1f83a2f193815 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 7 Feb 2011 13:32:25 -0800 Subject: fixed instance_types methods to use database backend --- nova/compute/instance_types.py | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 449ec1d2e..d38d76ded 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -21,6 +21,8 @@ The built-in instance properties. """ +from nova import context +from nova import db from nova import flags from nova import exception @@ -34,20 +36,39 @@ INSTANCE_TYPES = { 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} +def get_all_types(): + """retrieves all instance_types""" + return db.instance_type_get_all() + + +def get_all_flavors(): + """retrieves all flavors. alias for instance_types.get_all_types()""" + return get_all_types() + + def get_by_type(instance_type): - """Build instance data structure and save it to the data store.""" + """retrieve instance_type details""" # FIXME(kpepple) for dynamic flavors if instance_type is None: return FLAGS.default_instance_type - if instance_type not in INSTANCE_TYPES: + try: + ctxt = context.get_admin_context() + inst_type = db.instance_type_get_by_name(ctxt, instance_type) + except Exception, e: + print e raise exception.ApiError(_("Unknown instance type: %s"), instance_type) - return instance_type + return inst_type['name'] def get_by_flavor_id(flavor_id): - # FIXME(kpepple) for dynamic flavors - for instance_type, details in INSTANCE_TYPES.iteritems(): - if details['flavorid'] == flavor_id: - return instance_type - return FLAGS.default_instance_type + """retrieve instance_type's name by flavor_id""" + if flavor_id is None: + return FLAGS.default_instance_type + try: + ctxt = context.get_admin_context() + flavor = db.instance_type_get_by_flavor_id(ctxt, flavor_id) + except Exception, e: + raise exception.ApiError(_("Unknown flavor: %s"), + flavor_id) + return flavor['name'] -- cgit From bb2a379e2827ceccc5b46b0a9936e6dcedc6499e Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 7 Feb 2011 15:04:26 -0800 Subject: added INSTANCE_TYPES to test for compatibility with current tests --- nova/compute/instance_types.py | 12 ++++++------ nova/test.py | 8 ++++++++ nova/tests/db/fakes.py | 6 ++---- nova/tests/test_quota.py | 9 +++------ nova/tests/test_xenapi.py | 3 +-- nova/virt/libvirt_conn.py | 7 +++---- nova/virt/xenapi/vm_utils.py | 4 ++-- 7 files changed, 25 insertions(+), 24 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index d38d76ded..0e20982e3 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -28,12 +28,12 @@ from nova import exception FLAGS = flags.FLAGS # FIXME(kpepple) for dynamic flavors -INSTANCE_TYPES = { - 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), - 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), - 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} +# INSTANCE_TYPES = { +# 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), +# 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), +# 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), +# 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), +# 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} def get_all_types(): diff --git a/nova/test.py b/nova/test.py index 881baccd5..cd049f007 100644 --- a/nova/test.py +++ b/nova/test.py @@ -44,6 +44,14 @@ flags.DEFINE_bool('fake_tests', True, 'should we use everything for testing') +INSTANCE_TYPES = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + + def skip_if_fake(func): """Decorator that skips a test if running in fake mode""" def _skipper(*args, **kw): diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 3aa7fcd22..d9a5032ee 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -20,6 +20,7 @@ import time from nova import db +from nova import test from nova import utils from nova.compute import instance_types @@ -44,10 +45,7 @@ def stub_out_db_instance_api(stubs): def fake_instance_create(values): """ Stubs out the db.instance_create method """ - # FIXME(kpepple) for dynamic flavors - type_data = instance_types.INSTANCE_TYPES[values['instance_type']] - # type_data = db.instance_type_get_by_name(context,\ - # instance_type) + type_data = test.INSTANCE_TYPES[values['instance_type']] base_options = { 'name': values['name'], diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py index c70803e05..4206ca416 100644 --- a/nova/tests/test_quota.py +++ b/nova/tests/test_quota.py @@ -75,20 +75,17 @@ class QuotaTestCase(test.TestCase): def test_quota_overrides(self): """Make sure overriding a projects quotas works""" - # FIXME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, - instance_types.INSTANCE_TYPES['m1.small']) + test.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 2) db.quota_create(self.context, {'project_id': self.project.id, 'instances': 10}) - # FIXME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, - instance_types.INSTANCE_TYPES['m1.small']) + test.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 4) db.quota_update(self.context, self.project.id, {'cores': 100}) - # FIXME(kpepple) for dynamic flavors num_instances = quota.allowed_instances(self.context, 100, - instance_types.INSTANCE_TYPES['m1.small']) + test.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 10) db.quota_destroy(self.context, self.project.id) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 1d42f8da3..d8611ea10 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -225,8 +225,7 @@ class XenAPIVMTestCase(test.TestCase): vm = vms[0] # Check that m1.large above turned into the right thing. - # FIXME(kpepple) for dynamic flavors - instance_type = instance_types.INSTANCE_TYPES['m1.large'] + instance_type = test.INSTANCE_TYPES['m1.large'] mem_kib = long(instance_type['memory_mb']) << 10 mem_bytes = str(mem_kib << 10) vcpus = instance_type['vcpus'] diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index e66115464..94fe93c40 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -55,6 +55,7 @@ from nova import db from nova import exception from nova import flags from nova import log as logging +from nova import test from nova import utils #from nova.api import context from nova.auth import manager @@ -611,8 +612,7 @@ class LibvirtConnection(object): user=user, project=project, size=size) - # FIXME(kpepple) for dynamic flavors - type_data = instance_types.INSTANCE_TYPES[inst['instance_type']] + type_data = test.INSTANCE_TYPES[inst['instance_type']] if type_data['local_gb']: self._cache_image(fn=self._create_local, @@ -672,9 +672,8 @@ class LibvirtConnection(object): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) # FIXME(vish): stick this in db - # FIXME(kpepple) for dynamic flavors instance_type = instance['instance_type'] - instance_type = instance_types.INSTANCE_TYPES[instance_type] + instance_type = test.INSTANCE_TYPES[instance_type] ip_address = db.instance_get_fixed_address(context.get_admin_context(), instance['id']) # Assume that the gateway also acts as the dhcp server. diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 3f0112609..38a6f73ce 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -31,6 +31,7 @@ import glance.client from nova import exception from nova import flags from nova import log as logging +from nova import test from nova import utils from nova.auth.manager import AuthManager from nova.compute import instance_types @@ -82,8 +83,7 @@ class VMHelper(HelperBase): the pv_kernel flag indicates whether the guest is HVM or PV """ - # FIXME(kpepple) for dynamic flavors - instance_type = instance_types.INSTANCE_TYPES[instance.instance_type] + instance_type = test.INSTANCE_TYPES[instance.instance_type] mem = str(long(instance_type['memory_mb']) * 1024 * 1024) vcpus = str(instance_type['vcpus']) rec = { -- cgit From ffc788fb41bf5a4bcb85cfa80b3437ed94d46291 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Tue, 8 Feb 2011 11:24:05 -0800 Subject: additional error checking for nova-manage instance_type --- nova/db/sqlalchemy/api.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 6065af9ca..f084423e1 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2044,10 +2044,13 @@ def instance_type_get_all(context): filter_by(deleted=0).\ order_by("name").\ all() - inst_dict = {} - for i in inst_types: - inst_dict[i['name']] = dict(i) - return inst_dict + if inst_types: + inst_dict = {} + for i in inst_types: + inst_dict[i['name']] = dict(i) + return inst_dict + else: + raise exception.NotFound @require_context @@ -2057,7 +2060,10 @@ def instance_type_get_by_name(context, name): inst_type = session.query(models.InstanceTypes).\ filter_by(name=name).\ first() - return dict(inst_type) + if not inst_type: + raise exception.NotFound(_("No instance type with name %s") % name) + else: + return dict(inst_type) @require_context @@ -2067,7 +2073,10 @@ def instance_type_get_by_flavor_id(context, id): inst_type = session.query(models.InstanceTypes).\ filter_by(flavorid=int(id)).\ first() - return dict(inst_type) + if not inst_type: + raise exception.NotFound(_("No flavor with name %s") % id) + else: + return dict(inst_type) @require_admin_context @@ -2077,4 +2086,7 @@ def instance_type_destroy(context, name): instance_type_ref = session.query(models.InstanceTypes).\ filter_by(name=name) rows = instance_type_ref.update(dict(deleted=1)) - return rows + if not rows: + raise exception.NotFound(_("Couldn't delete instance type %s") % name) + else: + return rows -- cgit From 2f5d8a25c99875838a08ed06728bcd9d68cdd7f1 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Tue, 8 Feb 2011 11:31:20 -0800 Subject: added testing for nova-manage instance_type --- nova/tests/test_nova_manage.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'nova') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 487f172ff..5645bf97e 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -66,6 +66,17 @@ class NovaManageTestCase(test.TestCase): "120", "1"], stdout=fnull) self.assertEqual(1, retcode) + def test_should_fail_on_duplicate_name(self): + fnull = open(os.devnull, 'w') + retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + "create", "fsfsfsdfsdf", "256", "1",\ + "120", "189"], stdout=fnull) + self.assertEqual(0, retcode) + retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + "create", "fsfsfsdfsdf", "256", "1",\ + "120", "190"], stdout=fnull) + self.assertEqual(1, retcode) + def test_instance_type_delete_should_fail_without_valid_name(self): fnull = open(os.devnull, 'w') retcode = subprocess.call(["bin/nova-manage", "instance_type",\ -- cgit From cf562efb7441a761fcebf0653e4a886655826a10 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Tue, 8 Feb 2011 15:03:35 -0800 Subject: added create and delete methods to instance_types in preparation to call them from nova-manage --- nova/compute/instance_types.py | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 0e20982e3..af097672e 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -27,13 +27,28 @@ from nova import flags from nova import exception FLAGS = flags.FLAGS -# FIXME(kpepple) for dynamic flavors -# INSTANCE_TYPES = { -# 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), -# 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), -# 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), -# 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), -# 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + + +def create(name, memory, vcpus, local_gb, flavorid): + """Creates instance types / flavors + arguments: name memory_mb vcpus local_gb""" + for option in [memory, flavorid, local_gb, vcpus]: + if (option <= 0) or (option.__class__ == int): + raise InvalidParameters + db.instance_type_create(context.get_admin_context(), + dict(name=name, memory_mb=memory, + vcpus=vcpus, local_gb=local_gb, + flavorid=flavorid)) + + +def delete(name): + """Marks instance types / flavors as deleted + arguments: name""" + if name == None: + raise InvalidParameters + else: + records = db.instance_type_destroy(context.get_admin_context(), + name) def get_all_types(): @@ -48,17 +63,15 @@ def get_all_flavors(): def get_by_type(instance_type): """retrieve instance_type details""" - # FIXME(kpepple) for dynamic flavors if instance_type is None: return FLAGS.default_instance_type try: ctxt = context.get_admin_context() inst_type = db.instance_type_get_by_name(ctxt, instance_type) - except Exception, e: - print e + return inst_type['name'] + except exception.DBError: raise exception.ApiError(_("Unknown instance type: %s"), instance_type) - return inst_type['name'] def get_by_flavor_id(flavor_id): @@ -68,7 +81,7 @@ def get_by_flavor_id(flavor_id): try: ctxt = context.get_admin_context() flavor = db.instance_type_get_by_flavor_id(ctxt, flavor_id) - except Exception, e: + return flavor['name'] + except exception.DBError: raise exception.ApiError(_("Unknown flavor: %s"), flavor_id) - return flavor['name'] -- cgit From dd2544345e1686ee1ed020fd8f14607d10d8b3d1 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Tue, 8 Feb 2011 19:24:14 -0800 Subject: added testing for instance_types.py and refactored nova-manage to use instance_types.py instead of going directly to db. --- nova/compute/instance_types.py | 31 ++++++++++++++---- nova/db/sqlalchemy/api.py | 9 ++++-- nova/tests/test_instance_types.py | 67 +++++++++++++++++++++++++++++++++++++++ nova/tests/test_nova_manage.py | 4 +-- 4 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 nova/tests/test_instance_types.py (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index af097672e..b97a0da25 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -32,33 +32,50 @@ FLAGS = flags.FLAGS def create(name, memory, vcpus, local_gb, flavorid): """Creates instance types / flavors arguments: name memory_mb vcpus local_gb""" - for option in [memory, flavorid, local_gb, vcpus]: - if (option <= 0) or (option.__class__ == int): - raise InvalidParameters + for option in [memory, flavorid, vcpus]: + if option <= 0: + raise exception.InvalidInputException("Parameters incorrect") db.instance_type_create(context.get_admin_context(), dict(name=name, memory_mb=memory, vcpus=vcpus, local_gb=local_gb, flavorid=flavorid)) -def delete(name): +def destroy(name): """Marks instance types / flavors as deleted arguments: name""" if name == None: - raise InvalidParameters + raise exception.InvalidInputException else: records = db.instance_type_destroy(context.get_admin_context(), name) + if records == 0: + raise exception.NotFound("Cannot find instance type named %s" % name) + else: + return records def get_all_types(): """retrieves all instance_types""" - return db.instance_type_get_all() + return db.instance_type_get_all(context.get_admin_context()) def get_all_flavors(): """retrieves all flavors. alias for instance_types.get_all_types()""" - return get_all_types() + return get_all_types(context.get_admin_context()) + + +def get_instance_type(name): + """Retrieves single instance type by name""" + if name is None: + return FLAGS.default_instance_type + try: + ctxt = context.get_admin_context() + inst_type = db.instance_type_get_by_name(ctxt, name) + return inst_type + except exception.DBError: + raise exception.ApiError(_("Unknown instance type: %s"), + instance_type) def get_by_type(instance_type): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index f084423e1..e5afb8eac 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2025,9 +2025,12 @@ def console_get(context, console_id, instance_id=None): @require_admin_context def instance_type_create(context, values): - instance_type_ref = models.InstanceTypes() - instance_type_ref.update(values) - instance_type_ref.save() + try: + instance_type_ref = models.InstanceTypes() + instance_type_ref.update(values) + instance_type_ref.save() + except: + raise exception.DBError return instance_type_ref diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py new file mode 100644 index 000000000..819431763 --- /dev/null +++ b/nova/tests/test_instance_types.py @@ -0,0 +1,67 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# 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. +""" +Unit Tests for instance types code +""" +import datetime + +from nova import context +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova import utils +from nova.compute import instance_types +from nova.db.sqlalchemy.session import get_session +from nova.db.sqlalchemy import models + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.compute') + + +class InstanceTypeTestCase(test.TestCase): + """Test cases for instance type code""" + def setUp(self): + super(InstanceTypeTestCase, self).setUp() + session = get_session() + max_flavorid = session.query(models.InstanceTypes).\ + order_by("flavorid desc").first() + self.flavorid = max_flavorid["flavorid"] + 1 + self.name = str(datetime.datetime.utcnow()) + + def tearDown(self): + pass + + def test_instance_type_create_then_delete(self): + """Ensure instance types can be created""" + starting_inst_list = instance_types.get_all_types() + instance_types.create(self.name, 256, 1, 120, self.flavorid) + new = instance_types.get_all_types() + self.assertNotEqual(len(starting_inst_list), + len(new), + 'instance was not created') + rows = instance_types.destroy(self.name) + self.assertEqual(rows, 1) + self.assertEqual(1, + instance_types.get_instance_type(self.name)["deleted"]) + self.assertEqual(starting_inst_list, instance_types.get_all_types()) + + def test_get_all_instance_types(self): + """Ensures that all instance types can be retrieved""" + session = get_session() + total_instance_types = session.query(models.InstanceTypes).\ + count() + inst_types = instance_types.get_all_types() + self.assertEqual(total_instance_types, len(inst_types)) diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 5645bf97e..a2fa919a0 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -31,8 +31,8 @@ class NovaManageTestCase(test.TestCase): def test_create_and_delete_instance_types(self): fnull = open(os.devnull, 'w') - retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "create", "test", "256", "1",\ + retcode = subprocess.call(["bin/nova-manage", "instance_type", + "create", "test", "256", "1", "120", "99"], stdout=fnull) self.assertEqual(0, retcode) retcode = subprocess.call(["bin/nova-manage", "instance_type",\ -- cgit From 99a02a7d68416c72675f7b6c554df9b682771e04 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 9 Feb 2011 11:36:45 -0800 Subject: added support to pull list of ALL instance types even those that are marked deleted --- nova/compute/instance_types.py | 14 ++++++++------ nova/db/api.py | 4 ++-- nova/db/sqlalchemy/api.py | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index b97a0da25..b13ccda43 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -55,13 +55,15 @@ def destroy(name): return records -def get_all_types(): - """retrieves all instance_types""" - return db.instance_type_get_all(context.get_admin_context()) +def get_all_types(inactive=0): + """Retrieves non-deleted instance_types. + Pass true as argument if you want deleted instance types returned also.""" + return db.instance_type_get_all(context.get_admin_context(), inactive) def get_all_flavors(): - """retrieves all flavors. alias for instance_types.get_all_types()""" + """retrieves non-deleted flavors. alias for instance_types.get_all_types(). + Pass true as argument if you want deleted instance types returned also.""" return get_all_types(context.get_admin_context()) @@ -79,7 +81,7 @@ def get_instance_type(name): def get_by_type(instance_type): - """retrieve instance_type details""" + """retrieve instance type name""" if instance_type is None: return FLAGS.default_instance_type try: @@ -92,7 +94,7 @@ def get_by_type(instance_type): def get_by_flavor_id(flavor_id): - """retrieve instance_type's name by flavor_id""" + """retrieve instance type's name by flavor_id""" if flavor_id is None: return FLAGS.default_instance_type try: diff --git a/nova/db/api.py b/nova/db/api.py index 2f1903ade..69f577764 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -995,9 +995,9 @@ def instance_type_create(context, values): return IMPL.instance_type_create(context, values) -def instance_type_get_all(context): +def instance_type_get_all(context, inactive=0): """Get all instance types""" - return IMPL.instance_type_get_all(context) + return IMPL.instance_type_get_all(context, inactive) def instance_type_get_by_name(context, name): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e5afb8eac..1e13e4d2d 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2035,16 +2035,16 @@ def instance_type_create(context, values): @require_context -def instance_type_get_all(context): +def instance_type_get_all(context, inactive=0): """ - Returns a dict describing all instance_types with name as key: + Returns a dict describing all non-deleted instance_types with name as key: {'m1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3)} """ session = get_session() inst_types = session.query(models.InstanceTypes).\ - filter_by(deleted=0).\ + filter_by(deleted=inactive).\ order_by("name").\ all() if inst_types: -- cgit From cf2db4f18dbff14fb8882a4747c607ff26b1de55 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 9 Feb 2011 13:58:43 -0800 Subject: fixed overlooked mandatory changes in Xen --- nova/virt/libvirt_conn.py | 5 +++-- nova/virt/xenapi/vm_utils.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 94fe93c40..14cc4cf39 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -612,7 +612,7 @@ class LibvirtConnection(object): user=user, project=project, size=size) - type_data = test.INSTANCE_TYPES[inst['instance_type']] + type_data = instance_types.get_instance_type([inst['instance_type']]) if type_data['local_gb']: self._cache_image(fn=self._create_local, @@ -673,7 +673,8 @@ class LibvirtConnection(object): instance['id']) # FIXME(vish): stick this in db instance_type = instance['instance_type'] - instance_type = test.INSTANCE_TYPES[instance_type] + # instance_type = test.INSTANCE_TYPES[instance_type] + instance_type = instance_types.get_instance_type(instance_type) ip_address = db.instance_get_fixed_address(context.get_admin_context(), instance['id']) # Assume that the gateway also acts as the dhcp server. diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 38a6f73ce..a9308eea1 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -31,7 +31,6 @@ import glance.client from nova import exception from nova import flags from nova import log as logging -from nova import test from nova import utils from nova.auth.manager import AuthManager from nova.compute import instance_types @@ -83,7 +82,8 @@ class VMHelper(HelperBase): the pv_kernel flag indicates whether the guest is HVM or PV """ - instance_type = test.INSTANCE_TYPES[instance.instance_type] + instance_type = instance_types.\ + get_instance_type(instance.instance_type) mem = str(long(instance_type['memory_mb']) * 1024 * 1024) vcpus = str(instance_type['vcpus']) rec = { -- cgit From 1a9225d945bdc9b94473c1dd4ad5b9e4b7624571 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 9 Feb 2011 15:48:31 -0800 Subject: forgot to register new instance_types table --- nova/db/sqlalchemy/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 44583861b..3f418392c 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -550,7 +550,7 @@ def register_models(): connection is lost and needs to be reestablished. """ from sqlalchemy import create_engine - models = (Service, Instance, InstanceActions, + models = (Service, Instance, InstanceActions, InstanceTypes, Volume, ExportDevice, IscsiTarget, FixedIp, FloatingIp, Network, SecurityGroup, SecurityGroupIngressRule, SecurityGroupInstanceAssociation, AuthToken, User, -- cgit From 493d4d73ce427a686a674e00a2090d5aaec55a46 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 10 Feb 2011 10:20:33 -0800 Subject: refactored api call to use instance_types --- nova/compute/api.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nova') diff --git a/nova/compute/api.py b/nova/compute/api.py index fc18765f6..9c83cfd16 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -90,8 +90,9 @@ class API(base.Base): other arguments check out ok.""" # FIXME(kpepple) this needs to be factored for api.py:2065 refactor - type_data = db.instance_type_get_by_name(context,\ - instance_type) + type_data = instance_types.get_instance_type(instance_type) + # type_data = db.instance_type_get_by_name(context,\ + # instance_type) num_instances = quota.allowed_instances(context, max_count, type_data) if num_instances < min_count: pid = context.project_id -- cgit From d601471f54de5db95cf06f4a558362f90cc65c6b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 10 Feb 2011 10:28:52 -0800 Subject: typo --- nova/compute/api.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'nova') diff --git a/nova/compute/api.py b/nova/compute/api.py index 9c83cfd16..5d6a42a6b 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -89,10 +89,7 @@ class API(base.Base): """Create the number of instances requested if quota and other arguments check out ok.""" - # FIXME(kpepple) this needs to be factored for api.py:2065 refactor type_data = instance_types.get_instance_type(instance_type) - # type_data = db.instance_type_get_by_name(context,\ - # instance_type) num_instances = quota.allowed_instances(context, max_count, type_data) if num_instances < min_count: pid = context.project_id -- cgit From 9029d89d26b9115cad282c6f3f9ee11c47a28444 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 10 Feb 2011 11:19:02 -0800 Subject: flavorid needs to unique in model --- nova/db/sqlalchemy/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 3f418392c..955d373fd 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -218,7 +218,7 @@ class InstanceTypes(BASE, NovaBase): memory_mb = Column(Integer) vcpus = Column(Integer) local_gb = Column(Integer) - flavorid = Column(Integer) + flavorid = Column(Integer, unique=True) class Volume(BASE, NovaBase): -- cgit From fd915e3db7f1006e67342b034eb8db0384c87d34 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 10 Feb 2011 11:21:53 -0800 Subject: testing refactor --- nova/compute/instance_types.py | 6 +++--- nova/tests/test_instance_types.py | 10 ++++------ nova/tests/test_nova_manage.py | 32 ++++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 19 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index b13ccda43..fcd4d8973 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -32,9 +32,9 @@ FLAGS = flags.FLAGS def create(name, memory, vcpus, local_gb, flavorid): """Creates instance types / flavors arguments: name memory_mb vcpus local_gb""" - for option in [memory, flavorid, vcpus]: - if option <= 0: - raise exception.InvalidInputException("Parameters incorrect") + if (memory <= 0) or (vcpus <= 0) or (local_gb < 0): + raise exception.InvalidInputException + db.instance_type_create(context.get_admin_context(), dict(name=name, memory_mb=memory, vcpus=vcpus, local_gb=local_gb, diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 819431763..283f0bce8 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -14,7 +14,7 @@ """ Unit Tests for instance types code """ -import datetime +import time from nova import context from nova import db @@ -37,12 +37,10 @@ class InstanceTypeTestCase(test.TestCase): super(InstanceTypeTestCase, self).setUp() session = get_session() max_flavorid = session.query(models.InstanceTypes).\ - order_by("flavorid desc").first() + order_by("flavorid desc").\ + first() self.flavorid = max_flavorid["flavorid"] + 1 - self.name = str(datetime.datetime.utcnow()) - - def tearDown(self): - pass + self.name = str(int(time.time())) def test_instance_type_create_then_delete(self): """Ensure instance types can be created""" diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index a2fa919a0..d2c24e8b0 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -15,16 +15,25 @@ Tests For Nova-Manage """ +import time import os import subprocess from nova import test +from nova.db.sqlalchemy.session import get_session +from nova.db.sqlalchemy import models class NovaManageTestCase(test.TestCase): """Test case for nova-manage""" def setUp(self): super(NovaManageTestCase, self).setUp() + session = get_session() + max_flavorid = session.query(models.InstanceTypes).\ + order_by("flavorid desc").first() + self.flavorid = str(max_flavorid["flavorid"] + 1) + # self.flavorid = str(self.flavorid) + self.name = str(int(time.time())) def teardown(self): fnull.close() @@ -32,11 +41,11 @@ class NovaManageTestCase(test.TestCase): def test_create_and_delete_instance_types(self): fnull = open(os.devnull, 'w') retcode = subprocess.call(["bin/nova-manage", "instance_type", - "create", "test", "256", "1", - "120", "99"], stdout=fnull) + "create", self.name, "256", "1", + "120", self.flavorid], stdout=fnull) self.assertEqual(0, retcode) retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "delete", "test"], stdout=fnull) + "delete", self.name], stdout=fnull) self.assertEqual(0, retcode) def test_list_instance_types_or_flavors(self): @@ -52,17 +61,20 @@ class NovaManageTestCase(test.TestCase): "m1.medium"], stdout=fnull) self.assertEqual(0, retcode) - def test_should_raise_on_bad_create_args(self): + def test_should_error_on_bad_create_args(self): fnull = open(os.devnull, 'w') + # shouldn't be able to create instance type with 0 vcpus retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "create", "test", "256", "0",\ - "120", "99"], stdout=fnull) - self.assertEqual(1, retcode) + "create", self.name, "256", "0",\ + "120", self.flavorid], stdout=fnull) + # self.assertEqual(1, retcode, + # ("bin/nova-manage instance_type create %s 256 0 120 %s"\ + # % (self.name, self.flavorid))) def test_should_fail_on_duplicate_flavorid(self): fnull = open(os.devnull, 'w') retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "create", "test", "256", "1",\ + "create", self.name, "256", "1",\ "120", "1"], stdout=fnull) self.assertEqual(1, retcode) @@ -70,11 +82,11 @@ class NovaManageTestCase(test.TestCase): fnull = open(os.devnull, 'w') retcode = subprocess.call(["bin/nova-manage", "instance_type",\ "create", "fsfsfsdfsdf", "256", "1",\ - "120", "189"], stdout=fnull) + "120", self.flavorid], stdout=fnull) self.assertEqual(0, retcode) retcode = subprocess.call(["bin/nova-manage", "instance_type",\ "create", "fsfsfsdfsdf", "256", "1",\ - "120", "190"], stdout=fnull) + "120", self.flavorid], stdout=fnull) self.assertEqual(1, retcode) def test_instance_type_delete_should_fail_without_valid_name(self): -- cgit From 8ac02818a514716fa4899d633831877a388239c0 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 10 Feb 2011 16:29:25 -0800 Subject: fixed destroy calls --- nova/compute/instance_types.py | 7 +------ nova/db/sqlalchemy/api.py | 14 +++++++------- nova/tests/test_instance_types.py | 3 +-- nova/tests/test_nova_manage.py | 10 +++++----- 4 files changed, 14 insertions(+), 20 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index fcd4d8973..c6887795a 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -47,12 +47,7 @@ def destroy(name): if name == None: raise exception.InvalidInputException else: - records = db.instance_type_destroy(context.get_admin_context(), - name) - if records == 0: - raise exception.NotFound("Cannot find instance type named %s" % name) - else: - return records + db.instance_type_destroy(context.get_admin_context(), name) def get_all_types(inactive=0): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 1e13e4d2d..f8b0559d2 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2086,10 +2086,10 @@ def instance_type_get_by_flavor_id(context, id): def instance_type_destroy(context, name): """ Marks specific instance_type as deleted""" session = get_session() - instance_type_ref = session.query(models.InstanceTypes).\ - filter_by(name=name) - rows = instance_type_ref.update(dict(deleted=1)) - if not rows: - raise exception.NotFound(_("Couldn't delete instance type %s") % name) - else: - return rows + try: + instance_type_ref = session.query(models.InstanceTypes).\ + filter_by(name=name) + instance_type_ref.update(dict(deleted=1)) + except: + raise exception.DBError + return instance_type_ref diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 283f0bce8..36c29d336 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -50,8 +50,7 @@ class InstanceTypeTestCase(test.TestCase): self.assertNotEqual(len(starting_inst_list), len(new), 'instance was not created') - rows = instance_types.destroy(self.name) - self.assertEqual(rows, 1) + instance_types.destroy(self.name) self.assertEqual(1, instance_types.get_instance_type(self.name)["deleted"]) self.assertEqual(starting_inst_list, instance_types.get_all_types()) diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index d2c24e8b0..c1ef8cae9 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -89,8 +89,8 @@ class NovaManageTestCase(test.TestCase): "120", self.flavorid], stdout=fnull) self.assertEqual(1, retcode) - def test_instance_type_delete_should_fail_without_valid_name(self): - fnull = open(os.devnull, 'w') - retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "delete", "saefasff"], stdout=fnull) - self.assertEqual(1, retcode) + # def test_instance_type_delete_should_fail_without_valid_name(self): + # fnull = open(os.devnull, 'w') + # retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + # "delete", "saefasff"], stdout=fnull) + # self.assertEqual(1, retcode) -- cgit From a36b67d192eb619963494896928efffef5dae4b6 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 10 Feb 2011 18:35:10 -0800 Subject: after hours of tracking his prey, ken slowly crept behind the elusive wilderbeast test import hiding in the libvirt_conn.py bushes and gutted it with his steely blade --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 14cc4cf39..35b78368e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -55,7 +55,7 @@ from nova import db from nova import exception from nova import flags from nova import log as logging -from nova import test +#from nova import test from nova import utils #from nova.api import context from nova.auth import manager -- cgit From 4a058908db774bfebce4ece814534225e123345c Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Fri, 11 Feb 2011 15:04:49 -0600 Subject: Added more columns to instance_types tables --- nova/compute/instance_types.py | 28 ++++++++++--- .../sqlalchemy/migrate_repo/versions/003_cactus.py | 4 +- nova/db/sqlalchemy/models.py | 3 ++ nova/tests/test_nova_manage.py | 48 ++++++++++++++++++---- 4 files changed, 67 insertions(+), 16 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index c6887795a..01abee584 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -29,16 +29,32 @@ from nova import exception FLAGS = flags.FLAGS -def create(name, memory, vcpus, local_gb, flavorid): +def create( + name, + memory, + vcpus, + local_gb, + flavorid, + swap=0, + rxtx_quota=0, + rxtx_cap=0): """Creates instance types / flavors - arguments: name memory_mb vcpus local_gb""" + arguments: name memory vcpus local_gb flavorid swap rxtx_quota rxtx_cap + """ if (memory <= 0) or (vcpus <= 0) or (local_gb < 0): raise exception.InvalidInputException - db.instance_type_create(context.get_admin_context(), - dict(name=name, memory_mb=memory, - vcpus=vcpus, local_gb=local_gb, - flavorid=flavorid)) + db.instance_type_create( + context.get_admin_context(), + dict( + name=name, + memory_mb=memory, + vcpus=vcpus, + local_gb=local_gb, + flavorid=flavorid, + swap=swap, + rxtx_quota=rxtx_quota, + rxtx_cap=rxtx_cap)) def destroy(name): diff --git a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py index f95996042..fec191214 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py @@ -41,7 +41,9 @@ instance_types = Table('instance_types', meta, Column('vcpus', Integer(), nullable=False), Column('local_gb', Integer(), nullable=False), Column('flavorid', Integer(), nullable=False, unique=True), - ) + Column('swap', Integer(), nullable=False, default=0), + Column('rxtx_quota', Integer(), nullable=False, default=0), + Column('rxtx_cap', Integer(), nullable=False, default=0)) def upgrade(migrate_engine): diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 955d373fd..8ee3e3532 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -219,6 +219,9 @@ class InstanceTypes(BASE, NovaBase): vcpus = Column(Integer) local_gb = Column(Integer) flavorid = Column(Integer, unique=True) + swap = Column(Integer, nullable=False, default=0) + rxtx_quota = Column(Integer, nullable=False, default=0) + rxtx_cap = Column(Integer, nullable=False, default=0) class Volume(BASE, NovaBase): diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index c1ef8cae9..5a6e1287f 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -40,9 +40,19 @@ class NovaManageTestCase(test.TestCase): def test_create_and_delete_instance_types(self): fnull = open(os.devnull, 'w') - retcode = subprocess.call(["bin/nova-manage", "instance_type", - "create", self.name, "256", "1", - "120", self.flavorid], stdout=fnull) + retcode = subprocess.call([ + "bin/nova-manage", + "instance_type", + "create", + self.name, + "256", + "1", + "120", + self.flavorid, + "2", + "10", + "10"], + stdout=fnull) self.assertEqual(0, retcode) retcode = subprocess.call(["bin/nova-manage", "instance_type",\ "delete", self.name], stdout=fnull) @@ -80,13 +90,33 @@ class NovaManageTestCase(test.TestCase): def test_should_fail_on_duplicate_name(self): fnull = open(os.devnull, 'w') - retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "create", "fsfsfsdfsdf", "256", "1",\ - "120", self.flavorid], stdout=fnull) + retcode = subprocess.call([ + "bin/nova-manage", + "instance_type", + "create", + "fsfsfsdfsdf", + "256", + "1", + "120", + self.flavorid, + "2", + "10", + "10"], + stdout=fnull) self.assertEqual(0, retcode) - retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "create", "fsfsfsdfsdf", "256", "1",\ - "120", self.flavorid], stdout=fnull) + retcode = subprocess.call([ + "bin/nova-manage", + "instance_type", + "create", + "fsfsfsdfsdf", + "256", + "1", + "120", + self.flavorid, + "2", + "10", + "10"], + stdout=fnull) self.assertEqual(1, retcode) # def test_instance_type_delete_should_fail_without_valid_name(self): -- cgit From e4061a0f5d06dfd6136c5dda94945214cc9a2cf5 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Fri, 11 Feb 2011 13:11:28 -0800 Subject: more error checking on inputs and better errors returned --- nova/compute/instance_types.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index c6887795a..0cec4812e 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -32,22 +32,36 @@ FLAGS = flags.FLAGS def create(name, memory, vcpus, local_gb, flavorid): """Creates instance types / flavors arguments: name memory_mb vcpus local_gb""" - if (memory <= 0) or (vcpus <= 0) or (local_gb < 0): - raise exception.InvalidInputException - - db.instance_type_create(context.get_admin_context(), - dict(name=name, memory_mb=memory, - vcpus=vcpus, local_gb=local_gb, - flavorid=flavorid)) + for option in [memory, vcpus, local_gb, flavorid]: + try: + int(option) + except: + raise exception.InvalidInputException( + _("create arguments must be positive integers")) + if (int(memory) <= 0) or (int(vcpus) <= 0) or (int(local_gb) < 0): + raise exception.InvalidInputException( + _("create arguments must be positive integers")) + try: + db.instance_type_create(context.get_admin_context(), + dict(name=name, memory_mb=memory, + vcpus=vcpus, local_gb=local_gb, + flavorid=flavorid)) + except exception.DBError: + raise exception.ApiError(_("Cannot create instance type: %s"), + instance_type, "Invalid") def destroy(name): """Marks instance types / flavors as deleted arguments: name""" if name == None: - raise exception.InvalidInputException + raise exception.InvalidInputException(_("No instance type specified")) else: - db.instance_type_destroy(context.get_admin_context(), name) + try: + db.instance_type_destroy(context.get_admin_context(), name) + except exception.DBError: + raise exception.ApiError(_("Unknown instance type: %s"), + instance_type, "Invalid") def get_all_types(inactive=0): @@ -72,7 +86,7 @@ def get_instance_type(name): return inst_type except exception.DBError: raise exception.ApiError(_("Unknown instance type: %s"), - instance_type) + instance_type, "Invalid") def get_by_type(instance_type): @@ -85,7 +99,7 @@ def get_by_type(instance_type): return inst_type['name'] except exception.DBError: raise exception.ApiError(_("Unknown instance type: %s"), - instance_type) + instance_type, "Invalid") def get_by_flavor_id(flavor_id): @@ -98,4 +112,4 @@ def get_by_flavor_id(flavor_id): return flavor['name'] except exception.DBError: raise exception.ApiError(_("Unknown flavor: %s"), - flavor_id) + flavor_id, "Invalid") -- cgit From 40ec6d45a25bf997ae62dbbf08494aa39f047e33 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Fri, 11 Feb 2011 13:53:54 -0800 Subject: updated tests and added more error checking --- nova/compute/instance_types.py | 12 ++++++------ nova/db/sqlalchemy/api.py | 14 +++++++------- nova/tests/test_instance_types.py | 17 +++++++++++++++++ nova/tests/test_nova_manage.py | 21 +++++++++------------ 4 files changed, 39 insertions(+), 25 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 0cec4812e..f0b3fe473 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -48,7 +48,7 @@ def create(name, memory, vcpus, local_gb, flavorid): flavorid=flavorid)) except exception.DBError: raise exception.ApiError(_("Cannot create instance type: %s"), - instance_type, "Invalid") + name) def destroy(name): @@ -59,9 +59,9 @@ def destroy(name): else: try: db.instance_type_destroy(context.get_admin_context(), name) - except exception.DBError: + except exception.NotFound: raise exception.ApiError(_("Unknown instance type: %s"), - instance_type, "Invalid") + name) def get_all_types(inactive=0): @@ -86,7 +86,7 @@ def get_instance_type(name): return inst_type except exception.DBError: raise exception.ApiError(_("Unknown instance type: %s"), - instance_type, "Invalid") + name) def get_by_type(instance_type): @@ -99,7 +99,7 @@ def get_by_type(instance_type): return inst_type['name'] except exception.DBError: raise exception.ApiError(_("Unknown instance type: %s"), - instance_type, "Invalid") + instance_type) def get_by_flavor_id(flavor_id): @@ -112,4 +112,4 @@ def get_by_flavor_id(flavor_id): return flavor['name'] except exception.DBError: raise exception.ApiError(_("Unknown flavor: %s"), - flavor_id, "Invalid") + flavor_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index f8b0559d2..323f9b965 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2086,10 +2086,10 @@ def instance_type_get_by_flavor_id(context, id): def instance_type_destroy(context, name): """ Marks specific instance_type as deleted""" session = get_session() - try: - instance_type_ref = session.query(models.InstanceTypes).\ - filter_by(name=name) - instance_type_ref.update(dict(deleted=1)) - except: - raise exception.DBError - return instance_type_ref + instance_type_ref = session.query(models.InstanceTypes).\ + filter_by(name=name) + records = instance_type_ref.update(dict(deleted=1)) + if records == 0: + raise exception.NotFound + else: + return instance_type_ref diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 36c29d336..68ca3b842 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -62,3 +62,20 @@ class InstanceTypeTestCase(test.TestCase): count() inst_types = instance_types.get_all_types() self.assertEqual(total_instance_types, len(inst_types)) + + def test_invalid_create_args_should_fail(self): + """Ensures that instance type creation fails with invalid args""" + self.assertRaises( + exception.InvalidInputException, + instance_types.create, self.name, 0, 1, 120, self.flavorid) + self.assertRaises( + exception.InvalidInputException, + instance_types.create, self.name, 256, -1, 120, self.flavorid) + self.assertRaises( + exception.InvalidInputException, + instance_types.create, self.name, 256, 1, "aa", self.flavorid) + + def test_non_existant_inst_type_shouldnt_delete(self): + """Ensures that instance type creation fails with invalid args""" + self.assertRaises(exception.ApiError, + instance_types.destroy, "sfsfsdfdfs") diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index c1ef8cae9..8ab23ba2b 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -32,7 +32,6 @@ class NovaManageTestCase(test.TestCase): max_flavorid = session.query(models.InstanceTypes).\ order_by("flavorid desc").first() self.flavorid = str(max_flavorid["flavorid"] + 1) - # self.flavorid = str(self.flavorid) self.name = str(int(time.time())) def teardown(self): @@ -42,7 +41,7 @@ class NovaManageTestCase(test.TestCase): fnull = open(os.devnull, 'w') retcode = subprocess.call(["bin/nova-manage", "instance_type", "create", self.name, "256", "1", - "120", self.flavorid], stdout=fnull) + "10", self.flavorid], stdout=fnull) self.assertEqual(0, retcode) retcode = subprocess.call(["bin/nova-manage", "instance_type",\ "delete", self.name], stdout=fnull) @@ -67,16 +66,14 @@ class NovaManageTestCase(test.TestCase): retcode = subprocess.call(["bin/nova-manage", "instance_type",\ "create", self.name, "256", "0",\ "120", self.flavorid], stdout=fnull) - # self.assertEqual(1, retcode, - # ("bin/nova-manage instance_type create %s 256 0 120 %s"\ - # % (self.name, self.flavorid))) + self.assertEqual(1, retcode) def test_should_fail_on_duplicate_flavorid(self): fnull = open(os.devnull, 'w') retcode = subprocess.call(["bin/nova-manage", "instance_type",\ "create", self.name, "256", "1",\ "120", "1"], stdout=fnull) - self.assertEqual(1, retcode) + self.assertEqual(3, retcode) def test_should_fail_on_duplicate_name(self): fnull = open(os.devnull, 'w') @@ -87,10 +84,10 @@ class NovaManageTestCase(test.TestCase): retcode = subprocess.call(["bin/nova-manage", "instance_type",\ "create", "fsfsfsdfsdf", "256", "1",\ "120", self.flavorid], stdout=fnull) - self.assertEqual(1, retcode) + self.assertEqual(3, retcode) - # def test_instance_type_delete_should_fail_without_valid_name(self): - # fnull = open(os.devnull, 'w') - # retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - # "delete", "saefasff"], stdout=fnull) - # self.assertEqual(1, retcode) + def test_instance_type_delete_should_fail_without_valid_name(self): + fnull = open(os.devnull, 'w') + retcode = subprocess.call(["bin/nova-manage", "instance_type",\ + "delete", "doesntexist"], stdout=fnull) + self.assertEqual(1, retcode) -- cgit From b03d6f523a0dda7c942c298ac75bc46331085056 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Fri, 11 Feb 2011 14:06:33 -0800 Subject: added instance_type_purge() to actually remove records from db --- nova/db/api.py | 7 +++++++ nova/db/sqlalchemy/api.py | 15 +++++++++++++++ nova/tests/test_instance_types.py | 1 + 3 files changed, 23 insertions(+) (limited to 'nova') diff --git a/nova/db/api.py b/nova/db/api.py index 69f577764..4e53a8eee 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1013,3 +1013,10 @@ def instance_type_get_by_flavor_id(context, id): def instance_type_destroy(context, name): """Delete a instance type""" return IMPL.instance_type_destroy(context, name) + + +def instance_type_purge(context, name): + """Purges (removes) an instance type from DB + Use instance_type_destroy for most cases + """ + return IMPL.instance_type_purge(context, name) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 323f9b965..a8ce22922 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2093,3 +2093,18 @@ def instance_type_destroy(context, name): raise exception.NotFound else: return instance_type_ref + + +@require_admin_context +def instance_type_purge(context, name): + """ Removes specific instance_type from DB + Usually instance_type_destroy should be used + """ + session = get_session() + instance_type_ref = session.query(models.InstanceTypes).\ + filter_by(name=name) + records = instance_type_ref.delete() + if records == 0: + raise exception.NotFound + else: + return instance_type_ref diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 68ca3b842..0d54cc283 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -54,6 +54,7 @@ class InstanceTypeTestCase(test.TestCase): self.assertEqual(1, instance_types.get_instance_type(self.name)["deleted"]) self.assertEqual(starting_inst_list, instance_types.get_all_types()) + db.instance_type_purge(context.get_admin_context(), self.name) def test_get_all_instance_types(self): """Ensures that all instance types can be retrieved""" -- cgit From 4375069b6635d6ccd87231cb7d9f5b17708ffb1a Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 16 Feb 2011 11:11:49 -0600 Subject: Stubbed out flavor create/delete API calls --- nova/api/openstack/flavors.py | 9 ++++++++- nova/tests/api/openstack/test_flavors.py | 10 ++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 9b674afbd..215f0b8a6 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -42,7 +42,6 @@ class Controller(wsgi.Controller): def detail(self, req): """Return all flavors in detail.""" items = [self.show(req, id)['flavor'] for id in self._all_ids()] - items = common.limited(items, req) return dict(flavors=items) def show(self, req, id): @@ -57,6 +56,14 @@ class Controller(wsgi.Controller): return dict(flavor=values) raise faults.Fault(exc.HTTPNotFound()) + def create(self, req): + """Create a flavor.""" + print "CREATE! %s" % req + + def delete(self, req, id): + """Delete a flavor.""" + print "DELETE! %s %s" % (req, id) + def _all_ids(self): """Return the list of all flavorids.""" # FIXME(kpepple) do we really need admin context here ? diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 532b34e1b..7bfc46e0b 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -43,7 +43,17 @@ class FlavorsTest(unittest.TestCase): def test_get_flavor_list(self): req = webob.Request.blank('/v1.0/flavors') res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + def test_create_flavor(self): + req = webob.Request.blank("/v1.0/flavors/create/test") + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + + def test_delete_flavor(self): + req = webob.Request.blank("/v1.0/flavors/delete/test") + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) if __name__ == '__main__': unittest.main() -- cgit From 9d056b6fadcefed9ef9573bd89125b00af5e2726 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Thu, 17 Feb 2011 10:50:49 -0600 Subject: More testing --- nova/api/openstack/__init__.py | 1 + nova/api/openstack/flavors.py | 14 ++++++++++++-- nova/tests/api/openstack/test_flavors.py | 6 ++++-- 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'nova') diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 056c7dd27..1fafebe37 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -73,6 +73,7 @@ class APIRouter(wsgi.Router): server_members = {'action': 'POST'} if FLAGS.allow_admin_api: LOG.debug(_("Including admin operations in API.")) + server_members['pause'] = 'POST' server_members['unpause'] = 'POST' server_members["diagnostics"] = "GET" diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 215f0b8a6..a3a664506 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -58,11 +58,21 @@ class Controller(wsgi.Controller): def create(self, req): """Create a flavor.""" + instance_types.create( + name, + memory, + vcpus, + local_gb, + flavor_id, + swap, + rxtx_quota, + rxtx_cap) print "CREATE! %s" % req - def delete(self, req, id): + def delete(self, req, name): """Delete a flavor.""" - print "DELETE! %s %s" % (req, id) + instance_type.destroy(name) + print "DELETE! %s %s" % (req, name) def _all_ids(self): """Return the list of all flavorids.""" diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 7bfc46e0b..209ace0f8 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -46,12 +46,14 @@ class FlavorsTest(unittest.TestCase): self.assertEqual(res.status_int, 200) def test_create_flavor(self): - req = webob.Request.blank("/v1.0/flavors/create/test") + req = webob.Request.blank("/v1.0/flavors") + req.method = "POST" res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 200) def test_delete_flavor(self): - req = webob.Request.blank("/v1.0/flavors/delete/test") + req = webob.Request.blank("/v1.0/flavors/1") + req.method = "DELETE" res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 200) -- cgit From aa53c9476ed37f0a1359413d4a710eb08c997b06 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Thu, 17 Feb 2011 14:42:01 -0600 Subject: Finished flavor OS API stubs --- nova/api/openstack/flavors.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'nova') diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index a3a664506..375e12b18 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -58,21 +58,23 @@ class Controller(wsgi.Controller): def create(self, req): """Create a flavor.""" - instance_types.create( - name, - memory, - vcpus, - local_gb, - flavor_id, - swap, - rxtx_quota, - rxtx_cap) - print "CREATE! %s" % req + #TODO(jk0): Finish this later + #instance_types.create( + # name, + # memory, + # vcpus, + # local_gb, + # flavor_id, + # swap, + # rxtx_quota, + # rxtx_cap) + return "CREATE! %s" % req - def delete(self, req, name): + def delete(self, req, id): """Delete a flavor.""" - instance_type.destroy(name) - print "DELETE! %s %s" % (req, name) + #TODO(jk0): Finish this later + #instance_type.destroy(name) + return "DELETE! %s %s" % (req, id) def _all_ids(self): """Return the list of all flavorids.""" -- cgit From 8da339d53b4039c3a8e5e8a15ccf1434eeda5fa2 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Thu, 17 Feb 2011 15:05:19 -0600 Subject: Fixed unit test --- nova/virt/xenapi/vm_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 339cecd40..7031f2f82 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -141,7 +141,8 @@ class VMHelper(HelperBase): @classmethod def ensure_free_mem(cls, session, instance): - instance_type = instance_types.INSTANCE_TYPES[instance.instance_type] + instance_type = instance_types.get_instance_type( + instance.instance_type) mem = long(instance_type['memory_mb']) * 1024 * 1024 #get free memory from host host = session.get_xenapi_host() -- cgit From 273119957fb3f6cfa72d4357054f6ad1743704e8 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 17 Feb 2011 13:49:36 -0800 Subject: moved 003_cactus.py migration file to 004_add_instance_types.py to avoid naming collision with new trunk migration --- .../sqlalchemy/migrate_repo/versions/003_cactus.py | 86 ---------------------- .../versions/004_add_instance_types.py | 86 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 86 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/004_add_instance_types.py (limited to 'nova') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py b/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py deleted file mode 100644 index fec191214..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/003_cactus.py +++ /dev/null @@ -1,86 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# 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 * -from migrate import * - -from nova import api -from nova import db -from nova import log as logging - -import datetime - -meta = MetaData() - - -# -# New Tables -# -instance_types = Table('instance_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('name', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False), - unique=True), - Column('id', Integer(), primary_key=True, nullable=False), - Column('memory_mb', Integer(), nullable=False), - Column('vcpus', Integer(), nullable=False), - Column('local_gb', Integer(), nullable=False), - Column('flavorid', Integer(), nullable=False, unique=True), - Column('swap', Integer(), nullable=False, default=0), - Column('rxtx_quota', Integer(), nullable=False, default=0), - Column('rxtx_cap', Integer(), nullable=False, default=0)) - - -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: - instance_types.create() - except Exception: - logging.info(repr(table)) - logging.exception('Exception while creating instance_types table') - raise - - # Here are the old static instance types - INSTANCE_TYPES = { - 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), - 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), - 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} - try: - i = instance_types.insert() - for name, values in INSTANCE_TYPES.iteritems(): - # FIXME(kpepple) should we be seeding created_at / updated_at ? - # now = datetime.datatime.utcnow() - i.execute({'name': name, 'memory_mb': values["memory_mb"], - 'vcpus': values["vcpus"], 'deleted': 0, - 'local_gb': values["local_gb"], - 'flavorid': values["flavorid"]}) - except Exception: - logging.info(repr(table)) - logging.exception('Exception while seeding instance_types table') - raise - - -def downgrade(migrate_engine): - # Operations to reverse the above upgrade go here. - for table in (instance_types): - table.drop() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/004_add_instance_types.py b/nova/db/sqlalchemy/migrate_repo/versions/004_add_instance_types.py new file mode 100644 index 000000000..fec191214 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/004_add_instance_types.py @@ -0,0 +1,86 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# 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 * +from migrate import * + +from nova import api +from nova import db +from nova import log as logging + +import datetime + +meta = MetaData() + + +# +# New Tables +# +instance_types = Table('instance_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('name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + unique=True), + Column('id', Integer(), primary_key=True, nullable=False), + Column('memory_mb', Integer(), nullable=False), + Column('vcpus', Integer(), nullable=False), + Column('local_gb', Integer(), nullable=False), + Column('flavorid', Integer(), nullable=False, unique=True), + Column('swap', Integer(), nullable=False, default=0), + Column('rxtx_quota', Integer(), nullable=False, default=0), + Column('rxtx_cap', Integer(), nullable=False, default=0)) + + +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: + instance_types.create() + except Exception: + logging.info(repr(table)) + logging.exception('Exception while creating instance_types table') + raise + + # Here are the old static instance types + INSTANCE_TYPES = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + try: + i = instance_types.insert() + for name, values in INSTANCE_TYPES.iteritems(): + # FIXME(kpepple) should we be seeding created_at / updated_at ? + # now = datetime.datatime.utcnow() + i.execute({'name': name, 'memory_mb': values["memory_mb"], + 'vcpus': values["vcpus"], 'deleted': 0, + 'local_gb': values["local_gb"], + 'flavorid': values["flavorid"]}) + except Exception: + logging.info(repr(table)) + logging.exception('Exception while seeding instance_types table') + raise + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + for table in (instance_types): + table.drop() -- cgit From ff0ef603fd3f87ad9294260d13ea3c122bab387f Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 17 Feb 2011 16:22:04 -0800 Subject: changed migration to 006 for trunk compatibility --- .../versions/004_add_instance_types.py | 86 ---------------------- .../versions/006_add_instance_types.py | 86 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 86 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/004_add_instance_types.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/006_add_instance_types.py (limited to 'nova') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/004_add_instance_types.py b/nova/db/sqlalchemy/migrate_repo/versions/004_add_instance_types.py deleted file mode 100644 index fec191214..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/004_add_instance_types.py +++ /dev/null @@ -1,86 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# 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 * -from migrate import * - -from nova import api -from nova import db -from nova import log as logging - -import datetime - -meta = MetaData() - - -# -# New Tables -# -instance_types = Table('instance_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('name', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False), - unique=True), - Column('id', Integer(), primary_key=True, nullable=False), - Column('memory_mb', Integer(), nullable=False), - Column('vcpus', Integer(), nullable=False), - Column('local_gb', Integer(), nullable=False), - Column('flavorid', Integer(), nullable=False, unique=True), - Column('swap', Integer(), nullable=False, default=0), - Column('rxtx_quota', Integer(), nullable=False, default=0), - Column('rxtx_cap', Integer(), nullable=False, default=0)) - - -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: - instance_types.create() - except Exception: - logging.info(repr(table)) - logging.exception('Exception while creating instance_types table') - raise - - # Here are the old static instance types - INSTANCE_TYPES = { - 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), - 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), - 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} - try: - i = instance_types.insert() - for name, values in INSTANCE_TYPES.iteritems(): - # FIXME(kpepple) should we be seeding created_at / updated_at ? - # now = datetime.datatime.utcnow() - i.execute({'name': name, 'memory_mb': values["memory_mb"], - 'vcpus': values["vcpus"], 'deleted': 0, - 'local_gb': values["local_gb"], - 'flavorid': values["flavorid"]}) - except Exception: - logging.info(repr(table)) - logging.exception('Exception while seeding instance_types table') - raise - - -def downgrade(migrate_engine): - # Operations to reverse the above upgrade go here. - for table in (instance_types): - table.drop() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/006_add_instance_types.py b/nova/db/sqlalchemy/migrate_repo/versions/006_add_instance_types.py new file mode 100644 index 000000000..fec191214 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/006_add_instance_types.py @@ -0,0 +1,86 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# 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 * +from migrate import * + +from nova import api +from nova import db +from nova import log as logging + +import datetime + +meta = MetaData() + + +# +# New Tables +# +instance_types = Table('instance_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('name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + unique=True), + Column('id', Integer(), primary_key=True, nullable=False), + Column('memory_mb', Integer(), nullable=False), + Column('vcpus', Integer(), nullable=False), + Column('local_gb', Integer(), nullable=False), + Column('flavorid', Integer(), nullable=False, unique=True), + Column('swap', Integer(), nullable=False, default=0), + Column('rxtx_quota', Integer(), nullable=False, default=0), + Column('rxtx_cap', Integer(), nullable=False, default=0)) + + +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: + instance_types.create() + except Exception: + logging.info(repr(table)) + logging.exception('Exception while creating instance_types table') + raise + + # Here are the old static instance types + INSTANCE_TYPES = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + try: + i = instance_types.insert() + for name, values in INSTANCE_TYPES.iteritems(): + # FIXME(kpepple) should we be seeding created_at / updated_at ? + # now = datetime.datatime.utcnow() + i.execute({'name': name, 'memory_mb': values["memory_mb"], + 'vcpus': values["vcpus"], 'deleted': 0, + 'local_gb': values["local_gb"], + 'flavorid': values["flavorid"]}) + except Exception: + logging.info(repr(table)) + logging.exception('Exception while seeding instance_types table') + raise + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + for table in (instance_types): + table.drop() -- cgit From 2da6494d20624177c0077d0709e1fdb0e5f8f03c Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 17 Feb 2011 17:42:49 -0800 Subject: pep8 --- nova/tests/api/openstack/test_zones.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'nova') diff --git a/nova/tests/api/openstack/test_zones.py b/nova/tests/api/openstack/test_zones.py index 5542a1cf3..df497ef1b 100644 --- a/nova/tests/api/openstack/test_zones.py +++ b/nova/tests/api/openstack/test_zones.py @@ -57,8 +57,7 @@ def zone_get_all(context): dict(id=1, api_url='http://foo.com', username='bob', password='xxx'), dict(id=2, api_url='http://blah.com', username='alice', - password='qwerty') - ] + password='qwerty')] class ZonesTest(unittest.TestCase): -- cgit From fcd31c4d7c3855cb95ac75d6966b377eca8bbe7d Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Fri, 18 Feb 2011 15:59:42 -0800 Subject: added instance types purge test --- nova/tests/test_instance_types.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 0d54cc283..fe052110f 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -49,12 +49,16 @@ class InstanceTypeTestCase(test.TestCase): new = instance_types.get_all_types() self.assertNotEqual(len(starting_inst_list), len(new), - 'instance was not created') + 'instance type was not created') instance_types.destroy(self.name) self.assertEqual(1, instance_types.get_instance_type(self.name)["deleted"]) self.assertEqual(starting_inst_list, instance_types.get_all_types()) db.instance_type_purge(context.get_admin_context(), self.name) + self.assertEqual(len(starting_inst_list), + len(instance_types.get_all_types()), + 'instance type not purged') + def test_get_all_instance_types(self): """Ensures that all instance types can be retrieved""" -- cgit From 3609f1da7e1383b76295c6e8bd1d1dc0d798aa63 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Fri, 18 Feb 2011 16:00:22 -0800 Subject: pep8 --- nova/tests/test_instance_types.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova') diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index fe052110f..705144cb0 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -59,7 +59,6 @@ class InstanceTypeTestCase(test.TestCase): len(instance_types.get_all_types()), 'instance type not purged') - def test_get_all_instance_types(self): """Ensures that all instance types can be retrieved""" session = get_session() -- cgit From 53784c1afaa12d0a8b22248093ec1e623a1a913d Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Fri, 18 Feb 2011 17:17:47 -0800 Subject: added purge option and tightened up testing --- nova/compute/instance_types.py | 13 ++++++++ nova/tests/test_instance_types.py | 2 +- nova/tests/test_nova_manage.py | 62 ++++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 31 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index a5e0a7baf..ce4b25964 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -81,6 +81,19 @@ def destroy(name): name) +def purge(name): + """Removes instance types / flavors from database + arguments: name""" + if name == None: + raise exception.InvalidInputException(_("No instance type specified")) + else: + try: + db.instance_type_purge(context.get_admin_context(), name) + except exception.NotFound: + raise exception.ApiError(_("Unknown instance type: %s"), + name) + + def get_all_types(inactive=0): """Retrieves non-deleted instance_types. Pass true as argument if you want deleted instance types returned also.""" diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 705144cb0..1b192ca28 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -54,7 +54,7 @@ class InstanceTypeTestCase(test.TestCase): self.assertEqual(1, instance_types.get_instance_type(self.name)["deleted"]) self.assertEqual(starting_inst_list, instance_types.get_all_types()) - db.instance_type_purge(context.get_admin_context(), self.name) + instance_types.purge(self.name) self.assertEqual(len(starting_inst_list), len(instance_types.get_all_types()), 'instance type not purged') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 03b4e3fb8..03aea53c9 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -33,12 +33,13 @@ class NovaManageTestCase(test.TestCase): order_by("flavorid desc").first() self.flavorid = str(max_flavorid["flavorid"] + 1) self.name = str(int(time.time())) + self.fnull = open(os.devnull, 'w') def teardown(self): - fnull.close() + self.fnull.close() def test_create_and_delete_instance_types(self): - fnull = open(os.devnull, 'w') + myname = self.name + "create_and_delete" retcode = subprocess.call([ "bin/nova-manage", "instance_type", @@ -51,45 +52,44 @@ class NovaManageTestCase(test.TestCase): "2", "10", "10"], - stdout=fnull) + stdout=self.fnull) self.assertEqual(0, retcode) - retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "delete", self.name], stdout=fnull) + retcode = subprocess.call(["bin/nova-manage", "instance_type", + "delete", self.name], stdout=self.fnull) + self.assertEqual(0, retcode) + retcode = subprocess.call(["bin/nova-manage", "instance_type", + "delete", self.name, "--purge"], + stdout=self.fnull) self.assertEqual(0, retcode) def test_list_instance_types_or_flavors(self): - fnull = open(os.devnull, 'w') for c in ["instance_type", "flavor"]: retcode = subprocess.call(["bin/nova-manage", c, \ - "list"], stdout=fnull) + "list"], stdout=self.fnull) self.assertEqual(0, retcode) def test_list_specific_instance_type(self): - fnull = open(os.devnull, 'w') retcode = subprocess.call(["bin/nova-manage", "instance_type", "list", - "m1.medium"], stdout=fnull) + "m1.medium"], stdout=self.fnull) self.assertEqual(0, retcode) def test_should_error_on_bad_create_args(self): - fnull = open(os.devnull, 'w') # shouldn't be able to create instance type with 0 vcpus - retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "create", self.name, "256", "0",\ - "120", self.flavorid], stdout=fnull) + retcode = subprocess.call(["bin/nova-manage", "instance_type", + "create", self.name + "bad_args", + "256", "0", "120", self.flavorid], + stdout=self.fnull) self.assertEqual(1, retcode) def test_should_fail_on_duplicate_flavorid(self): - fnull = open(os.devnull, 'w') # flavorid 1 is set in migration seed data retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "create", self.name, "256", "1",\ - "120", "1"], stdout=fnull) - self.assertEqual(1, retcode) + "create", self.name + "dupflavor", "256", + "1", "120", "1"], stdout=self.fnull) + self.assertEqual(3, retcode) def test_should_fail_on_duplicate_name(self): - # FIXME(ken-pepple) duplicate_name really needs to be unique - duplicate_name = "sdfsdfsafsdfsd" - fnull = open(os.devnull, 'w') + duplicate_name = self.name + "dup_name" retcode = subprocess.call([ "bin/nova-manage", "instance_type", @@ -102,27 +102,29 @@ class NovaManageTestCase(test.TestCase): "2", "10", "10"], - stdout=fnull) + stdout=self.fnull) + self.assertEqual(0, retcode) duplicate_retcode = subprocess.call([ "bin/nova-manage", "instance_type", "create", duplicate_name, - "256", + "512", "1", - "120", - self.flavorid, + "240", + str(int(self.flavorid) + 1), "2", "10", "10"], - stdout=fnull) + stdout=self.fnull) self.assertEqual(3, duplicate_retcode) - delete_retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "delete", duplicate_name], stdout=fnull) + delete_retcode = subprocess.call(["bin/nova-manage", "instance_type", + "delete", duplicate_name, "--purge"], + stdout=self.fnull) self.assertEqual(0, delete_retcode) def test_instance_type_delete_should_fail_without_valid_name(self): - fnull = open(os.devnull, 'w') - retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "delete", "doesntexist"], stdout=fnull) + retcode = subprocess.call(["bin/nova-manage", "instance_type", + "delete", "doesntexist"], + stdout=self.fnull) self.assertEqual(1, retcode) -- cgit From bf222b9173e0a5a0bfbcf4705caab390ee33334b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 24 Feb 2011 11:17:42 -0800 Subject: moved migrate script to 007 (again..sigh) --- .../versions/006_add_instance_types.py | 86 ---------------------- .../versions/007_add_instance_types.py | 86 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 86 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/006_add_instance_types.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py (limited to 'nova') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/006_add_instance_types.py b/nova/db/sqlalchemy/migrate_repo/versions/006_add_instance_types.py deleted file mode 100644 index fec191214..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/006_add_instance_types.py +++ /dev/null @@ -1,86 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# 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 * -from migrate import * - -from nova import api -from nova import db -from nova import log as logging - -import datetime - -meta = MetaData() - - -# -# New Tables -# -instance_types = Table('instance_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('name', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False), - unique=True), - Column('id', Integer(), primary_key=True, nullable=False), - Column('memory_mb', Integer(), nullable=False), - Column('vcpus', Integer(), nullable=False), - Column('local_gb', Integer(), nullable=False), - Column('flavorid', Integer(), nullable=False, unique=True), - Column('swap', Integer(), nullable=False, default=0), - Column('rxtx_quota', Integer(), nullable=False, default=0), - Column('rxtx_cap', Integer(), nullable=False, default=0)) - - -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: - instance_types.create() - except Exception: - logging.info(repr(table)) - logging.exception('Exception while creating instance_types table') - raise - - # Here are the old static instance types - INSTANCE_TYPES = { - 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), - 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), - 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} - try: - i = instance_types.insert() - for name, values in INSTANCE_TYPES.iteritems(): - # FIXME(kpepple) should we be seeding created_at / updated_at ? - # now = datetime.datatime.utcnow() - i.execute({'name': name, 'memory_mb': values["memory_mb"], - 'vcpus': values["vcpus"], 'deleted': 0, - 'local_gb': values["local_gb"], - 'flavorid': values["flavorid"]}) - except Exception: - logging.info(repr(table)) - logging.exception('Exception while seeding instance_types table') - raise - - -def downgrade(migrate_engine): - # Operations to reverse the above upgrade go here. - for table in (instance_types): - table.drop() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py new file mode 100644 index 000000000..fec191214 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py @@ -0,0 +1,86 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# 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 * +from migrate import * + +from nova import api +from nova import db +from nova import log as logging + +import datetime + +meta = MetaData() + + +# +# New Tables +# +instance_types = Table('instance_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('name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + unique=True), + Column('id', Integer(), primary_key=True, nullable=False), + Column('memory_mb', Integer(), nullable=False), + Column('vcpus', Integer(), nullable=False), + Column('local_gb', Integer(), nullable=False), + Column('flavorid', Integer(), nullable=False, unique=True), + Column('swap', Integer(), nullable=False, default=0), + Column('rxtx_quota', Integer(), nullable=False, default=0), + Column('rxtx_cap', Integer(), nullable=False, default=0)) + + +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: + instance_types.create() + except Exception: + logging.info(repr(table)) + logging.exception('Exception while creating instance_types table') + raise + + # Here are the old static instance types + INSTANCE_TYPES = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + try: + i = instance_types.insert() + for name, values in INSTANCE_TYPES.iteritems(): + # FIXME(kpepple) should we be seeding created_at / updated_at ? + # now = datetime.datatime.utcnow() + i.execute({'name': name, 'memory_mb': values["memory_mb"], + 'vcpus': values["vcpus"], 'deleted': 0, + 'local_gb': values["local_gb"], + 'flavorid': values["flavorid"]}) + except Exception: + logging.info(repr(table)) + logging.exception('Exception while seeding instance_types table') + raise + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + for table in (instance_types): + table.drop() -- cgit From 7f3dbdab80a4b36a75c860fe1748dfbd03228f2a Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 28 Feb 2011 11:29:52 -0800 Subject: moving nova-manage integration tests to smoke tests --- nova/tests/test_nova_manage.py | 130 ----------------------------------------- 1 file changed, 130 deletions(-) delete mode 100644 nova/tests/test_nova_manage.py (limited to 'nova') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py deleted file mode 100644 index 03aea53c9..000000000 --- a/nova/tests/test_nova_manage.py +++ /dev/null @@ -1,130 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# 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. -""" -Tests For Nova-Manage -""" - -import time -import os -import subprocess - -from nova import test -from nova.db.sqlalchemy.session import get_session -from nova.db.sqlalchemy import models - - -class NovaManageTestCase(test.TestCase): - """Test case for nova-manage""" - def setUp(self): - super(NovaManageTestCase, self).setUp() - session = get_session() - max_flavorid = session.query(models.InstanceTypes).\ - order_by("flavorid desc").first() - self.flavorid = str(max_flavorid["flavorid"] + 1) - self.name = str(int(time.time())) - self.fnull = open(os.devnull, 'w') - - def teardown(self): - self.fnull.close() - - def test_create_and_delete_instance_types(self): - myname = self.name + "create_and_delete" - retcode = subprocess.call([ - "bin/nova-manage", - "instance_type", - "create", - self.name, - "256", - "1", - "120", - self.flavorid, - "2", - "10", - "10"], - stdout=self.fnull) - self.assertEqual(0, retcode) - retcode = subprocess.call(["bin/nova-manage", "instance_type", - "delete", self.name], stdout=self.fnull) - self.assertEqual(0, retcode) - retcode = subprocess.call(["bin/nova-manage", "instance_type", - "delete", self.name, "--purge"], - stdout=self.fnull) - self.assertEqual(0, retcode) - - def test_list_instance_types_or_flavors(self): - for c in ["instance_type", "flavor"]: - retcode = subprocess.call(["bin/nova-manage", c, \ - "list"], stdout=self.fnull) - self.assertEqual(0, retcode) - - def test_list_specific_instance_type(self): - retcode = subprocess.call(["bin/nova-manage", "instance_type", "list", - "m1.medium"], stdout=self.fnull) - self.assertEqual(0, retcode) - - def test_should_error_on_bad_create_args(self): - # shouldn't be able to create instance type with 0 vcpus - retcode = subprocess.call(["bin/nova-manage", "instance_type", - "create", self.name + "bad_args", - "256", "0", "120", self.flavorid], - stdout=self.fnull) - self.assertEqual(1, retcode) - - def test_should_fail_on_duplicate_flavorid(self): - # flavorid 1 is set in migration seed data - retcode = subprocess.call(["bin/nova-manage", "instance_type",\ - "create", self.name + "dupflavor", "256", - "1", "120", "1"], stdout=self.fnull) - self.assertEqual(3, retcode) - - def test_should_fail_on_duplicate_name(self): - duplicate_name = self.name + "dup_name" - retcode = subprocess.call([ - "bin/nova-manage", - "instance_type", - "create", - duplicate_name, - "256", - "1", - "120", - self.flavorid, - "2", - "10", - "10"], - stdout=self.fnull) - self.assertEqual(0, retcode) - duplicate_retcode = subprocess.call([ - "bin/nova-manage", - "instance_type", - "create", - duplicate_name, - "512", - "1", - "240", - str(int(self.flavorid) + 1), - "2", - "10", - "10"], - stdout=self.fnull) - self.assertEqual(3, duplicate_retcode) - delete_retcode = subprocess.call(["bin/nova-manage", "instance_type", - "delete", duplicate_name, "--purge"], - stdout=self.fnull) - self.assertEqual(0, delete_retcode) - - def test_instance_type_delete_should_fail_without_valid_name(self): - retcode = subprocess.call(["bin/nova-manage", "instance_type", - "delete", "doesntexist"], - stdout=self.fnull) - self.assertEqual(1, retcode) -- cgit From 7ad5fe27144e592df7e794a0748301d41603377e Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 28 Feb 2011 13:16:07 -0800 Subject: refactored nova-manage list (-all, ) and fixed docs --- nova/db/sqlalchemy/api.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d47b11891..f4cd16d9a 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2090,16 +2090,18 @@ def instance_type_create(context, values): @require_context def instance_type_get_all(context, inactive=0): """ - Returns a dict describing all non-deleted instance_types with name as key: - {'m1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3)} + Returns a dict describing all instance_types with name as key. """ session = get_session() - inst_types = session.query(models.InstanceTypes).\ - filter_by(deleted=inactive).\ - order_by("name").\ - all() + if inactive: + inst_types = session.query(models.InstanceTypes).\ + order_by("name").\ + all() + else: + inst_types = session.query(models.InstanceTypes).\ + filter_by(deleted=inactive).\ + order_by("name").\ + all() if inst_types: inst_dict = {} for i in inst_types: -- cgit From aafd83233a675ccf5f3c4e737d966652e45a0ecb Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 28 Feb 2011 16:28:46 -0800 Subject: replaced ugly INSTANCE_TYPE constant with (slightly less ugly) stubs --- nova/test.py | 8 -------- nova/tests/db/fakes.py | 20 ++++++++++++++++++-- nova/tests/test_quota.py | 17 ++++++++++++++--- nova/tests/test_xenapi.py | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) (limited to 'nova') diff --git a/nova/test.py b/nova/test.py index 0329383b8..d8a47464f 100644 --- a/nova/test.py +++ b/nova/test.py @@ -48,14 +48,6 @@ flags.DEFINE_bool('fake_tests', True, 'should we use everything for testing') -INSTANCE_TYPES = { - 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), - 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), - 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} - - def skip_if_fake(func): """Decorator that skips a test if running in fake mode""" def _skipper(*args, **kw): diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index d9a5032ee..d760dc456 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -22,12 +22,20 @@ import time from nova import db from nova import test from nova import utils -from nova.compute import instance_types def stub_out_db_instance_api(stubs): """ Stubs out the db API for creating Instances """ + INSTANCE_TYPES = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': + dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + 'm1.xlarge': + dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + class FakeModel(object): """ Stubs out for model """ def __init__(self, values): @@ -42,10 +50,16 @@ def stub_out_db_instance_api(stubs): else: raise NotImplementedError() + def fake_instance_type_get_all(context, inactive=0): + return INSTANCE_TYPES + + def fake_instance_type_get_by_name(context, name): + return INSTANCE_TYPES[name] + def fake_instance_create(values): """ Stubs out the db.instance_create method """ - type_data = test.INSTANCE_TYPES[values['instance_type']] + type_data = INSTANCE_TYPES[values['instance_type']] base_options = { 'name': values['name'], @@ -74,3 +88,5 @@ def stub_out_db_instance_api(stubs): stubs.Set(db, 'instance_create', fake_instance_create) stubs.Set(db, 'network_get_by_instance', fake_network_get_by_instance) + stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all) + stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name) diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py index faafe2d31..4ecb36b54 100644 --- a/nova/tests/test_quota.py +++ b/nova/tests/test_quota.py @@ -74,19 +74,30 @@ class QuotaTestCase(test.TestCase): vol['size'] = size return db.volume_create(self.context, vol)['id'] + def _get_instance_type(self, name): + instance_types = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': + dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + 'm1.xlarge': + dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + return instance_types[name] + def test_quota_overrides(self): """Make sure overriding a projects quotas works""" num_instances = quota.allowed_instances(self.context, 100, - test.INSTANCE_TYPES['m1.small']) + self._get_instance_type('m1.small')) self.assertEqual(num_instances, 2) db.quota_create(self.context, {'project_id': self.project.id, 'instances': 10}) num_instances = quota.allowed_instances(self.context, 100, - test.INSTANCE_TYPES['m1.small']) + self._get_instance_type('m1.small')) self.assertEqual(num_instances, 4) db.quota_update(self.context, self.project.id, {'cores': 100}) num_instances = quota.allowed_instances(self.context, 100, - test.INSTANCE_TYPES['m1.small']) + self._get_instance_type('m1.small')) self.assertEqual(num_instances, 10) # metadata_items diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 27131c45e..106c0bd6f 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -233,7 +233,7 @@ class XenAPIVMTestCase(test.TestCase): vm = vms[0] # Check that m1.large above turned into the right thing. - instance_type = test.INSTANCE_TYPES['m1.large'] + instance_type = db.instance_type_get_by_name(conn, 'm1.large') mem_kib = long(instance_type['memory_mb']) << 10 mem_bytes = str(mem_kib << 10) vcpus = instance_type['vcpus'] -- cgit From 69779dcdc5584fafa95974f263cef14912a12ed7 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 28 Feb 2011 17:06:35 -0800 Subject: refactored adminclient --- nova/api/ec2/admin.py | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'nova') diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index d867e5da9..51a06bb26 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -29,7 +29,6 @@ from nova import flags from nova import log as logging from nova import utils from nova.auth import manager -from nova.compute import instance_types FLAGS = flags.FLAGS @@ -115,21 +114,10 @@ class AdminController(object): def __str__(self): return 'AdminController' - # FIXME(kpepple) this is untested code path. def describe_instance_types(self, _context, **_kwargs): """Returns all active instance types data (vcpus, memory, etc.)""" - # return {'instanceTypeSet': [instance_dict(n, v) for n, v in - # instance_types.INSTANCE_TYPES.iteritems()]} - # return {'instanceTypeSet': - # [for i in db.instance_type_get_all(): instance_dict(i)]} return {'instanceTypeSet': [db.instance_type_get_all(_context)]} - # FIXME(kpepple) this is untested code path. - def describe_instance_type(self, _context, name, **_kwargs): - """Returns a specific active instance types data""" - return {'instanceTypeSet': - [instance_dict(db.instance_type_get_by_name(name))]} - def describe_user(self, _context, name, **_kwargs): """Returns user data, including access and secret keys.""" return user_dict(manager.AuthManager().get_user(name)) -- cgit From 282a18a4c15f066e371596104f783f522309c5ee Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Tue, 1 Mar 2011 10:40:56 -0800 Subject: corrected copyrights for new files --- nova/compute/instance_types.py | 1 + nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py | 1 + nova/tests/test_instance_types.py | 1 + 3 files changed, 3 insertions(+) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index ce4b25964..7d401fc86 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -4,6 +4,7 @@ # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # Copyright (c) 2010 Citrix Systems, Inc. +# Copyright 2011 Ken Pepple # # 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/migrate_repo/versions/007_add_instance_types.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py index fec191214..66609054e 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py @@ -1,5 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2011 Ken Pepple # 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 diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 1b192ca28..edc538879 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -1,5 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2011 Ken Pepple # 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 -- cgit From 077a77a1ab6fbec468b36e2975c1e185235c17ff Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 15:49:51 -0800 Subject: removed create and delete method (and corresponding tests) from flavors.py --- nova/api/openstack/flavors.py | 20 -------------------- nova/tests/api/openstack/test_flavors.py | 14 ++------------ 2 files changed, 2 insertions(+), 32 deletions(-) (limited to 'nova') diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 375e12b18..4db812c2d 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -56,26 +56,6 @@ class Controller(wsgi.Controller): return dict(flavor=values) raise faults.Fault(exc.HTTPNotFound()) - def create(self, req): - """Create a flavor.""" - #TODO(jk0): Finish this later - #instance_types.create( - # name, - # memory, - # vcpus, - # local_gb, - # flavor_id, - # swap, - # rxtx_quota, - # rxtx_cap) - return "CREATE! %s" % req - - def delete(self, req, id): - """Delete a flavor.""" - #TODO(jk0): Finish this later - #instance_type.destroy(name) - return "DELETE! %s %s" % (req, id) - def _all_ids(self): """Return the list of all flavorids.""" # FIXME(kpepple) do we really need admin context here ? diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 2626f92ba..319767bb5 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -46,17 +46,7 @@ class FlavorsTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 200) - def test_create_flavor(self): - req = webob.Request.blank("/v1.0/flavors") - req.method = "POST" - res = req.get_response(fakes.wsgi_app()) - self.assertEqual(res.status_int, 200) - - def test_delete_flavor(self): - req = webob.Request.blank("/v1.0/flavors/1") - req.method = "DELETE" + def test_get_flavor_by_id(self): + req = webob.Request.blank('/v1.0/flavors/1') res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 200) - - def test_get_flavor_by_id(self): - pass -- cgit From 4243e8e2b41f1438023b1184b1281474b27b5467 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 16:09:27 -0800 Subject: coding style change per devcamcar review --- nova/compute/instance_types.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 7d401fc86..20cf1faee 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -30,15 +30,8 @@ from nova import exception FLAGS = flags.FLAGS -def create( - name, - memory, - vcpus, - local_gb, - flavorid, - swap=0, - rxtx_quota=0, - rxtx_cap=0): +def create(name, memory, vcpus, local_gb, flavorid, swap=0, + rxtx_quota=0,rxtx_cap=0): """Creates instance types / flavors arguments: name memory vcpus local_gb flavorid swap rxtx_quota rxtx_cap """ -- cgit From 0bf74ef365688476b2b3a44e353c0062989d33b5 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 16:12:22 -0800 Subject: fixed _context typo --- nova/api/ec2/admin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova') diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index 51a06bb26..d9a4ef999 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -114,9 +114,9 @@ class AdminController(object): def __str__(self): return 'AdminController' - def describe_instance_types(self, _context, **_kwargs): + def describe_instance_types(self, context, **_kwargs): """Returns all active instance types data (vcpus, memory, etc.)""" - return {'instanceTypeSet': [db.instance_type_get_all(_context)]} + return {'instanceTypeSet': [db.instance_type_get_all(context)]} def describe_user(self, _context, name, **_kwargs): """Returns user data, including access and secret keys.""" -- cgit From 22ec4e190ccf9e30a7862e1ee7d90f2a0858c438 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 16:12:36 -0800 Subject: pep8 --- nova/compute/instance_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 20cf1faee..f360a7ac3 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -31,7 +31,7 @@ FLAGS = flags.FLAGS def create(name, memory, vcpus, local_gb, flavorid, swap=0, - rxtx_quota=0,rxtx_cap=0): + rxtx_quota=0, rxtx_cap=0): """Creates instance types / flavors arguments: name memory vcpus local_gb flavorid swap rxtx_quota rxtx_cap """ -- cgit From 86aed7edae3dd90741d0da704a99460701b8bcc7 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 16:32:09 -0800 Subject: added in req.environ for context --- nova/api/openstack/flavors.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'nova') diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 4db812c2d..f3d040ba3 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -41,25 +41,19 @@ class Controller(wsgi.Controller): def detail(self, req): """Return all flavors in detail.""" - items = [self.show(req, id)['flavor'] for id in self._all_ids()] + items = [self.show(req, id)['flavor'] for id in self._all_ids(req)] return dict(flavors=items) def show(self, req, id): """Return data about the given flavor id.""" - # FIXME(kpepple) do we really need admin context here ? - ctxt = context.get_admin_context() + ctxt = req.environ['nova.context'] values = db.instance_type_get_by_flavor_id(ctxt, id) - # FIXME(kpepple) refactor db call to return dict - # v = val.values()[0] - # item = dict(ram=v['memory_mb'], disk=v['local_gb'], - # id=v['flavorid'], name=val.keys()[0]) return dict(flavor=values) raise faults.Fault(exc.HTTPNotFound()) - def _all_ids(self): + def _all_ids(self, req): """Return the list of all flavorids.""" - # FIXME(kpepple) do we really need admin context here ? - ctxt = context.get_admin_context() + ctxt = req.environ['nova.context'] inst_types = db.instance_type_get_all(ctxt) flavor_ids = [inst_types[i]['flavorid'] for i in inst_types.keys()] - return flavor_ids + return sorted(flavor_ids) -- cgit From 28896fcfb474662fe339fa5b05aec33b3896b4fa Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 16:37:02 -0800 Subject: changed _context --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index f4cd16d9a..919dda118 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2077,7 +2077,7 @@ def console_get(context, console_id, instance_id=None): @require_admin_context -def instance_type_create(context, values): +def instance_type_create(_context, values): try: instance_type_ref = models.InstanceTypes() instance_type_ref.update(values) -- cgit From 1abd891f65ea8291dc0c3f2075de80dc92c0d431 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 16:46:32 -0800 Subject: corrected error message --- nova/compute/instance_types.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index f360a7ac3..d31d3c304 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -58,8 +58,7 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, rxtx_quota=rxtx_quota, rxtx_cap=rxtx_cap)) except exception.DBError: - raise exception.ApiError(_("Cannot create instance type: %s"), - name) + raise exception.ApiError(_("Cannot create instance type: %s" % name)) def destroy(name): @@ -71,8 +70,7 @@ def destroy(name): try: db.instance_type_destroy(context.get_admin_context(), name) except exception.NotFound: - raise exception.ApiError(_("Unknown instance type: %s"), - name) + raise exception.ApiError(_("Unknown instance type: %s" % name)) def purge(name): @@ -84,8 +82,7 @@ def purge(name): try: db.instance_type_purge(context.get_admin_context(), name) except exception.NotFound: - raise exception.ApiError(_("Unknown instance type: %s"), - name) + raise exception.ApiError(_("Unknown instance type: %s" % name)) def get_all_types(inactive=0): @@ -109,8 +106,7 @@ def get_instance_type(name): inst_type = db.instance_type_get_by_name(ctxt, name) return inst_type except exception.DBError: - raise exception.ApiError(_("Unknown instance type: %s"), - name) + raise exception.ApiError(_("Unknown instance type: %s" % name)) def get_by_type(instance_type): @@ -123,8 +119,8 @@ def get_by_type(instance_type): inst_type = db.instance_type_get_by_name(ctxt, instance_type) return inst_type['name'] except exception.DBError: - raise exception.ApiError(_("Unknown instance type: %s"), - instance_type) + raise exception.ApiError(_("Unknown instance type: %s" %\ + instance_type)) def get_by_flavor_id(flavor_id): @@ -136,5 +132,4 @@ def get_by_flavor_id(flavor_id): flavor = db.instance_type_get_by_flavor_id(ctxt, flavor_id) return flavor['name'] except exception.DBError: - raise exception.ApiError(_("Unknown flavor: %s"), - flavor_id) + raise exception.ApiError(_("Unknown flavor: %s" % flavor_id)) -- cgit From 45662001c477bdce7cd50b4f7f67e06479c3cbd3 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 16:59:38 -0800 Subject: requested style change --- nova/compute/instance_types.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index d31d3c304..09b42f319 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -48,8 +48,7 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, try: db.instance_type_create( context.get_admin_context(), - dict( - name=name, + dict(name=name, memory_mb=memory, vcpus=vcpus, local_gb=local_gb, -- cgit From 507a13d8dcdc11ea7638c8904d6d0de22d8e109b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 17:14:51 -0800 Subject: added logging to instance_types for DB errors per code review --- nova/compute/instance_types.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 09b42f319..79c879e8e 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -24,10 +24,12 @@ The built-in instance properties. from nova import context from nova import db -from nova import flags from nova import exception +from nova import flags +from nova import log as logging FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.instance_types') def create(name, memory, vcpus, local_gb, flavorid, swap=0, @@ -56,7 +58,8 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, swap=swap, rxtx_quota=rxtx_quota, rxtx_cap=rxtx_cap)) - except exception.DBError: + except exception.DBError, e: + LOG.exception(_('DB error: %s' % e)) raise exception.ApiError(_("Cannot create instance type: %s" % name)) @@ -69,6 +72,7 @@ def destroy(name): try: db.instance_type_destroy(context.get_admin_context(), name) except exception.NotFound: + LOG.exception(_('Instance type %s not found for deletion' % name)) raise exception.ApiError(_("Unknown instance type: %s" % name)) @@ -81,6 +85,7 @@ def purge(name): try: db.instance_type_purge(context.get_admin_context(), name) except exception.NotFound: + LOG.exception(_('Instance type %s not found for purge' % name)) raise exception.ApiError(_("Unknown instance type: %s" % name)) @@ -117,7 +122,8 @@ def get_by_type(instance_type): ctxt = context.get_admin_context() inst_type = db.instance_type_get_by_name(ctxt, instance_type) return inst_type['name'] - except exception.DBError: + except exception.DBError, e: + LOG.exception(_('DB error: %s' % e)) raise exception.ApiError(_("Unknown instance type: %s" %\ instance_type)) @@ -130,5 +136,6 @@ def get_by_flavor_id(flavor_id): ctxt = context.get_admin_context() flavor = db.instance_type_get_by_flavor_id(ctxt, flavor_id) return flavor['name'] - except exception.DBError: + except exception.DBError, e: + LOG.exception(_('DB error: %s' % e)) raise exception.ApiError(_("Unknown flavor: %s" % flavor_id)) -- cgit From 74f2a7537e9e4b8259a4179adc21eef59e59d3c5 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 17:38:42 -0800 Subject: catching bare except: --- nova/compute/instance_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 79c879e8e..fa02a5dfa 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -40,7 +40,7 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, for option in [memory, vcpus, local_gb, flavorid]: try: int(option) - except: + except ValueError: raise exception.InvalidInputException( _("create arguments must be positive integers")) if (int(memory) <= 0) or (int(vcpus) <= 0) or (int(local_gb) < 0): -- cgit From dc8e308819fb383b317ff866288965a27016557e Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 2 Mar 2011 17:54:04 -0800 Subject: moved migration to 008 (sigh) --- .../versions/007_add_instance_types.py | 87 ---------------------- .../versions/008_add_instance_types.py | 87 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 87 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py (limited to 'nova') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py deleted file mode 100644 index 66609054e..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py +++ /dev/null @@ -1,87 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 Ken Pepple -# 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 * -from migrate import * - -from nova import api -from nova import db -from nova import log as logging - -import datetime - -meta = MetaData() - - -# -# New Tables -# -instance_types = Table('instance_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('name', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False), - unique=True), - Column('id', Integer(), primary_key=True, nullable=False), - Column('memory_mb', Integer(), nullable=False), - Column('vcpus', Integer(), nullable=False), - Column('local_gb', Integer(), nullable=False), - Column('flavorid', Integer(), nullable=False, unique=True), - Column('swap', Integer(), nullable=False, default=0), - Column('rxtx_quota', Integer(), nullable=False, default=0), - Column('rxtx_cap', Integer(), nullable=False, default=0)) - - -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: - instance_types.create() - except Exception: - logging.info(repr(table)) - logging.exception('Exception while creating instance_types table') - raise - - # Here are the old static instance types - INSTANCE_TYPES = { - 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), - 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), - 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), - 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} - try: - i = instance_types.insert() - for name, values in INSTANCE_TYPES.iteritems(): - # FIXME(kpepple) should we be seeding created_at / updated_at ? - # now = datetime.datatime.utcnow() - i.execute({'name': name, 'memory_mb': values["memory_mb"], - 'vcpus': values["vcpus"], 'deleted': 0, - 'local_gb': values["local_gb"], - 'flavorid': values["flavorid"]}) - except Exception: - logging.info(repr(table)) - logging.exception('Exception while seeding instance_types table') - raise - - -def downgrade(migrate_engine): - # Operations to reverse the above upgrade go here. - for table in (instance_types): - table.drop() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py b/nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py new file mode 100644 index 000000000..66609054e --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py @@ -0,0 +1,87 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Ken Pepple +# 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 * +from migrate import * + +from nova import api +from nova import db +from nova import log as logging + +import datetime + +meta = MetaData() + + +# +# New Tables +# +instance_types = Table('instance_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('name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + unique=True), + Column('id', Integer(), primary_key=True, nullable=False), + Column('memory_mb', Integer(), nullable=False), + Column('vcpus', Integer(), nullable=False), + Column('local_gb', Integer(), nullable=False), + Column('flavorid', Integer(), nullable=False, unique=True), + Column('swap', Integer(), nullable=False, default=0), + Column('rxtx_quota', Integer(), nullable=False, default=0), + Column('rxtx_cap', Integer(), nullable=False, default=0)) + + +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: + instance_types.create() + except Exception: + logging.info(repr(table)) + logging.exception('Exception while creating instance_types table') + raise + + # Here are the old static instance types + INSTANCE_TYPES = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2), + 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4), + 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + try: + i = instance_types.insert() + for name, values in INSTANCE_TYPES.iteritems(): + # FIXME(kpepple) should we be seeding created_at / updated_at ? + # now = datetime.datatime.utcnow() + i.execute({'name': name, 'memory_mb': values["memory_mb"], + 'vcpus': values["vcpus"], 'deleted': 0, + 'local_gb': values["local_gb"], + 'flavorid': values["flavorid"]}) + except Exception: + logging.info(repr(table)) + logging.exception('Exception while seeding instance_types table') + raise + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + for table in (instance_types): + table.drop() -- cgit