diff options
38 files changed, 275 insertions, 74 deletions
diff --git a/etc/nova/policy.json b/etc/nova/policy.json index 97ae89a38..1a446263f 100644 --- a/etc/nova/policy.json +++ b/etc/nova/policy.json @@ -83,6 +83,10 @@ "compute_extension:virtual_interfaces": "", "compute_extension:virtual_storage_arrays": "", "compute_extension:volumes": "", + "compute_extension:volume_attachments:index": "", + "compute_extension:volume_attachments:show": "", + "compute_extension:volume_attachments:create": "", + "compute_extension:volume_attachments:delete": "", "compute_extension:volumetypes": "", "compute_extension:availability_zone:list": "", "compute_extension:availability_zone:detail": "rule:admin_api", diff --git a/nova/api/openstack/compute/contrib/flavorextraspecs.py b/nova/api/openstack/compute/contrib/flavorextraspecs.py index c8deb7b4c..84f157b6a 100644 --- a/nova/api/openstack/compute/contrib/flavorextraspecs.py +++ b/nova/api/openstack/compute/contrib/flavorextraspecs.py @@ -34,6 +34,15 @@ class ExtraSpecsTemplate(xmlutil.TemplateBuilder): return xmlutil.MasterTemplate(xmlutil.make_flat_dict('extra_specs'), 1) +class ExtraSpecTemplate(xmlutil.TemplateBuilder): + def construct(self): + sel = xmlutil.Selector(xmlutil.get_items, 0) + root = xmlutil.TemplateElement('extra_spec', selector=sel) + root.set('key', 0) + root.text = 1 + return xmlutil.MasterTemplate(root, 1) + + class FlavorExtraSpecsController(object): """The flavor extra specs API controller for the OpenStack API.""" @@ -70,7 +79,7 @@ class FlavorExtraSpecsController(object): raise exc.HTTPBadRequest(explanation=unicode(error)) return body - @wsgi.serializers(xml=ExtraSpecsTemplate) + @wsgi.serializers(xml=ExtraSpecTemplate) def update(self, req, flavor_id, id, body): context = req.environ['nova.context'] authorize(context) @@ -87,10 +96,9 @@ class FlavorExtraSpecsController(object): body) except exception.MetadataLimitExceeded as error: raise exc.HTTPBadRequest(explanation=unicode(error)) - return body - @wsgi.serializers(xml=ExtraSpecsTemplate) + @wsgi.serializers(xml=ExtraSpecTemplate) def show(self, req, flavor_id, id): """Return a single extra spec item.""" context = req.environ['nova.context'] diff --git a/nova/api/openstack/compute/contrib/volumes.py b/nova/api/openstack/compute/contrib/volumes.py index 47c717495..3fc503217 100644 --- a/nova/api/openstack/compute/contrib/volumes.py +++ b/nova/api/openstack/compute/contrib/volumes.py @@ -33,6 +33,15 @@ from nova import volume LOG = logging.getLogger(__name__) authorize = extensions.extension_authorizer('compute', 'volumes') +authorize_attach_index = extensions.extension_authorizer('compute', + 'volume_attachments:index') +authorize_attach_show = extensions.extension_authorizer('compute', + 'volume_attachments:show') +authorize_attach_create = extensions.extension_authorizer('compute', + 'volume_attachments:create') +authorize_attach_delete = extensions.extension_authorizer('compute', + 'volume_attachments:delete') + def _translate_volume_detail_view(context, vol): """Maps keys for volumes details view.""" @@ -329,6 +338,8 @@ class VolumeAttachmentController(wsgi.Controller): @wsgi.serializers(xml=VolumeAttachmentsTemplate) def index(self, req, server_id): """Returns the list of volume attachments for a given instance.""" + context = req.environ['nova.context'] + authorize_attach_index(context) return self._items(req, server_id, entity_maker=_translate_attachment_summary_view) @@ -337,6 +348,7 @@ class VolumeAttachmentController(wsgi.Controller): """Return data about the given volume attachment.""" context = req.environ['nova.context'] authorize(context) + authorize_attach_show(context) volume_id = id try: @@ -377,6 +389,7 @@ class VolumeAttachmentController(wsgi.Controller): """Attach a volume to an instance.""" context = req.environ['nova.context'] authorize(context) + authorize_attach_create(context) if not self.is_valid_body(body, 'volumeAttachment'): raise exc.HTTPUnprocessableEntity() @@ -423,6 +436,7 @@ class VolumeAttachmentController(wsgi.Controller): """Detach a volume from an instance.""" context = req.environ['nova.context'] authorize(context) + authorize_attach_delete(context) volume_id = id LOG.audit(_("Detach volume %s"), volume_id, context=context) diff --git a/nova/compute/api.py b/nova/compute/api.py index 06ce2e07e..a9d0a1bdd 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -508,6 +508,13 @@ class API(base.Base): availability_zone, forced_host = self._handle_availability_zone( availability_zone) + system_metadata = {} + instance_type_props = ['id', 'name', 'memory_mb', 'vcpus', + 'root_gb', 'ephemeral_gb', 'flavorid', + 'swap', 'rxtx_factor', 'vcpu_weight'] + for k in instance_type_props: + system_metadata["instance_type_%s" % k] = instance_type[k] + base_options = { 'reservation_id': reservation_id, 'image_ref': image_href, @@ -537,7 +544,8 @@ class API(base.Base): 'access_ip_v6': access_ip_v6, 'availability_zone': availability_zone, 'root_device_name': root_device_name, - 'progress': 0} + 'progress': 0, + 'system_metadata': system_metadata} options_from_image = self._inherit_properties_from_image( image, auto_disk_config) @@ -558,6 +566,11 @@ class API(base.Base): security_group, block_device_mapping) instances.append(instance) instance_uuids.append(instance['uuid']) + self._validate_bdm(context, instance) + # send a state update notification for the initial create to + # show it going from non-existent to BUILDING + notifications.send_update_with_states(context, instance, None, + vm_states.BUILDING, None, None, service="api") # In the case of any exceptions, attempt DB cleanup and rollback the # quota reservations. @@ -704,6 +717,23 @@ class API(base.Base): self.db.block_device_mapping_update_or_create(elevated_context, values) + def _validate_bdm(self, context, instance): + for bdm in self.db.block_device_mapping_get_all_by_instance( + context, instance['uuid']): + # NOTE(vish): For now, just make sure the volumes are accessible. + snapshot_id = bdm.get('snapshot_id') + volume_id = bdm.get('volume_id') + if volume_id is not None: + try: + self.volume_api.get(context, volume_id) + except Exception: + raise exception.InvalidBDMVolume(id=volume_id) + elif snapshot_id is not None: + try: + self.volume_api.get_snapshot(context, snapshot_id) + except Exception: + raise exception.InvalidBDMSnapshot(id=snapshot_id) + def _populate_instance_for_bdm(self, context, instance, instance_type, image, block_device_mapping): """Populate instance block device mapping information.""" @@ -818,11 +848,6 @@ class API(base.Base): self._populate_instance_for_bdm(context, instance, instance_type, image, block_device_mapping) - # send a state update notification for the initial create to - # show it going from non-existent to BUILDING - notifications.send_update_with_states(context, instance, None, - vm_states.BUILDING, None, None, service="api") - return instance def _check_create_policies(self, context, availability_zone, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 9bdab7a25..b52e85440 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -227,7 +227,8 @@ def wrap_instance_fault(function): with excutils.save_and_reraise_exception(): compute_utils.add_instance_fault_from_exc(context, - kwargs['instance'], e, sys.exc_info()) + self.conductor_api, kwargs['instance'], + e, sys.exc_info()) return decorated_function @@ -730,8 +731,8 @@ class ComputeManager(manager.SchedulerDependentManager): instance_uuid = instance['uuid'] rescheduled = False - compute_utils.add_instance_fault_from_exc(context, instance, - exc_info[1], exc_info=exc_info) + compute_utils.add_instance_fault_from_exc(context, self.conductor_api, + instance, exc_info[1], exc_info=exc_info) try: self._deallocate_network(context, instance) @@ -1463,7 +1464,7 @@ class ComputeManager(manager.SchedulerDependentManager): LOG.error(_('Cannot reboot instance: %(exc)s'), locals(), context=context, instance=instance) compute_utils.add_instance_fault_from_exc(context, - instance, exc, sys.exc_info()) + self.conductor_api, instance, exc, sys.exc_info()) # Fall through and reset task_state to None current_power_state = self._get_power_state(context, instance) @@ -1993,8 +1994,8 @@ class ComputeManager(manager.SchedulerDependentManager): rescheduled = False instance_uuid = instance['uuid'] - compute_utils.add_instance_fault_from_exc(context, instance, - exc_info[0], exc_info=exc_info) + compute_utils.add_instance_fault_from_exc(context, self.conductor_api, + instance, exc_info[0], exc_info=exc_info) try: scheduler_method = self.scheduler_rpcapi.prep_resize diff --git a/nova/compute/utils.py b/nova/compute/utils.py index 1874e886f..daf80874c 100644 --- a/nova/compute/utils.py +++ b/nova/compute/utils.py @@ -37,7 +37,8 @@ CONF.import_opt('host', 'nova.netconf') LOG = log.getLogger(__name__) -def add_instance_fault_from_exc(context, instance, fault, exc_info=None): +def add_instance_fault_from_exc(context, conductor, + instance, fault, exc_info=None): """Adds the specified fault to the database.""" code = 500 @@ -61,7 +62,7 @@ def add_instance_fault_from_exc(context, instance, fault, exc_info=None): 'details': unicode(details), 'host': CONF.host } - db.instance_fault_create(context, values) + conductor.instance_fault_create(context, values) def get_device_name_for_instance(context, instance, bdms, device): diff --git a/nova/conductor/api.py b/nova/conductor/api.py index d05c94877..b0e5afdcb 100644 --- a/nova/conductor/api.py +++ b/nova/conductor/api.py @@ -133,6 +133,9 @@ class LocalAPI(object): def instance_type_get(self, context, instance_type_id): return self._manager.instance_type_get(context, instance_type_id) + def instance_fault_create(self, context, values): + return self._manager.instance_fault_create(context, values) + def migration_get(self, context, migration_id): return self._manager.migration_get(context, migration_id) @@ -391,6 +394,9 @@ class API(object): return self.conductor_rpcapi.instance_type_get(context, instance_type_id) + def instance_fault_create(self, context, values): + return self.conductor_rpcapi.instance_fault_create(context, values) + def migration_get(self, context, migration_id): return self.conductor_rpcapi.migration_get(context, migration_id) diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 87b143912..c4ae33622 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -43,7 +43,7 @@ datetime_fields = ['launched_at', 'terminated_at'] class ConductorManager(manager.SchedulerDependentManager): """Mission: TBD.""" - RPC_API_VERSION = '1.35' + RPC_API_VERSION = '1.36' def __init__(self, *args, **kwargs): super(ConductorManager, self).__init__(service_name='conductor', @@ -258,6 +258,10 @@ class ConductorManager(manager.SchedulerDependentManager): result = self.db.instance_type_get(context, instance_type_id) return jsonutils.to_primitive(result) + def instance_fault_create(self, context, values): + result = self.db.instance_fault_create(context, values) + return jsonutils.to_primitive(result) + def vol_get_usage_by_time(self, context, start_time): result = self.db.vol_get_usage_by_time(context, start_time) return jsonutils.to_primitive(result) diff --git a/nova/conductor/rpcapi.py b/nova/conductor/rpcapi.py index 1699c85ed..04e576cce 100644 --- a/nova/conductor/rpcapi.py +++ b/nova/conductor/rpcapi.py @@ -68,6 +68,7 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): 1.33 - Added compute_node_create and compute_node_update 1.34 - Added service_update 1.35 - Added instance_get_active_by_window_joined + 1.36 - Added instance_fault_create """ BASE_RPC_API_VERSION = '1.0' @@ -293,6 +294,10 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): msg = self.make_msg('instance_get_all_by_host', host=host, node=node) return self.call(context, msg, version='1.32') + def instance_fault_create(self, context, values): + msg = self.make_msg('instance_fault_create', values=values) + return self.call(context, msg, version='1.36') + def action_event_start(self, context, values): msg = self.make_msg('action_event_start', values=values) return self.call(context, msg, version='1.25') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/153_instance_type_in_system_metadata.py b/nova/db/sqlalchemy/migrate_repo/versions/153_instance_type_in_system_metadata.py new file mode 100644 index 000000000..20e75a6eb --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/153_instance_type_in_system_metadata.py @@ -0,0 +1,49 @@ +# Copyright 2013 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import MetaData, select, Table + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + instances = Table('instances', meta, autoload=True) + instance_types = Table('instance_types', meta, autoload=True) + sys_meta = Table('instance_system_metadata', meta, autoload=True) + + # Taken from nova/compute/api.py + instance_type_props = ['id', 'name', 'memory_mb', 'vcpus', + 'root_gb', 'ephemeral_gb', 'flavorid', + 'swap', 'rxtx_factor', 'vcpu_weight'] + + select_columns = [instances.c.uuid] + select_columns += [getattr(instance_types.c, name) + for name in instance_type_props] + + q = select(select_columns, from_obj=instances.join( + instance_types, + instances.c.instance_type_id == instance_types.c.id)) + + i = sys_meta.insert() + for values in q.execute(): + for index in range(0, len(instance_type_props)): + i.execute({"key": "instance_type_%s" % instance_type_props[index], + "value": str(values[index + 1]), + "instance_uuid": values[0]}) + + +def downgrade(migration_engine): + # This migration only touches data, and only metadata at that. No need + # to go through and delete old metadata items. + pass diff --git a/nova/exception.py b/nova/exception.py index bb7749dd7..6915c14bb 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -226,6 +226,20 @@ class Invalid(NovaException): code = 400 +class InvalidBDM(Invalid): + message = _("Block Device Mapping is Invalid.") + + +class InvalidBDMSnapshot(InvalidBDM): + message = _("Block Device Mapping is Invalid: " + "failed to get snapshot %(id)s.") + + +class InvalidBDMVolume(InvalidBDM): + message = _("Block Device Mapping is Invalid: " + "failed to get volume %(id)s.") + + class VolumeUnattached(Invalid): message = _("Volume %(volume_id)s is not attached to anything") diff --git a/nova/tests/api/openstack/compute/contrib/test_flavors_extra_specs.py b/nova/tests/api/openstack/compute/contrib/test_flavors_extra_specs.py index bc9f66eb2..5328ec2ee 100644 --- a/nova/tests/api/openstack/compute/contrib/test_flavors_extra_specs.py +++ b/nova/tests/api/openstack/compute/contrib/test_flavors_extra_specs.py @@ -172,7 +172,6 @@ class FlavorsExtraSpecsXMLSerializerTest(test.TestCase): expected = ("<?xml version='1.0' encoding='UTF-8'?>\n" '<extra_specs><key1>value1</key1></extra_specs>') text = serializer.serialize(dict(extra_specs={"key1": "value1"})) - print text self.assertEqual(text, expected) def test_deserializer(self): @@ -182,3 +181,10 @@ class FlavorsExtraSpecsXMLSerializerTest(test.TestCase): '<extra_specs><key1>value1</key1></extra_specs>') result = deserializer.deserialize(intext)['body'] self.assertEqual(result, expected) + + def test_show_update_serializer(self): + serializer = flavorextraspecs.ExtraSpecTemplate() + expected = ("<?xml version='1.0' encoding='UTF-8'?>\n" + '<extra_spec key="key1">value1</extra_spec>') + text = serializer.serialize(dict({"key1": "value1"})) + self.assertEqual(text, expected) diff --git a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py index a72f5bf0f..0c1378a67 100644 --- a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py +++ b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py @@ -138,7 +138,6 @@ class QuotaTemplateXMLSerializerTest(test.TestCase): cores=90)) text = self.serializer.serialize(exemplar) - print text tree = etree.fromstring(text) self.assertEqual('quota_class_set', tree.tag) diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py index dab8c136e..8d518b815 100644 --- a/nova/tests/api/openstack/compute/contrib/test_quotas.py +++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py @@ -166,7 +166,6 @@ class QuotaXMLSerializerTest(test.TestCase): cores=90)) text = self.serializer.serialize(exemplar) - print text tree = etree.fromstring(text) self.assertEqual('quota_set', tree.tag) diff --git a/nova/tests/api/openstack/compute/contrib/test_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_security_groups.py index ccb58f858..231923e6d 100644 --- a/nova/tests/api/openstack/compute/contrib/test_security_groups.py +++ b/nova/tests/api/openstack/compute/contrib/test_security_groups.py @@ -1180,7 +1180,6 @@ class TestSecurityGroupXMLSerializer(test.TestCase): rule = dict(security_group_rule=raw_rule) text = self.rule_serializer.serialize(rule) - print text tree = etree.fromstring(text) self.assertEqual('security_group_rule', self._tag(tree)) @@ -1212,7 +1211,6 @@ class TestSecurityGroupXMLSerializer(test.TestCase): sg_group = dict(security_group=raw_group) text = self.default_serializer.serialize(sg_group) - print text tree = etree.fromstring(text) self._verify_security_group(raw_group, tree) @@ -1265,7 +1263,6 @@ class TestSecurityGroupXMLSerializer(test.TestCase): sg_groups = dict(security_groups=groups) text = self.index_serializer.serialize(sg_groups) - print text tree = etree.fromstring(text) self.assertEqual('security_groups', self._tag(tree)) diff --git a/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py b/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py index ea4565e14..783275ea2 100644 --- a/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py +++ b/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py @@ -74,7 +74,6 @@ class TestServerDiagnosticsXMLSerializer(test.TestCase): exemplar = dict(diag1='foo', diag2='bar') text = serializer.serialize(exemplar) - print text tree = etree.fromstring(text) self.assertEqual('diagnostics', self._tag(tree)) diff --git a/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py b/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py index b49a1feb4..13a4e9d61 100644 --- a/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py +++ b/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py @@ -293,7 +293,6 @@ class SimpleTenantUsageSerializerTest(test.TestCase): tenant_usage = dict(tenant_usage=raw_usage) text = serializer.serialize(tenant_usage) - print text tree = etree.fromstring(text) self._verify_tenant_usage(raw_usage, tree) @@ -378,7 +377,6 @@ class SimpleTenantUsageSerializerTest(test.TestCase): tenant_usages = dict(tenant_usages=raw_usages) text = serializer.serialize(tenant_usages) - print text tree = etree.fromstring(text) self.assertEqual('tenant_usages', tree.tag) diff --git a/nova/tests/api/openstack/compute/contrib/test_snapshots.py b/nova/tests/api/openstack/compute/contrib/test_snapshots.py index a223178fb..fa0c521fe 100644 --- a/nova/tests/api/openstack/compute/contrib/test_snapshots.py +++ b/nova/tests/api/openstack/compute/contrib/test_snapshots.py @@ -271,7 +271,6 @@ class SnapshotSerializerTest(test.TestCase): ) text = serializer.serialize(dict(snapshot=raw_snapshot)) - print text tree = etree.fromstring(text) self._verify_snapshot(raw_snapshot, tree) @@ -298,7 +297,6 @@ class SnapshotSerializerTest(test.TestCase): )] text = serializer.serialize(dict(snapshots=raw_snapshots)) - print text tree = etree.fromstring(text) self.assertEqual('snapshots', tree.tag) diff --git a/nova/tests/api/openstack/compute/contrib/test_virtual_interfaces.py b/nova/tests/api/openstack/compute/contrib/test_virtual_interfaces.py index 7c61cd51b..cf1c1593f 100644 --- a/nova/tests/api/openstack/compute/contrib/test_virtual_interfaces.py +++ b/nova/tests/api/openstack/compute/contrib/test_virtual_interfaces.py @@ -91,7 +91,6 @@ class ServerVirtualInterfaceSerializerTest(test.TestCase): vifs = dict(virtual_interfaces=raw_vifs) text = self.serializer.serialize(vifs) - print text tree = etree.fromstring(text) self.assertEqual('virtual_interfaces', self._tag(tree)) diff --git a/nova/tests/api/openstack/compute/contrib/test_volumes.py b/nova/tests/api/openstack/compute/contrib/test_volumes.py index 3119f55e8..1a8a570e8 100644 --- a/nova/tests/api/openstack/compute/contrib/test_volumes.py +++ b/nova/tests/api/openstack/compute/contrib/test_volumes.py @@ -348,7 +348,6 @@ class VolumeSerializerTest(test.TestCase): device='/foo') text = serializer.serialize(dict(volumeAttachment=raw_attach)) - print text tree = etree.fromstring(text) self.assertEqual('volumeAttachment', tree.tag) @@ -368,7 +367,6 @@ class VolumeSerializerTest(test.TestCase): device='/foo2')] text = serializer.serialize(dict(volumeAttachments=raw_attaches)) - print text tree = etree.fromstring(text) self.assertEqual('volumeAttachments', tree.tag) @@ -401,7 +399,6 @@ class VolumeSerializerTest(test.TestCase): ) text = serializer.serialize(dict(volume=raw_volume)) - print text tree = etree.fromstring(text) self._verify_volume(raw_volume, tree) @@ -450,7 +447,6 @@ class VolumeSerializerTest(test.TestCase): )] text = serializer.serialize(dict(volumes=raw_volumes)) - print text tree = etree.fromstring(text) self.assertEqual('volumes', tree.tag) diff --git a/nova/tests/api/openstack/compute/test_limits.py b/nova/tests/api/openstack/compute/test_limits.py index 375355a70..e3fff380d 100644 --- a/nova/tests/api/openstack/compute/test_limits.py +++ b/nova/tests/api/openstack/compute/test_limits.py @@ -874,7 +874,6 @@ class LimitsXMLSerializationTest(test.TestCase): "absolute": {}}} output = serializer.serialize(fixture) - print output has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>") self.assertTrue(has_dec) @@ -905,7 +904,6 @@ class LimitsXMLSerializationTest(test.TestCase): "maxPersonalitySize": 10240}}} output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'limits') @@ -940,7 +938,6 @@ class LimitsXMLSerializationTest(test.TestCase): "absolute": {}}} output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'limits') diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py index 5456c23af..4bfb1c1e3 100644 --- a/nova/tests/api/openstack/compute/test_servers.py +++ b/nova/tests/api/openstack/compute/test_servers.py @@ -4508,7 +4508,6 @@ class ServerXMLSerializationTest(test.TestCase): } output = serializer.serialize(fixture) - print output has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>") self.assertTrue(has_dec) @@ -4586,7 +4585,6 @@ class ServerXMLSerializationTest(test.TestCase): } output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'server') @@ -4717,7 +4715,6 @@ class ServerXMLSerializationTest(test.TestCase): } output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'server') @@ -4814,7 +4811,6 @@ class ServerXMLSerializationTest(test.TestCase): ]} output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'servers_index') server_elems = root.findall('{0}server'.format(NS)) @@ -4878,7 +4874,6 @@ class ServerXMLSerializationTest(test.TestCase): ]} output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'servers_index') server_elems = root.findall('{0}server'.format(NS)) @@ -5165,7 +5160,6 @@ class ServerXMLSerializationTest(test.TestCase): } output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'server') diff --git a/nova/tests/api/openstack/compute/test_versions.py b/nova/tests/api/openstack/compute/test_versions.py index 28b109215..bd2e9fa7b 100644 --- a/nova/tests/api/openstack/compute/test_versions.py +++ b/nova/tests/api/openstack/compute/test_versions.py @@ -228,7 +228,6 @@ class VersionsTest(test.TestCase): self.assertEqual(res.content_type, "application/xml") root = etree.XML(res.body) - print res.body xmlutil.validate_schema(root, 'versions') self.assertTrue(root.xpath('/ns:versions', namespaces=NS)) diff --git a/nova/tests/api/openstack/test_common.py b/nova/tests/api/openstack/test_common.py index 7e49e4ab8..68a5f0bf4 100644 --- a/nova/tests/api/openstack/test_common.py +++ b/nova/tests/api/openstack/test_common.py @@ -377,7 +377,6 @@ class MetadataXMLSerializationTest(test.TestCase): } output = serializer.serialize(fixture) - print output has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>") self.assertTrue(has_dec) @@ -390,7 +389,6 @@ class MetadataXMLSerializationTest(test.TestCase): }, } output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'metadata') metadata_dict = fixture['metadata'] @@ -409,7 +407,6 @@ class MetadataXMLSerializationTest(test.TestCase): }, } output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'metadata') metadata_dict = fixture['metadata'] @@ -428,7 +425,6 @@ class MetadataXMLSerializationTest(test.TestCase): }, } output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'metadata') metadata_dict = fixture['metadata'] @@ -447,7 +443,6 @@ class MetadataXMLSerializationTest(test.TestCase): }, } output = serializer.serialize(fixture) - print output root = etree.XML(output) meta_dict = fixture['meta'] (meta_key, meta_value) = meta_dict.items()[0] @@ -463,7 +458,6 @@ class MetadataXMLSerializationTest(test.TestCase): }, } output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'metadata') metadata_dict = fixture['metadata'] @@ -482,7 +476,6 @@ class MetadataXMLSerializationTest(test.TestCase): }, } output = serializer.serialize(fixture) - print output root = etree.XML(output) meta_dict = fixture['meta'] (meta_key, meta_value) = meta_dict.items()[0] @@ -499,7 +492,6 @@ class MetadataXMLSerializationTest(test.TestCase): }, } output = serializer.serialize(fixture) - print output root = etree.XML(output) xmlutil.validate_schema(root, 'metadata') metadata_dict = fixture['metadata'] diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index dc381d800..7b284779e 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -2722,8 +2722,11 @@ class ComputeTestCase(BaseTestCase): self.stubs.Set(nova.db, 'instance_fault_create', fake_db_fault_create) ctxt = context.get_admin_context() - compute_utils.add_instance_fault_from_exc(ctxt, instance, - NotImplementedError('test'), exc_info) + compute_utils.add_instance_fault_from_exc(ctxt, + self.compute.conductor_api, + instance, + NotImplementedError('test'), + exc_info) def test_add_instance_fault_with_remote_error(self): instance = self._create_fake_instance() @@ -2751,8 +2754,8 @@ class ComputeTestCase(BaseTestCase): self.stubs.Set(nova.db, 'instance_fault_create', fake_db_fault_create) ctxt = context.get_admin_context() - compute_utils.add_instance_fault_from_exc(ctxt, instance, exc, - exc_info) + compute_utils.add_instance_fault_from_exc(ctxt, + self.compute.conductor_api, instance, exc, exc_info) def test_add_instance_fault_user_error(self): instance = self._create_fake_instance() @@ -2779,8 +2782,8 @@ class ComputeTestCase(BaseTestCase): self.stubs.Set(nova.db, 'instance_fault_create', fake_db_fault_create) ctxt = context.get_admin_context() - compute_utils.add_instance_fault_from_exc(ctxt, instance, user_exc, - exc_info) + compute_utils.add_instance_fault_from_exc(ctxt, + self.compute.conductor_api, instance, user_exc, exc_info) def test_add_instance_fault_no_exc_info(self): instance = self._create_fake_instance() @@ -2798,8 +2801,10 @@ class ComputeTestCase(BaseTestCase): self.stubs.Set(nova.db, 'instance_fault_create', fake_db_fault_create) ctxt = context.get_admin_context() - compute_utils.add_instance_fault_from_exc(ctxt, instance, - NotImplementedError('test')) + compute_utils.add_instance_fault_from_exc(ctxt, + self.compute.conductor_api, + instance, + NotImplementedError('test')) def test_cleanup_running_deleted_instances(self): admin_context = context.get_admin_context() @@ -3780,6 +3785,28 @@ class ComputeAPITestCase(BaseTestCase): finally: db.instance_destroy(self.context, ref[0]['uuid']) + def test_create_saves_type_in_system_metadata(self): + instance_type = instance_types.get_default_instance_type() + (ref, resv_id) = self.compute_api.create( + self.context, + instance_type=instance_type, + image_href=None) + try: + sys_metadata = db.instance_system_metadata_get(self.context, + ref[0]['uuid']) + + instance_type_props = ['name', 'memory_mb', 'vcpus', 'root_gb', + 'ephemeral_gb', 'flavorid', 'swap', + 'rxtx_factor', 'vcpu_weight'] + for key in instance_type_props: + sys_meta_key = "instance_type_%s" % key + self.assertTrue(sys_meta_key in sys_metadata) + self.assertEqual(str(instance_type[key]), + str(sys_metadata[sys_meta_key])) + + finally: + db.instance_destroy(self.context, ref[0]['uuid']) + def test_create_instance_associates_security_groups(self): # Make sure create associates security groups. group = self._create_group() @@ -6752,6 +6779,7 @@ class ComputeRescheduleOrReraiseTestCase(BaseTestCase): exc_info = sys.exc_info() compute_utils.add_instance_fault_from_exc(self.context, + self.compute.conductor_api, self.instance, exc_info[0], exc_info=exc_info) self.compute._deallocate_network(self.context, self.instance).AndRaise(InnerTestingException("Error")) @@ -6802,6 +6830,7 @@ class ComputeRescheduleOrReraiseTestCase(BaseTestCase): except Exception: exc_info = sys.exc_info() compute_utils.add_instance_fault_from_exc(self.context, + self.compute.conductor_api, self.instance, exc_info[0], exc_info=exc_info) self.compute._deallocate_network(self.context, self.instance) @@ -6830,6 +6859,7 @@ class ComputeRescheduleOrReraiseTestCase(BaseTestCase): exc_info = sys.exc_info() compute_utils.add_instance_fault_from_exc(self.context, + self.compute.conductor_api, self.instance, exc_info[0], exc_info=exc_info) self.compute._deallocate_network(self.context, self.instance) diff --git a/nova/tests/conductor/test_conductor.py b/nova/tests/conductor/test_conductor.py index 30d176bbd..c46663e50 100644 --- a/nova/tests/conductor/test_conductor.py +++ b/nova/tests/conductor/test_conductor.py @@ -426,6 +426,15 @@ class _BaseTestCase(object): 'fake-values', False) self.assertEqual(result, 'fake-result') + def test_instance_fault_create(self): + self.mox.StubOutWithMock(db, 'instance_fault_create') + db.instance_fault_create(self.context, 'fake-values').AndReturn( + 'fake-result') + self.mox.ReplayAll() + result = self.conductor.instance_fault_create(self.context, + 'fake-values') + self.assertEqual(result, 'fake-result') + class ConductorTestCase(_BaseTestCase, test.TestCase): """Conductor Manager Tests.""" diff --git a/nova/tests/fake_policy.py b/nova/tests/fake_policy.py index dbf620196..ead43adea 100644 --- a/nova/tests/fake_policy.py +++ b/nova/tests/fake_policy.py @@ -157,6 +157,10 @@ policy_data = """ "compute_extension:virtual_interfaces": "", "compute_extension:virtual_storage_arrays": "", "compute_extension:volumes": "", + "compute_extension:volume_attachments:index": "", + "compute_extension:volume_attachments:show": "", + "compute_extension:volume_attachments:create": "", + "compute_extension:volume_attachments:delete": "", "compute_extension:volumetypes": "", "compute_extension:zones": "", "compute_extension:availability_zone:list": "", diff --git a/nova/tests/fake_volume.py b/nova/tests/fake_volume.py index f2aa3ea91..c7430ee6d 100644 --- a/nova/tests/fake_volume.py +++ b/nova/tests/fake_volume.py @@ -136,7 +136,6 @@ class API(object): def create_with_kwargs(self, context, **kwargs): volume_id = kwargs.get('volume_id', None) - print volume_id v = fake_volume(kwargs['size'], kwargs['name'], kwargs['description'], @@ -145,7 +144,6 @@ class API(object): None, None, None) - print v.vol['id'] if kwargs.get('status', None) is not None: v.vol['status'] = kwargs['status'] if kwargs['host'] is not None: diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py index 9dd9e5121..fb26fa4f1 100644 --- a/nova/tests/image/test_glance.py +++ b/nova/tests/image/test_glance.py @@ -339,7 +339,6 @@ class TestGlanceImageService(test.TestCase): def test_update(self): fixture = self._make_fixture(name='test image') image = self.service.create(self.context, fixture) - print image image_id = image['id'] fixture['name'] = 'new image name' self.service.update(self.context, image_id, fixture) diff --git a/nova/tests/integrated/test_multiprocess_api.py b/nova/tests/integrated/test_multiprocess_api.py index b2361b13c..ae4fcc32f 100644 --- a/nova/tests/integrated/test_multiprocess_api.py +++ b/nova/tests/integrated/test_multiprocess_api.py @@ -63,7 +63,7 @@ class MultiprocessWSGITest(integrated_helpers._IntegratedTestBase): try: traceback.print_exc() except BaseException: - print "Couldn't print traceback" + LOG.error("Couldn't print traceback") status = 2 # Really exit diff --git a/nova/tests/test_bdm.py b/nova/tests/test_bdm.py index 4d62d6bbf..43ca4d7b0 100644 --- a/nova/tests/test_bdm.py +++ b/nova/tests/test_bdm.py @@ -246,6 +246,5 @@ class BlockDeviceMappingEc2CloudTestCase(test.TestCase): result = {} cloud._format_mappings(properties, result) - print result self.assertEqual(result['blockDeviceMapping'].sort(), expected_result['blockDeviceMapping'].sort()) diff --git a/nova/tests/test_imagecache.py b/nova/tests/test_imagecache.py index 8142312b9..611519514 100644 --- a/nova/tests/test_imagecache.py +++ b/nova/tests/test_imagecache.py @@ -331,7 +331,6 @@ class ImageCacheManagerTestCase(test.TestCase): base_file1 = os.path.join(base_dir, fingerprint) base_file2 = os.path.join(base_dir, fingerprint + '_sm') base_file3 = os.path.join(base_dir, fingerprint + '_10737418240') - print res self.assertTrue(res == [(base_file1, False, False), (base_file2, True, False), (base_file3, False, True)]) diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index f96536893..5a90f3348 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -3833,7 +3833,6 @@ class IptablesFirewallTestCase(test.TestCase): if '*filter' in lines: self.out6_rules = lines return '', '' - print cmd, kwargs network_model = _fake_network_info(self.stubs, 1, spectacular=True) diff --git a/nova/tests/test_migrations.py b/nova/tests/test_migrations.py index 3b67e6439..8c18d5511 100644 --- a/nova/tests/test_migrations.py +++ b/nova/tests/test_migrations.py @@ -24,6 +24,7 @@ properly both upgrading and downgrading, and that no data loss occurs if possible. """ +import collections import commands import ConfigParser import os @@ -452,3 +453,69 @@ class TestMigrations(test.TestCase): self.assertEqual("", volume.deleted) volume = volumes.select(volumes.c.id == "second").execute().first() self.assertEqual(volume.id, volume.deleted) + + # migration 153, copy flavor information into system_metadata + def _prerun_153(self, engine): + fake_types = [ + dict(id=10, name='type1', memory_mb=128, vcpus=1, + root_gb=10, ephemeral_gb=0, flavorid="1", swap=0, + rxtx_factor=1.0, vcpu_weight=1, disabled=False, + is_public=True), + dict(id=11, name='type2', memory_mb=512, vcpus=1, + root_gb=10, ephemeral_gb=5, flavorid="2", swap=0, + rxtx_factor=1.5, vcpu_weight=2, disabled=False, + is_public=True), + dict(id=12, name='type3', memory_mb=128, vcpus=1, + root_gb=10, ephemeral_gb=0, flavorid="3", swap=0, + rxtx_factor=1.0, vcpu_weight=1, disabled=False, + is_public=False), + dict(id=13, name='type4', memory_mb=128, vcpus=1, + root_gb=10, ephemeral_gb=0, flavorid="4", swap=0, + rxtx_factor=1.0, vcpu_weight=1, disabled=True, + is_public=True), + dict(id=14, name='type5', memory_mb=128, vcpus=1, + root_gb=10, ephemeral_gb=0, flavorid="5", swap=0, + rxtx_factor=1.0, vcpu_weight=1, disabled=True, + is_public=False), + ] + + fake_instances = [ + dict(uuid='m153-uuid1', instance_type_id=10), + dict(uuid='m153-uuid2', instance_type_id=11), + dict(uuid='m153-uuid3', instance_type_id=12), + dict(uuid='m153-uuid4', instance_type_id=13), + # NOTE(danms): no use of type5 + ] + + instances = get_table(engine, 'instances') + instance_types = get_table(engine, 'instance_types') + engine.execute(instance_types.insert(), fake_types) + engine.execute(instances.insert(), fake_instances) + + return fake_types, fake_instances + + def _check_153(self, engine, data): + fake_types, fake_instances = data + # NOTE(danms): Fetch all the tables and data from scratch after change + instances = get_table(engine, 'instances') + instance_types = get_table(engine, 'instance_types') + sys_meta = get_table(engine, 'instance_system_metadata') + + # Collect all system metadata, indexed by instance_uuid + metadata = collections.defaultdict(dict) + for values in sys_meta.select().execute(): + metadata[values['instance_uuid']][values['key']] = values['value'] + + # Taken from nova/compute/api.py + instance_type_props = ['id', 'name', 'memory_mb', 'vcpus', + 'root_gb', 'ephemeral_gb', 'flavorid', + 'swap', 'rxtx_factor', 'vcpu_weight'] + + for instance in fake_instances: + inst_sys_meta = metadata[instance['uuid']] + inst_type = fake_types[instance['instance_type_id'] - 10] + for prop in instance_type_props: + prop_name = 'instance_type_%s' % prop + self.assertIn(prop_name, inst_sys_meta) + self.assertEqual(str(inst_sys_meta[prop_name]), + str(inst_type[prop])) diff --git a/nova/tests/test_notifications.py b/nova/tests/test_notifications.py index a300028a0..aec6c8f67 100644 --- a/nova/tests/test_notifications.py +++ b/nova/tests/test_notifications.py @@ -187,8 +187,6 @@ class NotificationsTestCase(test.TestCase): params = {"task_state": task_states.SPAWNING} (old_ref, new_ref) = db.instance_update_and_get_original(self.context, self.instance['uuid'], params) - print old_ref["task_state"] - print new_ref["task_state"] notifications.send_update(self.context, old_ref, new_ref) self.assertEquals(1, len(test_notifier.NOTIFICATIONS)) diff --git a/nova/tests/test_virt_disk_vfs_localfs.py b/nova/tests/test_virt_disk_vfs_localfs.py index 806ed01d8..af4571dd2 100644 --- a/nova/tests/test_virt_disk_vfs_localfs.py +++ b/nova/tests/test_virt_disk_vfs_localfs.py @@ -104,7 +104,6 @@ def fake_execute(*args, **kwargs): else: path = args[1] append = False - print str(files) if not path in files: files[path] = { "content": "Hello World", diff --git a/smoketests/base.py b/smoketests/base.py index 7c7d19838..c90da102c 100644 --- a/smoketests/base.py +++ b/smoketests/base.py @@ -169,7 +169,6 @@ class SmokeTestCase(unittest.TestCase): cmd += ' --kernel true' status, output = commands.getstatusoutput(cmd) if status != 0: - print '%s -> \n %s' % (cmd, output) raise Exception(output) return True @@ -178,7 +177,6 @@ class SmokeTestCase(unittest.TestCase): cmd += '%s -m %s/%s.manifest.xml' % (bucket_name, tempdir, image) status, output = commands.getstatusoutput(cmd) if status != 0: - print '%s -> \n %s' % (cmd, output) raise Exception(output) return True @@ -186,7 +184,6 @@ class SmokeTestCase(unittest.TestCase): cmd = 'euca-delete-bundle --clear -b %s' % (bucket_name) status, output = commands.getstatusoutput(cmd) if status != 0: - print '%s -> \n%s' % (cmd, output) raise Exception(output) return True diff --git a/smoketests/public_network_smoketests.py b/smoketests/public_network_smoketests.py index 4fb843e0f..f20b0923e 100644 --- a/smoketests/public_network_smoketests.py +++ b/smoketests/public_network_smoketests.py @@ -97,7 +97,6 @@ class InstanceTestsFromPublic(base.UserSmokeTestCase): self.data['ip_v6'], TEST_KEY) conn.close() except Exception as ex: - print ex time.sleep(1) else: break |