summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--HACKING.rst4
-rw-r--r--README.rst2
-rwxr-xr-xbin/nova-all2
-rwxr-xr-xbin/nova-baremetal-deploy-helper1
-rwxr-xr-xbin/nova-cert2
-rwxr-xr-xbin/nova-clear-rabbit-queues2
-rwxr-xr-xbin/nova-console2
-rwxr-xr-xbin/nova-consoleauth2
-rwxr-xr-xbin/nova-dhcpbridge4
-rwxr-xr-xbin/nova-manage15
-rwxr-xr-xbin/nova-novncproxy2
-rwxr-xr-xbin/nova-rootwrap2
-rwxr-xr-xbin/nova-rpc-zmq-receiver4
-rwxr-xr-xbin/nova-spicehtml5proxy2
-rwxr-xr-xbin/nova-xvpvncproxy2
-rw-r--r--doc/api_samples/os-volumes/attach-volume-to-server-req.json6
-rw-r--r--doc/api_samples/os-volumes/attach-volume-to-server-req.xml2
-rw-r--r--doc/api_samples/os-volumes/attach-volume-to-server-resp.json8
-rw-r--r--doc/api_samples/os-volumes/attach-volume-to-server-resp.xml2
-rw-r--r--doc/api_samples/os-volumes/list-volume-attachments-resp.json16
-rw-r--r--doc/api_samples/os-volumes/list-volume-attachments-resp.xml5
-rw-r--r--doc/api_samples/os-volumes/os-volumes-detail-resp.json24
-rw-r--r--doc/api_samples/os-volumes/os-volumes-detail-resp.xml9
-rw-r--r--doc/api_samples/os-volumes/os-volumes-get-resp.json22
-rw-r--r--doc/api_samples/os-volumes/os-volumes-get-resp.xml7
-rw-r--r--doc/api_samples/os-volumes/os-volumes-index-resp.json24
-rw-r--r--doc/api_samples/os-volumes/os-volumes-index-resp.xml9
-rw-r--r--doc/api_samples/os-volumes/os-volumes-post-req.json9
-rw-r--r--doc/api_samples/os-volumes/os-volumes-post-req.xml3
-rw-r--r--doc/api_samples/os-volumes/os-volumes-post-resp.json22
-rw-r--r--doc/api_samples/os-volumes/os-volumes-post-resp.xml7
-rw-r--r--doc/api_samples/os-volumes/server-post-req.json16
-rw-r--r--doc/api_samples/os-volumes/server-post-req.xml19
-rw-r--r--doc/api_samples/os-volumes/server-post-resp.json16
-rw-r--r--doc/api_samples/os-volumes/server-post-resp.xml6
-rw-r--r--doc/api_samples/os-volumes/snapshot-create-req.json8
-rw-r--r--doc/api_samples/os-volumes/snapshot-create-req.xml7
-rw-r--r--doc/api_samples/os-volumes/snapshot-create-resp.json32
-rw-r--r--doc/api_samples/os-volumes/snapshot-create-resp.xml2
-rw-r--r--doc/api_samples/os-volumes/snapshots-detail-resp.json31
-rw-r--r--doc/api_samples/os-volumes/snapshots-detail-resp.xml6
-rw-r--r--doc/api_samples/os-volumes/snapshots-list-resp.json31
-rw-r--r--doc/api_samples/os-volumes/snapshots-list-resp.xml6
-rw-r--r--doc/api_samples/os-volumes/snapshots-show-resp.json11
-rw-r--r--doc/api_samples/os-volumes/snapshots-show-resp.xml2
-rw-r--r--doc/api_samples/os-volumes/volume-attachment-detail-resp.json8
-rw-r--r--doc/api_samples/os-volumes/volume-attachment-detail-resp.xml2
-rw-r--r--doc/source/conf.py2
-rw-r--r--doc/source/devref/addmethod.openstackapi.rst2
-rw-r--r--doc/source/devref/aggregates.rst2
-rw-r--r--doc/source/man/nova-all.rst2
-rw-r--r--doc/source/man/nova-api-ec2.rst2
-rw-r--r--doc/source/man/nova-api-metadata.rst2
-rw-r--r--doc/source/man/nova-api-os-compute.rst2
-rw-r--r--doc/source/man/nova-api.rst2
-rw-r--r--doc/source/man/nova-baremetal-deploy-helper.rst2
-rw-r--r--doc/source/man/nova-baremetal-manage.rst2
-rw-r--r--doc/source/man/nova-cert.rst2
-rw-r--r--doc/source/man/nova-compute.rst2
-rw-r--r--doc/source/man/nova-conductor.rst2
-rw-r--r--doc/source/man/nova-console.rst2
-rw-r--r--doc/source/man/nova-consoleauth.rst2
-rw-r--r--doc/source/man/nova-dhcpbridge.rst2
-rw-r--r--doc/source/man/nova-manage.rst2
-rw-r--r--doc/source/man/nova-network.rst2
-rw-r--r--doc/source/man/nova-novncproxy.rst2
-rw-r--r--doc/source/man/nova-objectstore.rst2
-rw-r--r--doc/source/man/nova-rootwrap.rst2
-rw-r--r--doc/source/man/nova-rpc-zmq-receiver.rst2
-rw-r--r--doc/source/man/nova-scheduler.rst2
-rw-r--r--doc/source/man/nova-spicehtml5proxy.rst2
-rw-r--r--doc/source/man/nova-xvpvncproxy.rst2
-rw-r--r--etc/nova/nova.conf.sample275
-rw-r--r--nova/api/auth.py2
-rw-r--r--nova/api/ec2/__init__.py4
-rw-r--r--nova/api/ec2/cloud.py22
-rw-r--r--nova/api/metadata/__init__.py2
-rw-r--r--nova/api/metadata/handler.py2
-rw-r--r--nova/api/openstack/auth.py2
-rw-r--r--nova/api/openstack/common.py2
-rw-r--r--nova/api/openstack/compute/consoles.py2
-rw-r--r--nova/api/openstack/compute/contrib/admin_actions.py2
-rw-r--r--nova/api/openstack/compute/contrib/agents.py3
-rw-r--r--nova/api/openstack/compute/contrib/availability_zone.py2
-rw-r--r--nova/api/openstack/compute/contrib/cells.py2
-rw-r--r--nova/api/openstack/compute/contrib/certificates.py2
-rw-r--r--nova/api/openstack/compute/contrib/cloudpipe.py2
-rw-r--r--nova/api/openstack/compute/contrib/cloudpipe_update.py3
-rw-r--r--nova/api/openstack/compute/contrib/config_drive.py2
-rw-r--r--nova/api/openstack/compute/contrib/console_output.py2
-rw-r--r--nova/api/openstack/compute/contrib/consoles.py2
-rw-r--r--nova/api/openstack/compute/contrib/coverage_ext.py57
-rw-r--r--nova/api/openstack/compute/contrib/createserverext.py2
-rw-r--r--nova/api/openstack/compute/contrib/deferred_delete.py2
-rw-r--r--nova/api/openstack/compute/contrib/disk_config.py2
-rw-r--r--nova/api/openstack/compute/contrib/evacuate.py2
-rw-r--r--nova/api/openstack/compute/contrib/extended_availability_zone.py2
-rw-r--r--nova/api/openstack/compute/contrib/extended_server_attributes.py2
-rw-r--r--nova/api/openstack/compute/contrib/extended_status.py2
-rw-r--r--nova/api/openstack/compute/contrib/fixed_ips.py3
-rw-r--r--nova/api/openstack/compute/contrib/flavor_access.py2
-rw-r--r--nova/api/openstack/compute/contrib/flavorextradata.py2
-rw-r--r--nova/api/openstack/compute/contrib/floating_ip_dns.py11
-rw-r--r--nova/api/openstack/compute/contrib/floating_ips.py6
-rw-r--r--nova/api/openstack/compute/contrib/floating_ips_bulk.py3
-rw-r--r--nova/api/openstack/compute/contrib/fping.py2
-rw-r--r--nova/api/openstack/compute/contrib/hide_server_addresses.py2
-rw-r--r--nova/api/openstack/compute/contrib/hosts.py2
-rw-r--r--nova/api/openstack/compute/contrib/hypervisors.py2
-rw-r--r--nova/api/openstack/compute/contrib/instance_usage_audit_log.py2
-rw-r--r--nova/api/openstack/compute/contrib/keypairs.py7
-rw-r--r--nova/api/openstack/compute/contrib/multinic.py2
-rw-r--r--nova/api/openstack/compute/contrib/multiple_create.py2
-rw-r--r--nova/api/openstack/compute/contrib/os_networks.py2
-rw-r--r--nova/api/openstack/compute/contrib/os_tenant_networks.py2
-rw-r--r--nova/api/openstack/compute/contrib/quota_classes.py2
-rw-r--r--nova/api/openstack/compute/contrib/quotas.py2
-rw-r--r--nova/api/openstack/compute/contrib/rescue.py2
-rw-r--r--nova/api/openstack/compute/contrib/scheduler_hints.py2
-rw-r--r--nova/api/openstack/compute/contrib/security_groups.py10
-rw-r--r--nova/api/openstack/compute/contrib/server_diagnostics.py2
-rw-r--r--nova/api/openstack/compute/contrib/services.py3
-rw-r--r--nova/api/openstack/compute/contrib/simple_tenant_usage.py2
-rw-r--r--nova/api/openstack/compute/contrib/used_limits.py2
-rw-r--r--nova/api/openstack/compute/contrib/user_data.py2
-rw-r--r--nova/api/openstack/compute/extensions.py2
-rw-r--r--nova/api/openstack/compute/flavors.py2
-rw-r--r--nova/api/openstack/compute/image_metadata.py2
-rw-r--r--nova/api/openstack/compute/images.py2
-rw-r--r--nova/api/openstack/compute/ips.py2
-rw-r--r--nova/api/openstack/compute/limits.py2
-rw-r--r--nova/api/openstack/compute/server_metadata.py2
-rw-r--r--nova/api/openstack/compute/servers.py15
-rw-r--r--nova/api/openstack/compute/versions.py2
-rw-r--r--nova/api/openstack/compute/views/addresses.py2
-rw-r--r--nova/api/openstack/compute/views/flavors.py2
-rw-r--r--nova/api/openstack/compute/views/images.py2
-rw-r--r--nova/api/openstack/compute/views/limits.py2
-rw-r--r--nova/api/openstack/compute/views/servers.py2
-rw-r--r--nova/api/openstack/compute/views/versions.py2
-rw-r--r--nova/api/openstack/extensions.py2
-rw-r--r--nova/api/openstack/urlmap.py2
-rw-r--r--nova/api/openstack/wsgi.py16
-rw-r--r--nova/api/openstack/xmlutil.py2
-rw-r--r--nova/api/sizelimit.py2
-rw-r--r--nova/api/validator.py9
-rw-r--r--nova/availability_zones.py2
-rw-r--r--nova/cells/messaging.py9
-rw-r--r--nova/cert/__init__.py2
-rw-r--r--nova/cert/manager.py2
-rw-r--r--nova/compute/api.py116
-rw-r--r--nova/compute/cells_api.py12
-rw-r--r--nova/compute/claims.py2
-rw-r--r--nova/compute/instance_actions.py2
-rw-r--r--nova/compute/instance_types.py4
-rwxr-xr-xnova/compute/manager.py255
-rw-r--r--nova/compute/resource_tracker.py25
-rw-r--r--nova/compute/rpcapi.py6
-rw-r--r--nova/compute/stats.py2
-rw-r--r--nova/compute/task_states.py2
-rw-r--r--nova/compute/utils.py2
-rw-r--r--nova/compute/vm_mode.py2
-rw-r--r--nova/compute/vm_states.py2
-rw-r--r--nova/conductor/api.py8
-rw-r--r--nova/conductor/manager.py10
-rw-r--r--nova/conductor/rpcapi.py6
-rw-r--r--nova/console/api.py2
-rw-r--r--nova/console/fake.py2
-rw-r--r--nova/console/manager.py2
-rw-r--r--nova/console/vmrc.py2
-rw-r--r--nova/console/vmrc_manager.py2
-rw-r--r--nova/console/websocketproxy.py2
-rw-r--r--nova/console/xvp.py7
-rw-r--r--nova/consoleauth/__init__.py2
-rw-r--r--nova/consoleauth/manager.py4
-rw-r--r--nova/context.py2
-rw-r--r--nova/crypto.py5
-rw-r--r--nova/db/api.py44
-rw-r--r--nova/db/sqlalchemy/api.py189
-rw-r--r--nova/db/sqlalchemy/migrate_repo/__init__.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/manage.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/133_folsom.py4
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/134_add_counters_to_bw_usage_cache.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/135_add_node_to_instances.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/136_add_index_to_instances.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/137_add_indexes_to_migrations.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/138_drop_server_name_from_instances.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/139_add_indexes_to_fixed_ips.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/145_add_volume_usage_cache.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/146_aggregate_zones.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/147_no_service_zones.py10
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/148_add_instance_actions.py28
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/149_inet_datatype_for_postgres.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/150_add_host_to_instance_faults.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/159_revert_ip_column_length.py63
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/159_sqlite_downgrade.sql81
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/159_sqlite_upgrade.sql79
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/160_fix_system_metadata_deleted.py33
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/__init__.py2
-rw-r--r--nova/db/sqlalchemy/models.py29
-rw-r--r--nova/db/sqlalchemy/types.py2
-rw-r--r--nova/exception.py25
-rw-r--r--nova/filters.py2
-rw-r--r--nova/hooks.py2
-rw-r--r--nova/image/glance.py2
-rw-r--r--nova/ipv6/__init__.py2
-rw-r--r--nova/ipv6/api.py2
-rw-r--r--nova/loadables.py2
-rw-r--r--nova/locale/nova.pot1649
-rw-r--r--nova/network/api_deprecated.py151
-rw-r--r--nova/network/linux_net.py40
-rw-r--r--nova/network/model.py2
-rw-r--r--nova/network/quantumv2/__init__.py2
-rw-r--r--nova/network/quantumv2/api.py24
-rw-r--r--nova/network/security_group/quantum_driver.py31
-rw-r--r--nova/network/security_group/security_group_base.py50
-rw-r--r--nova/notifications.py49
-rw-r--r--nova/objectstore/s3server.py2
-rw-r--r--nova/openstack/common/context.py2
-rw-r--r--nova/openstack/common/db/exception.py45
-rw-r--r--nova/openstack/common/db/sqlalchemy/session.py72
-rw-r--r--nova/openstack/common/db/sqlalchemy/utils.py2
-rw-r--r--nova/openstack/common/eventlet_backdoor.py2
-rw-r--r--nova/openstack/common/excutils.py2
-rw-r--r--nova/openstack/common/fileutils.py2
-rw-r--r--nova/openstack/common/importutils.py2
-rw-r--r--nova/openstack/common/jsonutils.py6
-rw-r--r--nova/openstack/common/local.py2
-rw-r--r--nova/openstack/common/lockutils.py2
-rw-r--r--nova/openstack/common/log.py11
-rw-r--r--nova/openstack/common/memorycache.py (renamed from nova/common/memorycache.py)18
-rw-r--r--nova/openstack/common/network_utils.py2
-rw-r--r--nova/openstack/common/notifier/__init__.py2
-rw-r--r--nova/openstack/common/notifier/api.py2
-rw-r--r--nova/openstack/common/notifier/log_notifier.py2
-rw-r--r--nova/openstack/common/notifier/no_op_notifier.py2
-rw-r--r--nova/openstack/common/notifier/rpc_notifier.py2
-rw-r--r--nova/openstack/common/notifier/rpc_notifier2.py2
-rw-r--r--nova/openstack/common/notifier/test_notifier.py2
-rw-r--r--nova/openstack/common/plugin/__init__.py2
-rw-r--r--nova/openstack/common/plugin/callbackplugin.py2
-rw-r--r--nova/openstack/common/plugin/plugin.py2
-rw-r--r--nova/openstack/common/plugin/pluginmanager.py2
-rw-r--r--nova/openstack/common/policy.py2
-rw-r--r--nova/openstack/common/processutils.py2
-rw-r--r--nova/openstack/common/rootwrap/__init__.py2
-rw-r--r--nova/openstack/common/rootwrap/filters.py2
-rw-r--r--nova/openstack/common/rootwrap/wrapper.py2
-rw-r--r--nova/openstack/common/rpc/impl_fake.py2
-rw-r--r--nova/openstack/common/rpc/impl_kombu.py2
-rw-r--r--nova/openstack/common/rpc/impl_qpid.py2
-rw-r--r--nova/openstack/common/setup.py2
-rw-r--r--nova/openstack/common/version.py2
-rw-r--r--nova/policy.py2
-rw-r--r--nova/safe_utils.py55
-rw-r--r--nova/scheduler/__init__.py2
-rw-r--r--nova/scheduler/baremetal_host_manager.py2
-rw-r--r--nova/scheduler/chance.py2
-rw-r--r--nova/scheduler/driver.py6
-rw-r--r--nova/scheduler/filter_scheduler.py2
-rw-r--r--nova/scheduler/filters/__init__.py2
-rw-r--r--nova/scheduler/filters/affinity_filter.py2
-rw-r--r--nova/scheduler/filters/aggregate_instance_extra_specs.py2
-rw-r--r--nova/scheduler/filters/aggregate_multitenancy_isolation.py2
-rw-r--r--nova/scheduler/filters/all_hosts_filter.py2
-rw-r--r--nova/scheduler/filters/availability_zone_filter.py2
-rw-r--r--nova/scheduler/filters/compute_capabilities_filter.py2
-rw-r--r--nova/scheduler/filters/compute_filter.py2
-rw-r--r--nova/scheduler/filters/core_filter.py2
-rw-r--r--nova/scheduler/filters/disk_filter.py2
-rw-r--r--nova/scheduler/filters/extra_specs_ops.py2
-rw-r--r--nova/scheduler/filters/image_props_filter.py2
-rw-r--r--nova/scheduler/filters/io_ops_filter.py2
-rw-r--r--nova/scheduler/filters/isolated_hosts_filter.py2
-rw-r--r--nova/scheduler/filters/json_filter.py2
-rw-r--r--nova/scheduler/filters/num_instances_filter.py2
-rw-r--r--nova/scheduler/filters/ram_filter.py2
-rw-r--r--nova/scheduler/filters/retry_filter.py2
-rw-r--r--nova/scheduler/filters/trusted_filter.py2
-rw-r--r--nova/scheduler/host_manager.py2
-rw-r--r--nova/scheduler/manager.py2
-rw-r--r--nova/scheduler/multi.py2
-rw-r--r--nova/scheduler/scheduler_options.py9
-rw-r--r--nova/scheduler/weights/__init__.py2
-rw-r--r--nova/scheduler/weights/least_cost.py2
-rw-r--r--nova/scheduler/weights/ram.py2
-rw-r--r--nova/servicegroup/__init__.py2
-rw-r--r--nova/servicegroup/api.py3
-rw-r--r--nova/servicegroup/drivers/db.py3
-rw-r--r--nova/servicegroup/drivers/mc.py7
-rw-r--r--nova/servicegroup/drivers/zk.py25
-rw-r--r--nova/tests/api/__init__.py2
-rw-r--r--nova/tests/api/ec2/__init__.py2
-rw-r--r--nova/tests/api/ec2/test_cloud.py136
-rw-r--r--nova/tests/api/openstack/__init__.py2
-rw-r--r--nova/tests/api/openstack/common.py2
-rw-r--r--nova/tests/api/openstack/compute/__init__.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/__init__.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_admin_actions.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_admin_actions_with_cells.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_agents.py6
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_availability_zone.py3
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_cells.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_certificates.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_cloudpipe.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_cloudpipe_update.py3
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_config_drive.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_consoles.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_coverage_ext.py28
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_createserverext.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_deferred_delete.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_disk_config.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_evacuate.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_extended_availability_zone.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_extended_status.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_fixed_ips.py6
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_flavor_access.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_flavorextradata.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_floating_ip_bulk.py6
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_floating_ips.py15
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_fping.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_hide_server_addresses.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_hosts.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_hypervisors.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_instance_usage_audit_log.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_keypairs.py5
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_multinic_xs.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_networks.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py54
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_quota_classes.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_quotas.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_rescue.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_scheduler_hints.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_security_groups.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_services.py6
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_used_limits.py2
-rw-r--r--nova/tests/api/openstack/compute/extensions/__init__.py2
-rw-r--r--nova/tests/api/openstack/compute/extensions/foxinsocks.py2
-rw-r--r--nova/tests/api/openstack/compute/test_api.py2
-rw-r--r--nova/tests/api/openstack/compute/test_auth.py2
-rw-r--r--nova/tests/api/openstack/compute/test_consoles.py2
-rw-r--r--nova/tests/api/openstack/compute/test_extensions.py2
-rw-r--r--nova/tests/api/openstack/compute/test_flavors.py2
-rw-r--r--nova/tests/api/openstack/compute/test_image_metadata.py2
-rw-r--r--nova/tests/api/openstack/compute/test_images.py2
-rw-r--r--nova/tests/api/openstack/compute/test_limits.py2
-rw-r--r--nova/tests/api/openstack/compute/test_server_actions.py35
-rw-r--r--nova/tests/api/openstack/compute/test_server_metadata.py2
-rw-r--r--nova/tests/api/openstack/compute/test_servers.py82
-rw-r--r--nova/tests/api/openstack/compute/test_urlmap.py2
-rw-r--r--nova/tests/api/openstack/compute/test_versions.py2
-rw-r--r--nova/tests/api/openstack/fakes.py4
-rw-r--r--nova/tests/api/openstack/test_common.py2
-rw-r--r--nova/tests/api/openstack/test_faults.py2
-rw-r--r--nova/tests/api/openstack/test_xmlutil.py2
-rw-r--r--nova/tests/api/test_auth.py2
-rw-r--r--nova/tests/api/test_sizelimit.py2
-rw-r--r--nova/tests/api/test_validator.py8
-rw-r--r--nova/tests/api/test_wsgi.py2
-rw-r--r--nova/tests/baremetal/db/test_bm_interface.py4
-rw-r--r--nova/tests/baremetal/db/test_bm_pxe_ip.py6
-rw-r--r--nova/tests/baremetal/test_nova_baremetal_deploy_helper.py2
-rw-r--r--nova/tests/baremetal/test_nova_baremetal_manage.py2
-rw-r--r--nova/tests/baremetal/test_pxe.py74
-rw-r--r--nova/tests/baremetal/test_virtual_power_driver.py21
-rw-r--r--nova/tests/cert/__init__.py2
-rw-r--r--nova/tests/compute/__init__.py2
-rw-r--r--nova/tests/compute/fake_resource_tracker.py2
-rw-r--r--nova/tests/compute/test_claims.py2
-rw-r--r--nova/tests/compute/test_compute.py243
-rw-r--r--nova/tests/compute/test_compute_utils.py2
-rw-r--r--nova/tests/compute/test_host_api.py2
-rw-r--r--nova/tests/compute/test_multiple_nodes.py24
-rw-r--r--nova/tests/compute/test_resource_tracker.py31
-rw-r--r--nova/tests/compute/test_rpcapi.py3
-rw-r--r--nova/tests/compute/test_stats.py2
-rw-r--r--nova/tests/compute/test_virtapi.py4
-rw-r--r--nova/tests/conductor/test_conductor.py8
-rw-r--r--nova/tests/console/__init__.py2
-rw-r--r--nova/tests/console/test_console.py2
-rw-r--r--nova/tests/consoleauth/__init__.py2
-rw-r--r--nova/tests/consoleauth/test_consoleauth.py2
-rw-r--r--nova/tests/db/fakes.py17
-rw-r--r--nova/tests/fake_hosts.py2
-rw-r--r--nova/tests/fake_instance_actions.py2
-rw-r--r--nova/tests/fake_libvirt_utils.py2
-rw-r--r--nova/tests/fake_loadables/__init__.py2
-rw-r--r--nova/tests/fake_loadables/fake_loadable1.py2
-rw-r--r--nova/tests/fake_loadables/fake_loadable2.py2
-rw-r--r--nova/tests/fake_network_cache_model.py2
-rw-r--r--nova/tests/fake_policy.py2
-rw-r--r--nova/tests/fakelibvirt.py3
-rw-r--r--nova/tests/hyperv/db_fakes.py7
-rw-r--r--nova/tests/image/__init__.py2
-rw-r--r--nova/tests/image/fake.py2
-rw-r--r--nova/tests/image/test_fake.py2
-rw-r--r--nova/tests/image/test_glance.py2
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-req.json.tpl6
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-req.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-resp.json.tpl8
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-resp.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/list-volume-attachments-resp.json.tpl16
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/list-volume-attachments-resp.xml.tpl5
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-detail-resp.json.tpl24
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-detail-resp.xml.tpl9
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-get-resp.json.tpl22
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-get-resp.xml.tpl7
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-index-resp.json.tpl24
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-index-resp.xml.tpl9
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-post-req.json.tpl9
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-post-req.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-post-resp.json.tpl21
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/os-volumes-post-resp.xml.tpl7
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/server-post-req.json.tpl16
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/server-post-req.xml.tpl19
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/server-post-resp.json.tpl16
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/server-post-resp.xml.tpl6
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshot-create-req.json.tpl8
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshot-create-req.xml.tpl7
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshot-create-resp.json.tpl32
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshot-create-resp.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshots-detail-resp.json.tpl31
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshots-detail-resp.xml.tpl6
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshots-list-resp.json.tpl31
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshots-list-resp.xml.tpl6
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshots-show-resp.json.tpl11
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/snapshots-show-resp.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/volume-attachment-detail-resp.json.tpl8
-rw-r--r--nova/tests/integrated/api_samples/os-volumes/volume-attachment-detail-resp.xml.tpl2
-rw-r--r--nova/tests/integrated/test_api_samples.py310
-rw-r--r--nova/tests/integrated/test_multiprocess_api.py2
-rw-r--r--nova/tests/integrated/test_servers.py4
-rw-r--r--nova/tests/monkey_patch_example/__init__.py2
-rw-r--r--nova/tests/monkey_patch_example/example_a.py2
-rw-r--r--nova/tests/monkey_patch_example/example_b.py2
-rw-r--r--nova/tests/network/__init__.py2
-rw-r--r--nova/tests/network/test_deprecated_api.py80
-rw-r--r--nova/tests/network/test_linux_net.py16
-rw-r--r--nova/tests/network/test_manager.py4
-rw-r--r--nova/tests/network/test_network_info.py2
-rw-r--r--nova/tests/network/test_quantumv2.py31
-rw-r--r--nova/tests/scheduler/__init__.py2
-rw-r--r--nova/tests/scheduler/fakes.py2
-rw-r--r--nova/tests/scheduler/test_chance_scheduler.py2
-rw-r--r--nova/tests/scheduler/test_filter_scheduler.py2
-rw-r--r--nova/tests/scheduler/test_host_filters.py2
-rw-r--r--nova/tests/scheduler/test_host_manager.py2
-rw-r--r--nova/tests/scheduler/test_least_cost.py2
-rw-r--r--nova/tests/scheduler/test_multi_scheduler.py2
-rw-r--r--nova/tests/scheduler/test_scheduler.py8
-rw-r--r--nova/tests/scheduler/test_scheduler_options.py2
-rw-r--r--nova/tests/scheduler/test_weights.py2
-rw-r--r--nova/tests/servicegroup/__init__.py2
-rw-r--r--nova/tests/servicegroup/test_db_servicegroup.py2
-rw-r--r--nova/tests/servicegroup/test_mc_servicegroup.py2
-rw-r--r--nova/tests/servicegroup/test_zk_driver.py4
-rw-r--r--nova/tests/test_cinder.py2
-rw-r--r--nova/tests/test_context.py2
-rw-r--r--nova/tests/test_crypto.py2
-rw-r--r--nova/tests/test_db_api.py79
-rw-r--r--nova/tests/test_driver.py2
-rw-r--r--nova/tests/test_exception.py7
-rw-r--r--nova/tests/test_fakelibvirt.py2
-rw-r--r--nova/tests/test_filters.py2
-rw-r--r--nova/tests/test_hooks.py2
-rw-r--r--nova/tests/test_hypervapi.py50
-rw-r--r--nova/tests/test_iptables_network.py37
-rw-r--r--nova/tests/test_ipv6.py2
-rw-r--r--nova/tests/test_libvirt.py58
-rw-r--r--nova/tests/test_libvirt_blockinfo.py10
-rw-r--r--nova/tests/test_libvirt_vif.py4
-rw-r--r--nova/tests/test_libvirt_volume.py2
-rw-r--r--nova/tests/test_loadables.py2
-rw-r--r--nova/tests/test_migrations.py263
-rw-r--r--nova/tests/test_misc.py2
-rw-r--r--nova/tests/test_notifications.py2
-rw-r--r--nova/tests/test_nova_manage.py12
-rw-r--r--nova/tests/test_periodic_tasks.py2
-rw-r--r--nova/tests/test_pipelib.py2
-rw-r--r--nova/tests/test_plugin_api_extensions.py2
-rw-r--r--nova/tests/test_powervm.py87
-rw-r--r--nova/tests/test_safeutils.py100
-rw-r--r--nova/tests/test_test_utils.py2
-rw-r--r--nova/tests/test_utils.py131
-rw-r--r--nova/tests/test_virt_disk_vfs_localfs.py4
-rw-r--r--nova/tests/test_virt_drivers.py5
-rw-r--r--nova/tests/test_vmwareapi.py2
-rw-r--r--nova/tests/test_vmwareapi_vmops.py2
-rw-r--r--nova/tests/test_xenapi.py95
-rw-r--r--nova/tests/utils.py2
-rw-r--r--nova/tests/virt/disk/test_api.py2
-rw-r--r--nova/tests/virt/xenapi/imageupload/test_glance.py5
-rw-r--r--nova/tests/virt/xenapi/test_vm_utils.py2
-rw-r--r--nova/tests/vmwareapi/__init__.py2
-rw-r--r--nova/tests/vmwareapi/db_fakes.py2
-rw-r--r--nova/tests/vmwareapi/stubs.py2
-rw-r--r--nova/tests/volume/__init__.py2
-rw-r--r--nova/utils.py59
-rw-r--r--nova/version.py2
-rw-r--r--nova/virt/baremetal/baremetal_states.py2
-rw-r--r--nova/virt/baremetal/base.py4
-rw-r--r--nova/virt/baremetal/db/sqlalchemy/api.py3
-rw-r--r--nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/001_init.py2
-rw-r--r--nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/004_add_instance_name_to_bm_nodes.py4
-rw-r--r--nova/virt/baremetal/db/sqlalchemy/session.py2
-rwxr-xr-xnova/virt/baremetal/driver.py12
-rw-r--r--nova/virt/baremetal/pxe.py44
-rw-r--r--nova/virt/baremetal/virtual_power_driver.py19
-rw-r--r--nova/virt/disk/vfs/guestfs.py3
-rwxr-xr-xnova/virt/driver.py2
-rwxr-xr-xnova/virt/fake.py5
-rw-r--r--nova/virt/firewall.py16
-rwxr-xr-xnova/virt/hyperv/driver.py21
-rw-r--r--nova/virt/hyperv/imagecache.py75
-rw-r--r--nova/virt/hyperv/livemigrationops.py18
-rw-r--r--nova/virt/hyperv/migrationops.py29
-rw-r--r--nova/virt/hyperv/pathutils.py21
-rw-r--r--nova/virt/hyperv/vhdutils.py7
-rw-r--r--nova/virt/hyperv/vif.py7
-rw-r--r--nova/virt/hyperv/vmops.py86
-rw-r--r--nova/virt/hyperv/volumeops.py24
-rw-r--r--nova/virt/hyperv/volumeutils.py6
-rw-r--r--nova/virt/hyperv/volumeutilsv2.py6
-rw-r--r--nova/virt/libvirt/__init__.py2
-rw-r--r--nova/virt/libvirt/blockinfo.py2
-rwxr-xr-xnova/virt/libvirt/driver.py94
-rwxr-xr-xnova/virt/libvirt/utils.py2
-rw-r--r--nova/virt/libvirt/vif.py5
-rw-r--r--nova/virt/libvirt/volume.py2
-rw-r--r--nova/virt/powervm/__init__.py2
-rw-r--r--nova/virt/powervm/blockdev.py19
-rw-r--r--nova/virt/powervm/command.py2
-rw-r--r--nova/virt/powervm/common.py8
-rw-r--r--nova/virt/powervm/constants.py2
-rwxr-xr-xnova/virt/powervm/driver.py28
-rw-r--r--nova/virt/powervm/exception.py2
-rw-r--r--nova/virt/powervm/lpar.py2
-rw-r--r--nova/virt/powervm/operator.py9
-rw-r--r--nova/virt/virtapi.py7
-rw-r--r--nova/virt/vmwareapi/__init__.py2
-rwxr-xr-xnova/virt/vmwareapi/driver.py2
-rw-r--r--nova/virt/vmwareapi/error_util.py2
-rw-r--r--nova/virt/vmwareapi/fake.py2
-rw-r--r--nova/virt/vmwareapi/host.py4
-rw-r--r--nova/virt/vmwareapi/io_util.py2
-rw-r--r--nova/virt/vmwareapi/network_util.py2
-rw-r--r--nova/virt/vmwareapi/read_write_util.py2
-rw-r--r--nova/virt/vmwareapi/vif.py2
-rw-r--r--nova/virt/vmwareapi/vim.py2
-rw-r--r--nova/virt/vmwareapi/vim_util.py2
-rw-r--r--nova/virt/vmwareapi/vm_util.py2
-rw-r--r--nova/virt/vmwareapi/vmops.py2
-rw-r--r--nova/virt/vmwareapi/vmware_images.py2
-rw-r--r--nova/virt/xenapi/agent.py2
-rwxr-xr-xnova/virt/xenapi/driver.py2
-rw-r--r--nova/virt/xenapi/host.py2
-rw-r--r--nova/virt/xenapi/imageupload/glance.py59
-rw-r--r--nova/virt/xenapi/pool.py2
-rw-r--r--nova/virt/xenapi/pool_states.py2
-rw-r--r--nova/virt/xenapi/vif.py2
-rw-r--r--nova/virt/xenapi/vm_utils.py10
-rw-r--r--nova/virt/xenapi/vmops.py30
-rw-r--r--nova/virt/xenapi/volume_utils.py2
-rw-r--r--nova/virt/xenapi/volumeops.py2
-rw-r--r--nova/vnc/__init__.py2
-rw-r--r--nova/vnc/xvp_proxy.py2
-rw-r--r--nova/weights.py2
-rw-r--r--nova/wsgi.py9
-rw-r--r--openstack-common.conf2
-rwxr-xr-xplugins/xenserver/networking/etc/init.d/host-rules2
-rwxr-xr-xplugins/xenserver/networking/etc/init.d/openvswitch-nova2
-rw-r--r--plugins/xenserver/networking/etc/xensource/scripts/novalib.py2
-rwxr-xr-xplugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py2
-rwxr-xr-xplugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py2
-rwxr-xr-xplugins/xenserver/networking/etc/xensource/scripts/vif_rules.py2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/_bittorrent_seeder2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/agent2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/bandwidth2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/bittorrent2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/glance34
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/kernel2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/migration2
-rw-r--r--plugins/xenserver/xenapi/etc/xapi.d/plugins/utils.py2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/workarounds2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py2
-rwxr-xr-xrun_tests.sh4
-rw-r--r--tools/conf/extract_opts.py25
-rwxr-xr-xtools/conf/generate_sample.sh8
-rwxr-xr-xtools/db/schema_diff.py2
-rwxr-xr-xtools/enable-pre-commit-hook.sh2
-rw-r--r--tools/esx/guest_tool.py2
-rwxr-xr-xtools/hacking.py92
-rw-r--r--tools/install_venv.py2
-rw-r--r--tools/install_venv_common.py5
-rw-r--r--tools/patch_tox_venv.py38
-rw-r--r--tools/pip-requires12
-rwxr-xr-xtools/xenserver/cleanup_sm_locks.py2
-rw-r--r--tools/xenserver/vdi_chain_cleanup.py2
-rwxr-xr-xtools/xenserver/vm_vdi_cleaner.py2
-rw-r--r--tox.ini6
604 files changed, 5724 insertions, 2796 deletions
diff --git a/HACKING.rst b/HACKING.rst
index 223f3ed7b..307d7477c 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -271,8 +271,8 @@ Commit Messages
Using a common format for commit messages will help keep our git history
readable. Follow these guidelines:
- First, provide a brief summary (it is recommended to keep the commit title
- under 50 chars).
+ First, provide a brief summary of 50 characters or less. Summaries
+ of greater then 72 characters will be rejected by the gate.
The first line of the commit message should provide an accurate
description of the change, not just a reference to a bug or
diff --git a/README.rst b/README.rst
index 43f6b9d51..8e50b4584 100644
--- a/README.rst
+++ b/README.rst
@@ -3,7 +3,7 @@ OpenStack Nova README
OpenStack Nova provides a cloud computing fabric controller,
supporting a wide variety of virtualization technologies,
-including KVM, Xen, LXC, VMWare, and more. In addition to
+including KVM, Xen, LXC, VMware, and more. In addition to
its native API, it includes compatibility with the commonly
encountered Amazon EC2 and S3 APIs.
diff --git a/bin/nova-all b/bin/nova-all
index 5fb1748e8..ace305727 100755
--- a/bin/nova-all
+++ b/bin/nova-all
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack, LLC
+# Copyright 2011 OpenStack Foundation
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
diff --git a/bin/nova-baremetal-deploy-helper b/bin/nova-baremetal-deploy-helper
index 0d2d21984..756305776 100755
--- a/bin/nova-baremetal-deploy-helper
+++ b/bin/nova-baremetal-deploy-helper
@@ -121,6 +121,7 @@ def dd(src, dst):
'if=%s' % src,
'of=%s' % dst,
'bs=1M',
+ 'oflag=direct',
run_as_root=True,
check_exit_code=[0])
diff --git a/bin/nova-cert b/bin/nova-cert
index d309cc028..c6d9ddbad 100755
--- a/bin/nova-cert
+++ b/bin/nova-cert
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack, LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/bin/nova-clear-rabbit-queues b/bin/nova-clear-rabbit-queues
index 3e8b8e56d..32a7fe5d1 100755
--- a/bin/nova-clear-rabbit-queues
+++ b/bin/nova-clear-rabbit-queues
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/bin/nova-console b/bin/nova-console
index c567f28b1..6d6569104 100755
--- a/bin/nova-console
+++ b/bin/nova-console
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/bin/nova-consoleauth b/bin/nova-consoleauth
index 776ee9b35..0cbec669a 100755
--- a/bin/nova-consoleauth
+++ b/bin/nova-consoleauth
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge
index c00578821..1acaf4cd1 100755
--- a/bin/nova-dhcpbridge
+++ b/bin/nova-dhcpbridge
@@ -42,6 +42,7 @@ from nova import context
from nova import db
from nova.network import rpcapi as network_rpcapi
from nova.openstack.common import importutils
+from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common import rpc
@@ -121,7 +122,8 @@ def main():
except KeyError:
config_file = os.environ['FLAGFILE']
- config.parse_args(sys.argv, default_config_files=[config_file])
+ config.parse_args(sys.argv,
+ default_config_files=jsonutils.loads(config_file))
logging.setup("nova")
diff --git a/bin/nova-manage b/bin/nova-manage
index c4e9841ce..274ae4640 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -80,7 +80,7 @@ from nova import db
from nova.db import migration
from nova import exception
from nova.openstack.common import cliutils
-from nova.openstack.common.db.sqlalchemy import session as db_session
+from nova.openstack.common.db import exception as db_exc
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common import rpc
@@ -790,12 +790,15 @@ class DbCommands(object):
@args('--max_rows', dest='max_rows', metavar='<number>',
help='Maximum number of deleted rows to archive')
- def archive_deleted_rows(self, max_rows=None):
+ def archive_deleted_rows(self, max_rows):
"""Move up to max_rows deleted rows from production tables to shadow
tables.
"""
if max_rows is not None:
max_rows = int(max_rows)
+ if max_rows < 0:
+ print _("Must supply a positive value for max_rows")
+ sys.exit(1)
admin_context = context.get_admin_context()
db.archive_deleted_rows(admin_context, max_rows)
@@ -861,7 +864,7 @@ class InstanceTypeCommands(object):
except exception.InstanceTypeNotFound:
print _("Valid instance type name is required")
sys.exit(1)
- except db_session.DBError, e:
+ except db_exc.DBError, e:
print _("DB Error: %s") % e
sys.exit(2)
except Exception:
@@ -878,7 +881,7 @@ class InstanceTypeCommands(object):
inst_types = instance_types.get_all_types()
else:
inst_types = instance_types.get_instance_type_by_name(name)
- except db_session.DBError, e:
+ except db_exc.DBError, e:
_db_error(e)
if isinstance(inst_types.values()[0], dict):
for k, v in inst_types.iteritems():
@@ -909,7 +912,7 @@ class InstanceTypeCommands(object):
ext_spec)
print _("Key %(key)s set to %(value)s on instance"
" type %(name)s") % locals()
- except db_session.DBError, e:
+ except db_exc.DBError, e:
_db_error(e)
@args('--name', dest='name', metavar='<name>',
@@ -932,7 +935,7 @@ class InstanceTypeCommands(object):
key)
print _("Key %(key)s on instance type %(name)s unset") % locals()
- except db_session.DBError, e:
+ except db_exc.DBError, e:
_db_error(e)
diff --git a/bin/nova-novncproxy b/bin/nova-novncproxy
index 45f272ada..37486f6a4 100755
--- a/bin/nova-novncproxy
+++ b/bin/nova-novncproxy
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/bin/nova-rootwrap b/bin/nova-rootwrap
index 35e2f47f3..e42f383dc 100755
--- a/bin/nova-rootwrap
+++ b/bin/nova-rootwrap
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/bin/nova-rpc-zmq-receiver b/bin/nova-rpc-zmq-receiver
index 90b652b91..7995fbe80 100755
--- a/bin/nova-rpc-zmq-receiver
+++ b/bin/nova-rpc-zmq-receiver
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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
@@ -39,10 +39,10 @@ from nova.openstack.common.rpc import impl_zmq
CONF = cfg.CONF
CONF.register_opts(rpc.rpc_opts)
CONF.register_opts(impl_zmq.zmq_opts)
-CONF(sys.argv[1:], project='nova')
def main():
+ CONF(sys.argv[1:], project='nova')
logging.setup("nova")
with contextlib.closing(impl_zmq.ZmqProxy(CONF)) as reactor:
diff --git a/bin/nova-spicehtml5proxy b/bin/nova-spicehtml5proxy
index 23d250ca3..a4c97a73d 100755
--- a/bin/nova-spicehtml5proxy
+++ b/bin/nova-spicehtml5proxy
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/bin/nova-xvpvncproxy b/bin/nova-xvpvncproxy
index c24f41176..6ad61d0ba 100755
--- a/bin/nova-xvpvncproxy
+++ b/bin/nova-xvpvncproxy
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/doc/api_samples/os-volumes/attach-volume-to-server-req.json b/doc/api_samples/os-volumes/attach-volume-to-server-req.json
new file mode 100644
index 000000000..4062687fc
--- /dev/null
+++ b/doc/api_samples/os-volumes/attach-volume-to-server-req.json
@@ -0,0 +1,6 @@
+{
+ "volumeAttachment": {
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "device": "/dev/vdd"
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/attach-volume-to-server-req.xml b/doc/api_samples/os-volumes/attach-volume-to-server-req.xml
new file mode 100644
index 000000000..eedfc329a
--- /dev/null
+++ b/doc/api_samples/os-volumes/attach-volume-to-server-req.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<volumeAttachment volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803" device="/dev/vdd" /> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/attach-volume-to-server-resp.json b/doc/api_samples/os-volumes/attach-volume-to-server-resp.json
new file mode 100644
index 000000000..2e512ac99
--- /dev/null
+++ b/doc/api_samples/os-volumes/attach-volume-to-server-resp.json
@@ -0,0 +1,8 @@
+{
+ "volumeAttachment": {
+ "device": "/dev/vdd",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "0c92f3f6-c253-4c9b-bd43-e880a8d2eb0a",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/attach-volume-to-server-resp.xml b/doc/api_samples/os-volumes/attach-volume-to-server-resp.xml
new file mode 100644
index 000000000..aaa85dd43
--- /dev/null
+++ b/doc/api_samples/os-volumes/attach-volume-to-server-resp.xml
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumeAttachment device="/dev/vdd" serverId="20f0cb44-7b00-4019-a612-364777cd2931" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/list-volume-attachments-resp.json b/doc/api_samples/os-volumes/list-volume-attachments-resp.json
new file mode 100644
index 000000000..9ae9b4a2a
--- /dev/null
+++ b/doc/api_samples/os-volumes/list-volume-attachments-resp.json
@@ -0,0 +1,16 @@
+{
+ "volumeAttachments": [
+ {
+ "device": "/dev/sdd",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "4d8c3732-a248-40ed-bebc-539a6ffd25c0",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ },
+ {
+ "device": "/dev/sdc",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f804",
+ "serverId": "4d8c3732-a248-40ed-bebc-539a6ffd25c0",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f804"
+ }
+ ]
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/list-volume-attachments-resp.xml b/doc/api_samples/os-volumes/list-volume-attachments-resp.xml
new file mode 100644
index 000000000..7d70882c0
--- /dev/null
+++ b/doc/api_samples/os-volumes/list-volume-attachments-resp.xml
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumeAttachments>
+ <volumeAttachment device="/dev/sdd" serverId="4335bab6-6086-4247-8274-8b8b048edaaa" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/>
+ <volumeAttachment device="/dev/sdc" serverId="4335bab6-6086-4247-8274-8b8b048edaaa" id="a26887c6-c47b-4654-abb5-dfadf7d3f804" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f804"/>
+</volumeAttachments> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/os-volumes-detail-resp.json b/doc/api_samples/os-volumes/os-volumes-detail-resp.json
new file mode 100644
index 000000000..95be0419e
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-detail-resp.json
@@ -0,0 +1,24 @@
+{
+ "volumes": [
+ {
+ "attachments": [
+ {
+ "device": "/",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "3912f2b4-c5ba-4aec-9165-872876fe202e",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ }
+ ],
+ "availabilityZone": "zone1:host1",
+ "createdAt": "1999-01-01T01:01:01",
+ "displayDescription": "Volume Description",
+ "displayName": "Volume Name",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "metadata": {},
+ "size": 100,
+ "snapshotId": null,
+ "status": "in-use",
+ "volumeType": "Backup"
+ }
+ ]
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/os-volumes-detail-resp.xml b/doc/api_samples/os-volumes/os-volumes-detail-resp.xml
new file mode 100644
index 000000000..b849c2d2e
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-detail-resp.xml
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumes>
+ <volume status="in-use" displayDescription="Volume Description" availabilityZone="zone1:host1" displayName="Volume Name" volumeType="Backup" snapshotId="None" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" createdAt="2008-12-01T11:01:55" size="100">
+ <attachments>
+ <attachment device="/" serverId="3912f2b4-c5ba-4aec-9165-872876fe202e" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/>
+ </attachments>
+ <metadata/>
+ </volume>
+</volumes> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/os-volumes-get-resp.json b/doc/api_samples/os-volumes/os-volumes-get-resp.json
new file mode 100644
index 000000000..5c8429cb1
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-get-resp.json
@@ -0,0 +1,22 @@
+{
+ "volume": {
+ "attachments": [
+ {
+ "device": "/",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "3912f2b4-c5ba-4aec-9165-872876fe202e",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ }
+ ],
+ "availabilityZone": "zone1:host1",
+ "createdAt": "2013-02-18T14:51:18.528085",
+ "displayDescription": "Volume Description",
+ "displayName": "Volume Name",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "metadata": {},
+ "size": 100,
+ "snapshotId": null,
+ "status": "in-use",
+ "volumeType": "Backup"
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/os-volumes-get-resp.xml b/doc/api_samples/os-volumes/os-volumes-get-resp.xml
new file mode 100644
index 000000000..1a516d5d2
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-get-resp.xml
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volume status="in-use" displayDescription="Volume Description" availabilityZone="zone1:host1" displayName="Volume Name" volumeType="Backup" snapshotId="None" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" createdAt="2008-12-01T11:01:55" size="100">
+ <attachments>
+ <attachment device="/" serverId="3912f2b4-c5ba-4aec-9165-872876fe202e" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/>
+ </attachments>
+ <metadata/>
+</volume> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/os-volumes-index-resp.json b/doc/api_samples/os-volumes/os-volumes-index-resp.json
new file mode 100644
index 000000000..c0fa4b891
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-index-resp.json
@@ -0,0 +1,24 @@
+{
+ "volumes": [
+ {
+ "attachments": [
+ {
+ "device": "/",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "3912f2b4-c5ba-4aec-9165-872876fe202e",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ }
+ ],
+ "availabilityZone": "zone1:host1",
+ "createdAt": "2013-02-19T20:01:40.274897",
+ "displayDescription": "Volume Description",
+ "displayName": "Volume Name",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "metadata": {},
+ "size": 100,
+ "snapshotId": null,
+ "status": "in-use",
+ "volumeType": "Backup"
+ }
+ ]
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/os-volumes-index-resp.xml b/doc/api_samples/os-volumes/os-volumes-index-resp.xml
new file mode 100644
index 000000000..b849c2d2e
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-index-resp.xml
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumes>
+ <volume status="in-use" displayDescription="Volume Description" availabilityZone="zone1:host1" displayName="Volume Name" volumeType="Backup" snapshotId="None" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" createdAt="2008-12-01T11:01:55" size="100">
+ <attachments>
+ <attachment device="/" serverId="3912f2b4-c5ba-4aec-9165-872876fe202e" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/>
+ </attachments>
+ <metadata/>
+ </volume>
+</volumes> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/os-volumes-post-req.json b/doc/api_samples/os-volumes/os-volumes-post-req.json
new file mode 100644
index 000000000..c8b218adb
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-post-req.json
@@ -0,0 +1,9 @@
+{
+ "volume":
+ {
+ "availability_zone": "zone1:host1",
+ "display_name": "Volume Name",
+ "display_description": "Volume Description",
+ "size": 100
+ }
+}
diff --git a/doc/api_samples/os-volumes/os-volumes-post-req.xml b/doc/api_samples/os-volumes/os-volumes-post-req.xml
new file mode 100644
index 000000000..68a0b5864
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-post-req.xml
@@ -0,0 +1,3 @@
+<?xml version='1.0' encoding='UTF-8'?>
+ <volume displayDescription="Volume Description" availabilityZone="zone1:host1" displayName="Volume Name" size="100"/>
+
diff --git a/doc/api_samples/os-volumes/os-volumes-post-resp.json b/doc/api_samples/os-volumes/os-volumes-post-resp.json
new file mode 100644
index 000000000..ba3795a0b
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-post-resp.json
@@ -0,0 +1,22 @@
+{
+ "volume": {
+ "attachments": [
+ {
+ "device": "/",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "3912f2b4-c5ba-4aec-9165-872876fe202e",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ }
+ ],
+ "availabilityZone": "zone1:host1",
+ "createdAt": "2013-02-18T14:51:17.970024",
+ "displayDescription": "Volume Description",
+ "displayName": "Volume Name",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "metadata": {},
+ "size": 100,
+ "snapshotId": null,
+ "status": "in-use",
+ "volumeType": "Backup"
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/os-volumes-post-resp.xml b/doc/api_samples/os-volumes/os-volumes-post-resp.xml
new file mode 100644
index 000000000..1a516d5d2
--- /dev/null
+++ b/doc/api_samples/os-volumes/os-volumes-post-resp.xml
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volume status="in-use" displayDescription="Volume Description" availabilityZone="zone1:host1" displayName="Volume Name" volumeType="Backup" snapshotId="None" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" createdAt="2008-12-01T11:01:55" size="100">
+ <attachments>
+ <attachment device="/" serverId="3912f2b4-c5ba-4aec-9165-872876fe202e" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/>
+ </attachments>
+ <metadata/>
+</volume> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/server-post-req.json b/doc/api_samples/os-volumes/server-post-req.json
new file mode 100644
index 000000000..d88eb4122
--- /dev/null
+++ b/doc/api_samples/os-volumes/server-post-req.json
@@ -0,0 +1,16 @@
+{
+ "server" : {
+ "name" : "new-server-test",
+ "imageRef" : "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b",
+ "flavorRef" : "http://openstack.example.com/openstack/flavors/1",
+ "metadata" : {
+ "My Server Name" : "Apache1"
+ },
+ "personality" : [
+ {
+ "path" : "/etc/banner.txt",
+ "contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/server-post-req.xml b/doc/api_samples/os-volumes/server-post-req.xml
new file mode 100644
index 000000000..0a3c8bb53
--- /dev/null
+++ b/doc/api_samples/os-volumes/server-post-req.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<server xmlns="http://docs.openstack.org/compute/api/v1.1" imageRef="http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" flavorRef="http://openstack.example.com/openstack/flavors/1" name="new-server-test">
+ <metadata>
+ <meta key="My Server Name">Apache1</meta>
+ </metadata>
+ <personality>
+ <file path="/etc/banner.txt">
+ ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp
+ dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k
+ IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs
+ c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g
+ QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo
+ ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv
+ dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy
+ c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6
+ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==
+ </file>
+ </personality>
+</server> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/server-post-resp.json b/doc/api_samples/os-volumes/server-post-resp.json
new file mode 100644
index 000000000..6ae553403
--- /dev/null
+++ b/doc/api_samples/os-volumes/server-post-resp.json
@@ -0,0 +1,16 @@
+{
+ "server": {
+ "adminPass": "8VqALQcVB9MT",
+ "id": "a80b9477-84c1-4242-9731-14a3c2a04241",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/a80b9477-84c1-4242-9731-14a3c2a04241",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/a80b9477-84c1-4242-9731-14a3c2a04241",
+ "rel": "bookmark"
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/server-post-resp.xml b/doc/api_samples/os-volumes/server-post-resp.xml
new file mode 100644
index 000000000..b2474027d
--- /dev/null
+++ b/doc/api_samples/os-volumes/server-post-resp.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<server xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="b11339a0-3a3e-496d-ade0-4539dbb5d816" adminPass="J3qyiuLMEWV3">
+ <metadata/>
+ <atom:link href="http://openstack.example.com/v2/openstack/servers/b11339a0-3a3e-496d-ade0-4539dbb5d816" rel="self"/>
+ <atom:link href="http://openstack.example.com/openstack/servers/b11339a0-3a3e-496d-ade0-4539dbb5d816" rel="bookmark"/>
+</server> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshot-create-req.json b/doc/api_samples/os-volumes/snapshot-create-req.json
new file mode 100644
index 000000000..8ad5b3cb0
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshot-create-req.json
@@ -0,0 +1,8 @@
+{
+ "snapshot": {
+ "display_name": "snap-001",
+ "display_description": "Daily backup",
+ "volume_id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c",
+ "force": false
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshot-create-req.xml b/doc/api_samples/os-volumes/snapshot-create-req.xml
new file mode 100644
index 000000000..e5001cf06
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshot-create-req.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <snapshot>
+ <display_name>snap-001</display_name>
+ <display_description>Daily backup</display_description>
+ <volume_id>521752a6-acf6-4b2d-bc7a-119f9148cd8c</volume_id>
+ <force>false</force>
+ </snapshot> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshot-create-resp.json b/doc/api_samples/os-volumes/snapshot-create-resp.json
new file mode 100644
index 000000000..1a14bea01
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshot-create-resp.json
@@ -0,0 +1,32 @@
+{
+ "snapshot": {
+ "createdAt": "2013-02-25T16:27:54.680544",
+ "displayDescription": "Daily backup",
+ "displayName": "snap-001",
+ "id": 100,
+ "size": 100,
+ "status": "available",
+ "volumeId": {
+ "attach_status": "attached",
+ "availability_zone": "fakeaz",
+ "created_at": "1999-01-01T01:01:01.000000",
+ "display_description": "displaydesc",
+ "display_name": "displayname",
+ "host": "fakehost",
+ "id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c",
+ "instance_uuid": "fakeuuid",
+ "mountpoint": "/",
+ "name": "vol name",
+ "project_id": "fakeproject",
+ "size": 1,
+ "snapshot_id": null,
+ "status": "fakestatus",
+ "user_id": "fakeuser",
+ "volume_metadata": [],
+ "volume_type": {
+ "name": "vol_type_name"
+ },
+ "volume_type_id": "fakevoltype"
+ }
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshot-create-resp.xml b/doc/api_samples/os-volumes/snapshot-create-resp.xml
new file mode 100644
index 000000000..ad815f723
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshot-create-resp.xml
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<snapshot status="available" displayDescription="Daily backup" displayName="snap-001" volumeId="{'instance_uuid': 'fakeuuid', 'status': 'fakestatus', 'user_id': 'fakeuser', 'name': 'vol name', 'display_name': 'displayname', 'availability_zone': 'fakeaz', 'created_at': datetime.datetime(1999, 1, 1, 1, 1, 1), 'attach_status': 'attached', 'display_description': 'displaydesc', 'host': 'fakehost', 'volume_type_id': 'fakevoltype', 'volume_metadata': [], 'volume_type': {'name': 'vol_type_name'}, 'snapshot_id': None, 'mountpoint': '/', 'project_id': 'fakeproject', 'id': u'521752a6-acf6-4b2d-bc7a-119f9148cd8c', 'size': 1}" id="100" createdAt="2013-02-25 16:27:36.840121" size="100"/> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshots-detail-resp.json b/doc/api_samples/os-volumes/snapshots-detail-resp.json
new file mode 100644
index 000000000..796e522c4
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshots-detail-resp.json
@@ -0,0 +1,31 @@
+{
+ "snapshots": [
+ {
+ "createdAt": "2013-02-25T16:27:54.671372",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 100,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ },
+ {
+ "createdAt": "2013-02-25T16:27:54.671378",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 101,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ },
+ {
+ "createdAt": "2013-02-25T16:27:54.671381",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 102,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ }
+ ]
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshots-detail-resp.xml b/doc/api_samples/os-volumes/snapshots-detail-resp.xml
new file mode 100644
index 000000000..5e946939f
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshots-detail-resp.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<snapshots>
+ <snapshot status="available" displayDescription="Default description" displayName="Default name" volumeId="12" id="100" createdAt="2013-02-25 16:27:36.862459" size="100"/>
+ <snapshot status="available" displayDescription="Default description" displayName="Default name" volumeId="12" id="101" createdAt="2013-02-25 16:27:36.862466" size="100"/>
+ <snapshot status="available" displayDescription="Default description" displayName="Default name" volumeId="12" id="102" createdAt="2013-02-25 16:27:36.862469" size="100"/>
+</snapshots> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshots-list-resp.json b/doc/api_samples/os-volumes/snapshots-list-resp.json
new file mode 100644
index 000000000..9b7cb412a
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshots-list-resp.json
@@ -0,0 +1,31 @@
+{
+ "snapshots": [
+ {
+ "createdAt": "2013-02-25T16:27:54.684999",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 100,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ },
+ {
+ "createdAt": "2013-02-25T16:27:54.685005",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 101,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ },
+ {
+ "createdAt": "2013-02-25T16:27:54.685008",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 102,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ }
+ ]
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshots-list-resp.xml b/doc/api_samples/os-volumes/snapshots-list-resp.xml
new file mode 100644
index 000000000..6714c98bc
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshots-list-resp.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<snapshots>
+ <snapshot status="available" displayDescription="Default description" displayName="Default name" volumeId="12" id="100" createdAt="2013-02-25 16:27:36.769149" size="100"/>
+ <snapshot status="available" displayDescription="Default description" displayName="Default name" volumeId="12" id="101" createdAt="2013-02-25 16:27:36.769154" size="100"/>
+ <snapshot status="available" displayDescription="Default description" displayName="Default name" volumeId="12" id="102" createdAt="2013-02-25 16:27:36.769157" size="100"/>
+</snapshots> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshots-show-resp.json b/doc/api_samples/os-volumes/snapshots-show-resp.json
new file mode 100644
index 000000000..d7b3f26e4
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshots-show-resp.json
@@ -0,0 +1,11 @@
+{
+ "snapshot": {
+ "createdAt": "2013-02-25T16:27:54.724209",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": "100",
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/snapshots-show-resp.xml b/doc/api_samples/os-volumes/snapshots-show-resp.xml
new file mode 100644
index 000000000..3c70cf033
--- /dev/null
+++ b/doc/api_samples/os-volumes/snapshots-show-resp.xml
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<snapshot status="available" displayDescription="Default description" displayName="Default name" volumeId="12" id="100" createdAt="2013-02-25 16:27:36.854206" size="100"/> \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/volume-attachment-detail-resp.json b/doc/api_samples/os-volumes/volume-attachment-detail-resp.json
new file mode 100644
index 000000000..5375033bb
--- /dev/null
+++ b/doc/api_samples/os-volumes/volume-attachment-detail-resp.json
@@ -0,0 +1,8 @@
+{
+ "volumeAttachment": {
+ "device": "/dev/sdd",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "2390fb4d-1693-45d7-b309-e29c4af16538",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ }
+} \ No newline at end of file
diff --git a/doc/api_samples/os-volumes/volume-attachment-detail-resp.xml b/doc/api_samples/os-volumes/volume-attachment-detail-resp.xml
new file mode 100644
index 000000000..dea235292
--- /dev/null
+++ b/doc/api_samples/os-volumes/volume-attachment-detail-resp.xml
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumeAttachment device="/dev/sdd" serverId="20f12907-3993-44f7-a680-d51e2ceedbd9" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/> \ No newline at end of file
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 9af5f5494..4fa13e045 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -58,7 +58,7 @@ master_doc = 'index'
# General information about the project.
project = u'nova'
-copyright = u'2010-present, OpenStack, LLC'
+copyright = u'2010-present, OpenStack Foundation'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/doc/source/devref/addmethod.openstackapi.rst b/doc/source/devref/addmethod.openstackapi.rst
index 18123f8cc..fe6b77c87 100644
--- a/doc/source/devref/addmethod.openstackapi.rst
+++ b/doc/source/devref/addmethod.openstackapi.rst
@@ -1,5 +1,5 @@
..
- Copyright 2010-2011 OpenStack LLC
+ Copyright 2010-2011 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/doc/source/devref/aggregates.rst b/doc/source/devref/aggregates.rst
index ecc6329ba..7e854e6ae 100644
--- a/doc/source/devref/aggregates.rst
+++ b/doc/source/devref/aggregates.rst
@@ -1,5 +1,5 @@
..
- Copyright 2012 OpenStack, LLC
+ Copyright 2012 OpenStack Foundation
Copyright 2012 Citrix Systems, Inc.
Copyright 2012, The Cloudscaling Group, Inc.
All Rights Reserved.
diff --git a/doc/source/man/nova-all.rst b/doc/source/man/nova-all.rst
index 4cb0b21c5..05bf128a1 100644
--- a/doc/source/man/nova-all.rst
+++ b/doc/source/man/nova-all.rst
@@ -8,7 +8,7 @@ Server for all Nova services
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-api-ec2.rst b/doc/source/man/nova-api-ec2.rst
index ce3126480..209809cd9 100644
--- a/doc/source/man/nova-api-ec2.rst
+++ b/doc/source/man/nova-api-ec2.rst
@@ -8,7 +8,7 @@ Server for the Nova EC2 API
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-api-metadata.rst b/doc/source/man/nova-api-metadata.rst
index 6c5a0d8f8..281f279a2 100644
--- a/doc/source/man/nova-api-metadata.rst
+++ b/doc/source/man/nova-api-metadata.rst
@@ -8,7 +8,7 @@ Server for the Nova Metadata API
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-api-os-compute.rst b/doc/source/man/nova-api-os-compute.rst
index 4819285c0..f4fac477e 100644
--- a/doc/source/man/nova-api-os-compute.rst
+++ b/doc/source/man/nova-api-os-compute.rst
@@ -8,7 +8,7 @@ Server for the Nova OpenStack Compute APIs
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-api.rst b/doc/source/man/nova-api.rst
index fe378f721..247b10cae 100644
--- a/doc/source/man/nova-api.rst
+++ b/doc/source/man/nova-api.rst
@@ -8,7 +8,7 @@ Server for the Nova EC2 and OpenStack APIs
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-baremetal-deploy-helper.rst b/doc/source/man/nova-baremetal-deploy-helper.rst
index 106cb85e7..4ba3830f6 100644
--- a/doc/source/man/nova-baremetal-deploy-helper.rst
+++ b/doc/source/man/nova-baremetal-deploy-helper.rst
@@ -8,7 +8,7 @@ Writes images to a bare-metal node and switch it to instance-mode
:Author: openstack@lists.launchpad.net
:Date: 2012-10-17
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2013.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-baremetal-manage.rst b/doc/source/man/nova-baremetal-manage.rst
index 1fab368e5..10de08dfc 100644
--- a/doc/source/man/nova-baremetal-manage.rst
+++ b/doc/source/man/nova-baremetal-manage.rst
@@ -8,7 +8,7 @@ Manage bare-metal DB in OpenStack Nova
:Author: openstack@lists.launchpad.net
:Date: 2012-10-17
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2013.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-cert.rst b/doc/source/man/nova-cert.rst
index f8c6d0c2d..f7a5c72ef 100644
--- a/doc/source/man/nova-cert.rst
+++ b/doc/source/man/nova-cert.rst
@@ -8,7 +8,7 @@ Server for the Nova Cert
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-compute.rst b/doc/source/man/nova-compute.rst
index 97a4b447b..9dd100c98 100644
--- a/doc/source/man/nova-compute.rst
+++ b/doc/source/man/nova-compute.rst
@@ -8,7 +8,7 @@ Nova Compute Server
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-conductor.rst b/doc/source/man/nova-conductor.rst
index 7a32730e1..2b98d62c2 100644
--- a/doc/source/man/nova-conductor.rst
+++ b/doc/source/man/nova-conductor.rst
@@ -8,7 +8,7 @@ Server for the Nova Conductor
:Author: openstack@lists.launchpad.net
:Date: 2012-11-16
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-console.rst b/doc/source/man/nova-console.rst
index 60d910b0e..895edf867 100644
--- a/doc/source/man/nova-console.rst
+++ b/doc/source/man/nova-console.rst
@@ -8,7 +8,7 @@ Nova Console Server
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-consoleauth.rst b/doc/source/man/nova-consoleauth.rst
index fe0cf1bcf..11f6d7712 100644
--- a/doc/source/man/nova-consoleauth.rst
+++ b/doc/source/man/nova-consoleauth.rst
@@ -8,7 +8,7 @@ Nova Console Authentication Server
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-dhcpbridge.rst b/doc/source/man/nova-dhcpbridge.rst
index 3405a9c4e..63faaf35d 100644
--- a/doc/source/man/nova-dhcpbridge.rst
+++ b/doc/source/man/nova-dhcpbridge.rst
@@ -8,7 +8,7 @@ Handles Lease Database updates from DHCP servers
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-manage.rst b/doc/source/man/nova-manage.rst
index a3a742af9..1800a4875 100644
--- a/doc/source/man/nova-manage.rst
+++ b/doc/source/man/nova-manage.rst
@@ -8,7 +8,7 @@ control and manage cloud computer instances and images
:Author: openstack@lists.launchpad.net
:Date: 2012-04-05
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-network.rst b/doc/source/man/nova-network.rst
index 1073a6834..42e017534 100644
--- a/doc/source/man/nova-network.rst
+++ b/doc/source/man/nova-network.rst
@@ -8,7 +8,7 @@ Nova Network Server
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-novncproxy.rst b/doc/source/man/nova-novncproxy.rst
index 5302fd063..a7068e8c4 100644
--- a/doc/source/man/nova-novncproxy.rst
+++ b/doc/source/man/nova-novncproxy.rst
@@ -8,7 +8,7 @@ Websocket novnc Proxy for OpenStack Nova noVNC consoles.
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-objectstore.rst b/doc/source/man/nova-objectstore.rst
index c4bc16d3e..70c7dde1f 100644
--- a/doc/source/man/nova-objectstore.rst
+++ b/doc/source/man/nova-objectstore.rst
@@ -8,7 +8,7 @@ Nova Objectstore Server
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-rootwrap.rst b/doc/source/man/nova-rootwrap.rst
index 8bc089a35..d8050d094 100644
--- a/doc/source/man/nova-rootwrap.rst
+++ b/doc/source/man/nova-rootwrap.rst
@@ -8,7 +8,7 @@ Root wrapper for Nova
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-rpc-zmq-receiver.rst b/doc/source/man/nova-rpc-zmq-receiver.rst
index c42afae6d..72ed6a76e 100644
--- a/doc/source/man/nova-rpc-zmq-receiver.rst
+++ b/doc/source/man/nova-rpc-zmq-receiver.rst
@@ -8,7 +8,7 @@ Receiver for 0MQ based nova RPC
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-scheduler.rst b/doc/source/man/nova-scheduler.rst
index b125352a0..1d8b9c995 100644
--- a/doc/source/man/nova-scheduler.rst
+++ b/doc/source/man/nova-scheduler.rst
@@ -8,7 +8,7 @@ Nova Scheduler
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-spicehtml5proxy.rst b/doc/source/man/nova-spicehtml5proxy.rst
index 4d0aaa202..0d06b6eb1 100644
--- a/doc/source/man/nova-spicehtml5proxy.rst
+++ b/doc/source/man/nova-spicehtml5proxy.rst
@@ -8,7 +8,7 @@ Websocket Proxy for OpenStack Nova SPICE HTML5 consoles.
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/doc/source/man/nova-xvpvncproxy.rst b/doc/source/man/nova-xvpvncproxy.rst
index e6f8904e7..7c624f6ad 100644
--- a/doc/source/man/nova-xvpvncproxy.rst
+++ b/doc/source/man/nova-xvpvncproxy.rst
@@ -8,7 +8,7 @@ XVP VNC Console Proxy Server
:Author: openstack@lists.launchpad.net
:Date: 2012-09-27
-:Copyright: OpenStack LLC
+:Copyright: OpenStack Foundation
:Version: 2012.1
:Manual section: 1
:Manual group: cloud computing
diff --git a/etc/nova/nova.conf.sample b/etc/nova/nova.conf.sample
index 9cbb8c1a5..ed989ce86 100644
--- a/etc/nova/nova.conf.sample
+++ b/etc/nova/nova.conf.sample
@@ -577,12 +577,14 @@
# a raw disk image instead (string value)
#null_kernel=nokernel
-# The full class name of the security group handler class
-# (string value)
-#security_group_handler=nova.network.sg.NullSecurityGroupHandler
-
-# The full class name of the security API class (string value)
-#security_group_api=nova.compute.api.SecurityGroupAPI
+# When creating multiple instances with a single request using
+# the os-multiple-create API extension, this template will be
+# used to build the display name for each instance. The
+# benefit is that the instances end up with different
+# hostnames. To restore legacy behavior of every instance
+# having the same name, set this option to "%(name)s". Valid
+# keys for the template are: name, uuid, count. (string value)
+#multi_instance_display_name_template=%(name)s-%(uuid)s
#
@@ -781,9 +783,6 @@
# Options defined in nova.db.api
#
-# The backend to use for db (string value)
-#db_backend=sqlalchemy
-
# Services to be added to the available pool on create
# (boolean value)
#enable_new_services=true
@@ -970,7 +969,7 @@
# Options defined in nova.network.linux_net
#
-# location of flagfile for dhcpbridge (string value)
+# location of flagfiles for dhcpbridge (multi valued)
#dhcpbridge_flagfile=/etc/nova/nova-dhcpbridge.conf
# Location to keep network config files (string value)
@@ -991,12 +990,22 @@
# Lifetime of a DHCP lease in seconds (integer value)
#dhcp_lease_time=120
-# if set, uses specific dns server for dnsmasq (string value)
-#dns_server=<None>
+# if set, uses specific dns server for dnsmasq. Canbe
+# specified multiple times. (multi valued)
+#dns_server=
+
+# if set, uses the dns1 and dns2 from the network ref.as dns
+# servers. (boolean value)
+#use_network_dns_servers=false
# A list of dmz range that should be accepted (list value)
#dmz_cidr=
+# Traffic to this range will always be snatted to the fallback
+# ip, even if it would normally be bridged out of the node.
+# Can be specified multiple times. (multi valued)
+#force_snat_range=
+
# Override the default dnsmasq settings with this file (string
# value)
#dnsmasq_config_file=
@@ -1029,6 +1038,14 @@
# the port for the metadata api port (integer value)
#metadata_port=8775
+# Regular expression to match iptables rule that shouldalways
+# be on the top. (string value)
+#iptables_top_regex=
+
+# Regular expression to match iptables rule that shouldalways
+# be on the bottom. (string value)
+#iptables_bottom_regex=
+
#
# Options defined in nova.network.manager
@@ -1157,6 +1174,9 @@
# value)
#quantum_admin_auth_url=http://localhost:5000/v2.0
+# if set, ignore any SSL validation issues (boolean value)
+#quantum_api_insecure=false
+
# auth strategy for connecting to quantum in admin context
# (string value)
#quantum_auth_strategy=keystone
@@ -1165,6 +1185,10 @@
# value)
#quantum_ovs_bridge=br-int
+# Number of seconds before querying quantum for extensions
+# (integer value)
+#quantum_extension_sync_interval=600
+
#
# Options defined in nova.network.rpcapi
@@ -1180,6 +1204,63 @@
#
+# Options defined in nova.network.security_group.openstack_driver
+#
+
+# The full class name of the security API class (string value)
+#security_group_api=nova
+
+# The full class name of the security group handler class
+# (string value)
+#security_group_handler=nova.network.sg.NullSecurityGroupHandler
+
+
+#
+# Options defined in bin.nova-clear-rabbit-queues
+#
+
+# Queues to delete (multi valued)
+#queues=
+
+# delete nova exchange too. (boolean value)
+#delete_exchange=false
+
+
+#
+# Options defined in bin.nova-novncproxy
+#
+
+# Record sessions to FILE.[session_number] (boolean value)
+#record=false
+
+# Become a daemon (background process) (boolean value)
+#daemon=false
+
+# Disallow non-encrypted connections (boolean value)
+#ssl_only=false
+
+# Source is ipv6 (boolean value)
+#source_is_ipv6=false
+
+# SSL certificate file (string value)
+#cert=self.pem
+
+# SSL key file (if separate from cert) (string value)
+#key=<None>
+
+# Run webserver on same port. Serve files from DIR. (string
+# value)
+#web=/usr/share/novnc
+
+# Host on which to listen for incoming requests (string value)
+#novncproxy_host=0.0.0.0
+
+# Port on which to listen for incoming requests (integer
+# value)
+#novncproxy_port=6080
+
+
+#
# Options defined in nova.objectstore.s3server
#
@@ -1194,12 +1275,24 @@
#
+# Options defined in nova.openstack.common.db.api
+#
+
+# The backend to use for db (string value)
+#db_backend=sqlalchemy
+
+# Enable the experimental use of thread pooling for all DB API
+# calls (boolean value)
+#dbapi_use_tpool=false
+
+
+#
# Options defined in nova.openstack.common.db.sqlalchemy.session
#
# The SQLAlchemy connection string used to connect to the
# database (string value)
-#sql_connection=sqlite:////home/markmc/git/openstack/nova/nova/openstack/common/db/$sqlite_db
+#sql_connection=sqlite:////nova/openstack/common/db/$sqlite_db
# the filename to use with sqlite (string value)
#sqlite_db=nova.sqlite
@@ -1239,10 +1332,6 @@
# value)
#sql_connection_trace=false
-# enable the use of eventlet's db_pool for MySQL (boolean
-# value)
-#sql_dbpool_enable=false
-
#
# Options defined in nova.openstack.common.eventlet_backdoor
@@ -1259,8 +1348,9 @@
# Whether to disable inter-process locks (boolean value)
#disable_process_locking=false
-# Directory to use for lock files (string value)
-#lock_path=/usr/lib/python/site-packages/nova/openstack
+# Directory to use for lock files. Default to a temp directory
+# (string value)
+#lock_path=<None>
#
@@ -1352,6 +1442,7 @@
# Driver or drivers to handle sending notifications (multi
# valued)
+#notification_driver=
# Default notification level for outgoing notifications
# (string value)
@@ -1405,6 +1496,15 @@
#
+# Options defined in nova.openstack.common.rpc.amqp
+#
+
+# Enable a fast single reply queue if using AMQP based RPC
+# like RabbitMQ or Qpid. (boolean value)
+#amqp_rpc_single_reply_queue=false
+
+
+#
# Options defined in nova.openstack.common.rpc.impl_kombu
#
@@ -1519,6 +1619,10 @@
# Number of ZeroMQ contexts, defaults to 1 (integer value)
#rpc_zmq_contexts=1
+# Maximum number of ingress messages to locally buffer per
+# topic. Default is unlimited. (integer value)
+#rpc_zmq_topic_backlog=<None>
+
# Directory for holding IPC sockets (string value)
#rpc_zmq_ipc_dir=/var/run/openstack
@@ -1549,6 +1653,19 @@
#
+# Options defined in nova.scheduler.filter_scheduler
+#
+
+# New instances will be scheduled on a host chosen randomly
+# from a subset of the N best hosts. This property defines the
+# subset size that a host is chosen from. A value of 1 chooses
+# the first host returned by the weighing functions. This
+# value must be at least 1. Any value less than 1 will be
+# ignored, and 1 will be used instead (integer value)
+#scheduler_host_subset_size=1
+
+
+#
# Options defined in nova.scheduler.filters.core_filter
#
@@ -1751,6 +1868,11 @@
# with on creation. (string value)
#default_ephemeral_format=<None>
+# VM image preallocation mode: "none" => no storage
+# provisioning is done up front, "space" => storage is fully
+# allocated at instance start (string value)
+#preallocate_images=none
+
# Whether to use cow images (boolean value)
#use_cow_images=true
@@ -1850,9 +1972,9 @@
# Inject the ssh public key at boot time (boolean value)
#libvirt_inject_key=true
-# The partition to inject to : -1 => inspect (libguestfs
-# only), 0 => not partitioned, >0 => partition number (integer
-# value)
+# The partition to inject to : -2 => disable, -1 => inspect
+# (libguestfs only), 0 => not partitioned, >0 => partition
+# number (integer value)
#libvirt_inject_partition=1
# Sync virtual and real mouse cursors in Windows VMs (boolean
@@ -1881,7 +2003,7 @@
#libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtGenericVIFDriver
# Libvirt handlers for remote volumes. (list value)
-#libvirt_volume_drivers=iscsi=nova.virt.libvirt.volume.LibvirtISCSIVolumeDriver,local=nova.virt.libvirt.volume.LibvirtVolumeDriver,fake=nova.virt.libvirt.volume.LibvirtFakeVolumeDriver,rbd=nova.virt.libvirt.volume.LibvirtNetVolumeDriver,sheepdog=nova.virt.libvirt.volume.LibvirtNetVolumeDriver,nfs=nova.virt.libvirt.volume.LibvirtNFSVolumeDriver
+#libvirt_volume_drivers=iscsi=nova.virt.libvirt.volume.LibvirtISCSIVolumeDriver,local=nova.virt.libvirt.volume.LibvirtVolumeDriver,fake=nova.virt.libvirt.volume.LibvirtFakeVolumeDriver,rbd=nova.virt.libvirt.volume.LibvirtNetVolumeDriver,sheepdog=nova.virt.libvirt.volume.LibvirtNetVolumeDriver,nfs=nova.virt.libvirt.volume.LibvirtNFSVolumeDriver,aoe=nova.virt.libvirt.volume.LibvirtAOEVolumeDriver,glusterfs=nova.virt.libvirt.volume.LibvirtGlusterfsVolumeDriver,fibre_channel=nova.virt.libvirt.volume.LibvirtFibreChannelVolumeDriver,scality=nova.virt.libvirt.volume.LibvirtScalityVolumeDriver
# Override the default disk prefix for the devices attached to
# a server, which is dependent on libvirt_type. (valid options
@@ -1919,6 +2041,10 @@
# Location where the Xen hvmloader is kept (string value)
#xen_hvmloader_path=/usr/lib/xen/boot/hvmloader
+# Specific cachemodes to use for different disk types e.g:
+# ["file=directsync","block=none"] (list value)
+#disk_cachemodes=
+
#
# Options defined in nova.virt.libvirt.imagebackend
@@ -1937,6 +2063,10 @@
# flag is set to True. (boolean value)
#libvirt_sparse_logical_volumes=false
+# The amount of storage (in megabytes) to allocate for LVM
+# snapshot copy-on-write blocks. (integer value)
+#libvirt_lvm_snapshot_size=1000
+
#
# Options defined in nova.virt.libvirt.imagecache
@@ -1954,6 +2084,12 @@
# Should unused base images be removed? (boolean value)
#remove_unused_base_images=true
+# Should unused kernel images be removed? This is only safe to
+# enable if all compute nodes have been updated to support
+# this option. This will enabled by default in future.
+# (boolean value)
+#remove_unused_kernels=false
+
# Unused resized base images younger than this will not be
# removed (integer value)
#remove_unused_resized_minimum_age_seconds=3600
@@ -2015,6 +2151,24 @@
# nfs man page for details (string value)
#nfs_mount_options=<None>
+# number of times to rediscover AoE target to find volume
+# (integer value)
+#num_aoe_discover_tries=3
+
+# Dir where the glusterfs volume is mounted on the compute
+# node (string value)
+#glusterfs_mount_point_base=$state_path/mnt
+
+# use multipath connection of the iSCSI volume (boolean value)
+#libvirt_iscsi_use_multipath=false
+
+# Path or URL to Scality SOFS configuration file (string
+# value)
+#scality_sofs_config=<None>
+
+# Base dir where Scality SOFS shall be mounted (string value)
+#scality_sofs_mount_point=$state_path/scality
+
#
# Options defined in nova.virt.powervm.driver
@@ -2032,11 +2186,14 @@
# PowerVM manager user password (string value)
#powervm_mgr_passwd=<None>
-# PowerVM image remote path (string value)
-#powervm_img_remote_path=<None>
+# PowerVM image remote path where images will be moved. Make
+# sure this path can fit your biggest image in glance (string
+# value)
+#powervm_img_remote_path=/home/padmin
-# Local directory to download glance images to (string value)
-#powervm_img_local_path=<None>
+# Local directory to download glance images to. Make sure this
+# path can fit your biggest image in glance (string value)
+#powervm_img_local_path=/tmp
#
@@ -2371,6 +2528,24 @@
# value)
#cinder_api_insecure=false
+# Allow attach between instance and volume in different
+# availability zones. (boolean value)
+#cinder_cross_az_attach=true
+
+
+[HYPERV]
+
+#
+# Options defined in nova.virt.hyperv.pathutils
+#
+
+# The name of a Windows share name mapped to the
+# "instances_path" dir and used by the resize feature to copy
+# files to the target host. If left blank, an administrative
+# share will be used, looking for the same "instances_path"
+# used locally (string value)
+#instances_path_share=
+
[conductor]
@@ -2474,6 +2649,28 @@
#db_check_interval=60
+[zookeeper]
+
+#
+# Options defined in nova.servicegroup.drivers.zk
+#
+
+# The ZooKeeper addresses for servicegroup service in the
+# format of host1:port,host2:port,host3:port (string value)
+#address=<None>
+
+# recv_timeout parameter for the zk session (integer value)
+#recv_timeout=4000
+
+# The prefix used in ZooKeeper to store ephemeral nodes
+# (string value)
+#sg_prefix=/servicegroups
+
+# Number of seconds to wait until retrying to join the session
+# (integer value)
+#sg_retry_interval=5
+
+
[baremetal]
#
@@ -2567,6 +2764,28 @@
# Template file for PXE configuration (string value)
#pxe_config_template=$pybasedir/nova/virt/baremetal/pxe_config.template
+# Timeout for PXE deployments. Default: 0 (unlimited) (integer
+# value)
+#pxe_deploy_timeout=0
+
+
+#
+# Options defined in nova.virt.baremetal.virtual_power_driver
+#
+
+# ip or name to virtual power host (string value)
+#virtual_power_ssh_host=
+
+# base command to use for virtual power(vbox,virsh) (string
+# value)
+#virtual_power_type=vbox
+
+# user to execute virtual power commands as (string value)
+#virtual_power_host_user=
+
+# password for virtual power host_user (string value)
+#virtual_power_host_pass=
+
#
# Options defined in nova.virt.baremetal.volume_driver
@@ -2656,4 +2875,4 @@
#keymap=en-us
-# Total option count: 543
+# Total option count: 584
diff --git a/nova/api/auth.py b/nova/api/auth.py
index 04bb34066..cc8264567 100644
--- a/nova/api/auth.py
+++ b/nova/api/auth.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC
+# Copyright (c) 2011 OpenStack Foundation
#
# 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/api/ec2/__init__.py b/nova/api/ec2/__init__.py
index 397190fae..7ce18685b 100644
--- a/nova/api/ec2/__init__.py
+++ b/nova/api/ec2/__init__.py
@@ -32,12 +32,12 @@ from nova.api.ec2 import apirequest
from nova.api.ec2 import ec2utils
from nova.api.ec2 import faults
from nova.api import validator
-from nova.common import memorycache
from nova import context
from nova import exception
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
+from nova.openstack.common import memorycache
from nova.openstack.common import timeutils
from nova import utils
from nova import wsgi
@@ -442,7 +442,7 @@ class Validator(wsgi.Middleware):
'image_id': validator.validate_ec2_id,
'attribute': validator.validate_str(),
'image_location': validator.validate_image_path,
- 'public_ip': validator.validate_ipv4,
+ 'public_ip': utils.is_valid_ipv4,
'region_name': validator.validate_str(),
'group_name': validator.validate_str(max_length=255),
'group_description': validator.validate_str(max_length=255),
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index dcbde3428..6bc5185bf 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -503,9 +503,17 @@ class CloudController(object):
r['groups'] = []
r['ipRanges'] = []
if rule['group_id']:
- source_group = rule['grantee_group']
- r['groups'] += [{'groupName': source_group['name'],
- 'userId': source_group['project_id']}]
+ if rule.get('grantee_group'):
+ source_group = rule['grantee_group']
+ r['groups'] += [{'groupName': source_group['name'],
+ 'userId': source_group['project_id']}]
+ else:
+ # rule is not always joined with grantee_group
+ # for example when using quantum driver.
+ source_group = self.security_group_api.get(
+ context, id=rule['group_id'])
+ r['groups'] += [{'groupName': source_group.get('name'),
+ 'userId': source_group.get('project_id')}]
if rule['protocol']:
r['ipProtocol'] = rule['protocol'].lower()
r['fromPort'] = rule['from_port']
@@ -1692,13 +1700,13 @@ class EC2SecurityGroupExceptions(object):
pass
-class CloudSecurityGroupNovaAPI(compute_api.SecurityGroupAPI,
- EC2SecurityGroupExceptions):
+class CloudSecurityGroupNovaAPI(EC2SecurityGroupExceptions,
+ compute_api.SecurityGroupAPI):
pass
-class CloudSecurityGroupQuantumAPI(quantum_driver.SecurityGroupAPI,
- EC2SecurityGroupExceptions):
+class CloudSecurityGroupQuantumAPI(EC2SecurityGroupExceptions,
+ quantum_driver.SecurityGroupAPI):
pass
diff --git a/nova/api/metadata/__init__.py b/nova/api/metadata/__init__.py
index cf0e1e320..f3d0c88ac 100644
--- a/nova/api/metadata/__init__.py
+++ b/nova/api/metadata/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack, LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/api/metadata/handler.py b/nova/api/metadata/handler.py
index 7cccbc324..bbaeba524 100644
--- a/nova/api/metadata/handler.py
+++ b/nova/api/metadata/handler.py
@@ -26,10 +26,10 @@ import webob.dec
import webob.exc
from nova.api.metadata import base
-from nova.common import memorycache
from nova import conductor
from nova import exception
from nova.openstack.common import log as logging
+from nova.openstack.common import memorycache
from nova import wsgi
CACHE_EXPIRATION = 15 # in seconds
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py
index 979aa74b6..67d77f5a6 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/auth.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index 8b880720b..c6473a648 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/consoles.py b/nova/api/openstack/compute/consoles.py
index 613a375f2..f9c30943a 100644
--- a/nova/api/openstack/compute/consoles.py
+++ b/nova/api/openstack/compute/consoles.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/admin_actions.py b/nova/api/openstack/compute/contrib/admin_actions.py
index a3f68e828..8e5863706 100644
--- a/nova/api/openstack/compute/contrib/admin_actions.py
+++ b/nova/api/openstack/compute/contrib/admin_actions.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack, LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/agents.py b/nova/api/openstack/compute/contrib/agents.py
index 6590deafe..1ea92b4de 100644
--- a/nova/api/openstack/compute/contrib/agents.py
+++ b/nova/api/openstack/compute/contrib/agents.py
@@ -1,7 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
diff --git a/nova/api/openstack/compute/contrib/availability_zone.py b/nova/api/openstack/compute/contrib/availability_zone.py
index c79556839..f5092010c 100644
--- a/nova/api/openstack/compute/contrib/availability_zone.py
+++ b/nova/api/openstack/compute/contrib/availability_zone.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/cells.py b/nova/api/openstack/compute/contrib/cells.py
index 8e31777e2..efd2cd189 100644
--- a/nova/api/openstack/compute/contrib/cells.py
+++ b/nova/api/openstack/compute/contrib/cells.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011-2012 OpenStack LLC.
+# Copyright 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/certificates.py b/nova/api/openstack/compute/contrib/certificates.py
index d2ce7bc5d..2d8e8ad6d 100644
--- a/nova/api/openstack/compute/contrib/certificates.py
+++ b/nova/api/openstack/compute/contrib/certificates.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/cloudpipe.py b/nova/api/openstack/compute/contrib/cloudpipe.py
index 20ae87fe1..01e6f8303 100644
--- a/nova/api/openstack/compute/contrib/cloudpipe.py
+++ b/nova/api/openstack/compute/contrib/cloudpipe.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack, LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/cloudpipe_update.py b/nova/api/openstack/compute/contrib/cloudpipe_update.py
index f6ed7bb3a..a096c7107 100644
--- a/nova/api/openstack/compute/contrib/cloudpipe_update.py
+++ b/nova/api/openstack/compute/contrib/cloudpipe_update.py
@@ -1,7 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
diff --git a/nova/api/openstack/compute/contrib/config_drive.py b/nova/api/openstack/compute/contrib/config_drive.py
index 5f1f7b16d..f0b3de5ed 100644
--- a/nova/api/openstack/compute/contrib/config_drive.py
+++ b/nova/api/openstack/compute/contrib/config_drive.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/console_output.py b/nova/api/openstack/compute/contrib/console_output.py
index 60594cb53..2cfa6e447 100644
--- a/nova/api/openstack/compute/contrib/console_output.py
+++ b/nova/api/openstack/compute/contrib/console_output.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2011 Grid Dynamics
# Copyright 2011 Eldar Nugaev, Kirill Shileev, Ilya Alekseyev
#
diff --git a/nova/api/openstack/compute/contrib/consoles.py b/nova/api/openstack/compute/contrib/consoles.py
index 4895a9e7b..264f0b270 100644
--- a/nova/api/openstack/compute/contrib/consoles.py
+++ b/nova/api/openstack/compute/contrib/consoles.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/coverage_ext.py b/nova/api/openstack/compute/contrib/coverage_ext.py
index 6edf9244f..bafb6711e 100644
--- a/nova/api/openstack/compute/contrib/coverage_ext.py
+++ b/nova/api/openstack/compute/contrib/coverage_ext.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
@@ -19,10 +19,12 @@
import os
import re
+import socket
import sys
import telnetlib
import tempfile
+from oslo.config import cfg
from webob import exc
from nova.api.openstack import extensions
@@ -39,13 +41,13 @@ from nova.scheduler import rpcapi as scheduler_api
LOG = logging.getLogger(__name__)
authorize = extensions.extension_authorizer('compute', 'coverage_ext')
+CONF = cfg.CONF
class CoverageController(object):
"""The Coverage report API controller for the OpenStack API."""
def __init__(self):
self.data_path = tempfile.mkdtemp(prefix='nova-coverage_')
- data_out = os.path.join(self.data_path, '.nova-coverage')
self.compute_api = compute_api.API()
self.network_api = network_api.API()
self.conductor_api = conductor_api.API()
@@ -55,18 +57,25 @@ class CoverageController(object):
self.cert_api = cert_api.CertAPI()
self.services = []
self.combine = False
- try:
- import coverage
- self.coverInst = coverage.coverage(data_file=data_out)
- self.has_coverage = True
- except ImportError:
- self.has_coverage = False
+ self._cover_inst = None
+ self.host = CONF.host
super(CoverageController, self).__init__()
+ @property
+ def coverInst(self):
+ if not self._cover_inst:
+ try:
+ import coverage
+ data_out = os.path.join(self.data_path, '.nova-coverage')
+ self._cover_inst = coverage.coverage(data_file=data_out)
+ except ImportError:
+ pass
+ return self._cover_inst
+
def _find_services(self, req):
"""Returns a list of services."""
context = req.environ['nova.context']
- services = db.service_get_all(context, False)
+ services = db.service_get_all(context)
hosts = []
for serv in services:
hosts.append({"service": serv["topic"], "host": serv["host"]})
@@ -109,14 +118,13 @@ class CoverageController(object):
return ports
def _start_coverage_telnet(self, tn, service):
+ data_file = os.path.join(self.data_path,
+ '.nova-coverage.%s' % str(service))
tn.write('import sys\n')
tn.write('from coverage import coverage\n')
- if self.combine:
- data_file = os.path.join(self.data_path,
- '.nova-coverage.%s' % str(service))
- tn.write("coverInst = coverage(data_file='%s')\n)" % data_file)
- else:
- tn.write('coverInst = coverage()\n')
+ tn.write("coverInst = coverage(data_file='%s') "
+ "if 'coverInst' not in locals() "
+ "else coverInst\n" % data_file)
tn.write('coverInst.skipModules = sys.modules.keys()\n')
tn.write("coverInst.start()\n")
tn.write("print 'finished'\n")
@@ -135,8 +143,21 @@ class CoverageController(object):
ports = self._find_ports(req, hosts)
self.services = []
for service in ports:
- service['telnet'] = telnetlib.Telnet(service['host'],
- service['port'])
+ try:
+ service['telnet'] = telnetlib.Telnet(service['host'],
+ service['port'])
+ # NOTE(mtreinish): Fallback to try connecting to lo if
+ # ECONNREFUSED is raised. If using the hostname that is returned
+ # for the service from the service_get_all() DB query raises
+ # ECONNREFUSED it most likely means that the hostname in the DB
+ # doesn't resolve to 127.0.0.1. Currently backdoors only open on
+ # loopback so this is for covering the common single host use case
+ except socket.error as e:
+ if 'ECONNREFUSED' in e and service['host'] == self.host:
+ service['telnet'] = telnetlib.Telnet('127.0.0.1',
+ service['port'])
+ else:
+ raise e
self.services.append(service)
self._start_coverage_telnet(service['telnet'], service['service'])
@@ -242,7 +263,7 @@ class CoverageController(object):
'report': self._report_coverage,
}
authorize(req.environ['nova.context'])
- if not self.has_coverage:
+ if not self.coverInst:
msg = _("Python coverage module is not installed.")
raise exc.HTTPServiceUnavailable(explanation=msg)
for action, data in body.iteritems():
diff --git a/nova/api/openstack/compute/contrib/createserverext.py b/nova/api/openstack/compute/contrib/createserverext.py
index db9838c98..337fedae6 100644
--- a/nova/api/openstack/compute/contrib/createserverext.py
+++ b/nova/api/openstack/compute/contrib/createserverext.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/deferred_delete.py b/nova/api/openstack/compute/contrib/deferred_delete.py
index 94bf63ab4..122fc7035 100644
--- a/nova/api/openstack/compute/contrib/deferred_delete.py
+++ b/nova/api/openstack/compute/contrib/deferred_delete.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack, LLC
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/disk_config.py b/nova/api/openstack/compute/contrib/disk_config.py
index 4a8fe9ce5..2c4d24332 100644
--- a/nova/api/openstack/compute/contrib/disk_config.py
+++ b/nova/api/openstack/compute/contrib/disk_config.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/evacuate.py b/nova/api/openstack/compute/contrib/evacuate.py
index 4c9229d1e..7877fa1fd 100644
--- a/nova/api/openstack/compute/contrib/evacuate.py
+++ b/nova/api/openstack/compute/contrib/evacuate.py
@@ -1,4 +1,4 @@
-# Copyright 2013 OpenStack, LLC.
+# Copyright 2013 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/extended_availability_zone.py b/nova/api/openstack/compute/contrib/extended_availability_zone.py
index 734ddf7c8..af557219f 100644
--- a/nova/api/openstack/compute/contrib/extended_availability_zone.py
+++ b/nova/api/openstack/compute/contrib/extended_availability_zone.py
@@ -21,8 +21,8 @@ from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
from nova import availability_zones
-from nova.common import memorycache
from nova.openstack.common import log as logging
+from nova.openstack.common import memorycache
LOG = logging.getLogger(__name__)
# NOTE(vish): azs don't change that often, so cache them for an hour to
diff --git a/nova/api/openstack/compute/contrib/extended_server_attributes.py b/nova/api/openstack/compute/contrib/extended_server_attributes.py
index 51fd7f375..dd332ff13 100644
--- a/nova/api/openstack/compute/contrib/extended_server_attributes.py
+++ b/nova/api/openstack/compute/contrib/extended_server_attributes.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack, LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/extended_status.py b/nova/api/openstack/compute/contrib/extended_status.py
index 8a7c67f18..930893b27 100644
--- a/nova/api/openstack/compute/contrib/extended_status.py
+++ b/nova/api/openstack/compute/contrib/extended_status.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack, LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/fixed_ips.py b/nova/api/openstack/compute/contrib/fixed_ips.py
index e70416bac..6f0a36888 100644
--- a/nova/api/openstack/compute/contrib/fixed_ips.py
+++ b/nova/api/openstack/compute/contrib/fixed_ips.py
@@ -1,7 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
diff --git a/nova/api/openstack/compute/contrib/flavor_access.py b/nova/api/openstack/compute/contrib/flavor_access.py
index 744fea13b..ec5937094 100644
--- a/nova/api/openstack/compute/contrib/flavor_access.py
+++ b/nova/api/openstack/compute/contrib/flavor_access.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/flavorextradata.py b/nova/api/openstack/compute/contrib/flavorextradata.py
index 8f9640c98..313b83b5d 100644
--- a/nova/api/openstack/compute/contrib/flavorextradata.py
+++ b/nova/api/openstack/compute/contrib/flavorextradata.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack, LLC
+# Copyright 2012 OpenStack Foundation
# Copyright 2011 Canonical Ltd.
# All Rights Reserved.
#
diff --git a/nova/api/openstack/compute/contrib/floating_ip_dns.py b/nova/api/openstack/compute/contrib/floating_ip_dns.py
index bddf3580c..5caea9ffa 100644
--- a/nova/api/openstack/compute/contrib/floating_ip_dns.py
+++ b/nova/api/openstack/compute/contrib/floating_ip_dns.py
@@ -14,7 +14,6 @@
# License for the specific language governing permissions and limitations
# under the License
-import socket
import urllib
import webob
@@ -25,6 +24,7 @@ from nova.api.openstack import xmlutil
from nova import exception
from nova import network
from nova.openstack.common import log as logging
+from nova import utils
LOG = logging.getLogger(__name__)
@@ -210,15 +210,8 @@ class FloatingIPDNSEntryController(object):
floating_ip = None
# Check whether id is a valid ipv4/ipv6 address.
- try:
- socket.inet_pton(socket.AF_INET, id)
+ if utils.is_valid_ipv4(id) or utils.is_valid_ipv6(id):
floating_ip = id
- except socket.error:
- try:
- socket.inet_pton(socket.AF_INET6, id)
- floating_ip = id
- except socket.error:
- pass
if floating_ip:
entries = self.network_api.get_dns_entries_by_address(context,
diff --git a/nova/api/openstack/compute/contrib/floating_ips.py b/nova/api/openstack/compute/contrib/floating_ips.py
index f7c1100a5..bf1246ccb 100644
--- a/nova/api/openstack/compute/contrib/floating_ips.py
+++ b/nova/api/openstack/compute/contrib/floating_ips.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
# Copyright 2011 Grid Dynamics
# Copyright 2011 Eldar Nugaev, Kirill Shileev, Ilya Alekseyev
@@ -294,7 +294,9 @@ class FloatingIPActionController(wsgi.Controller):
disassociate_floating_ip(self, context, instance, address)
return webob.Response(status_int=202)
else:
- return webob.Response(status_int=404)
+ msg = _("Floating ip %(address)s is not associated with instance "
+ "%(id)s.") % locals()
+ raise webob.exc.HTTPUnprocessableEntity(explanation=msg)
class Floating_ips(extensions.ExtensionDescriptor):
diff --git a/nova/api/openstack/compute/contrib/floating_ips_bulk.py b/nova/api/openstack/compute/contrib/floating_ips_bulk.py
index afd42e12f..e6a7fecee 100644
--- a/nova/api/openstack/compute/contrib/floating_ips_bulk.py
+++ b/nova/api/openstack/compute/contrib/floating_ips_bulk.py
@@ -1,7 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
diff --git a/nova/api/openstack/compute/contrib/fping.py b/nova/api/openstack/compute/contrib/fping.py
index 394d5924e..e1a8dfb8c 100644
--- a/nova/api/openstack/compute/contrib/fping.py
+++ b/nova/api/openstack/compute/contrib/fping.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 Grid Dynamics
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/hide_server_addresses.py b/nova/api/openstack/compute/contrib/hide_server_addresses.py
index 4d8bcd94e..08e33ce53 100644
--- a/nova/api/openstack/compute/contrib/hide_server_addresses.py
+++ b/nova/api/openstack/compute/contrib/hide_server_addresses.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/hosts.py b/nova/api/openstack/compute/contrib/hosts.py
index a3cfd229c..3ecfb9965 100644
--- a/nova/api/openstack/compute/contrib/hosts.py
+++ b/nova/api/openstack/compute/contrib/hosts.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/hypervisors.py b/nova/api/openstack/compute/contrib/hypervisors.py
index 7e477bbf3..28cb0f291 100644
--- a/nova/api/openstack/compute/contrib/hypervisors.py
+++ b/nova/api/openstack/compute/contrib/hypervisors.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/instance_usage_audit_log.py b/nova/api/openstack/compute/contrib/instance_usage_audit_log.py
index d6ffe3677..3c3aa23c0 100644
--- a/nova/api/openstack/compute/contrib/instance_usage_audit_log.py
+++ b/nova/api/openstack/compute/contrib/instance_usage_audit_log.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/keypairs.py b/nova/api/openstack/compute/contrib/keypairs.py
index ef93fb048..a79b39aae 100644
--- a/nova/api/openstack/compute/contrib/keypairs.py
+++ b/nova/api/openstack/compute/contrib/keypairs.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -119,7 +119,10 @@ class KeypairController(object):
context = req.environ['nova.context']
authorize(context)
- keypair = self.api.get_key_pair(context, context.user_id, id)
+ try:
+ keypair = self.api.get_key_pair(context, context.user_id, id)
+ except exception.KeypairNotFound:
+ raise webob.exc.HTTPNotFound()
return {'keypair': keypair}
@wsgi.serializers(xml=KeypairsTemplate)
diff --git a/nova/api/openstack/compute/contrib/multinic.py b/nova/api/openstack/compute/contrib/multinic.py
index 7017422a1..30789a3f1 100644
--- a/nova/api/openstack/compute/contrib/multinic.py
+++ b/nova/api/openstack/compute/contrib/multinic.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/multiple_create.py b/nova/api/openstack/compute/contrib/multiple_create.py
index cbad2d439..fd450b6d8 100644
--- a/nova/api/openstack/compute/contrib/multiple_create.py
+++ b/nova/api/openstack/compute/contrib/multiple_create.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/os_networks.py b/nova/api/openstack/compute/contrib/os_networks.py
index bef2c3d1f..c6268f277 100644
--- a/nova/api/openstack/compute/contrib/os_networks.py
+++ b/nova/api/openstack/compute/contrib/os_networks.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 Grid Dynamics
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/os_tenant_networks.py b/nova/api/openstack/compute/contrib/os_tenant_networks.py
index c22e64b1f..5268ecd64 100644
--- a/nova/api/openstack/compute/contrib/os_tenant_networks.py
+++ b/nova/api/openstack/compute/contrib/os_tenant_networks.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/quota_classes.py b/nova/api/openstack/compute/contrib/quota_classes.py
index 7b94e45b1..361748df8 100644
--- a/nova/api/openstack/compute/contrib/quota_classes.py
+++ b/nova/api/openstack/compute/contrib/quota_classes.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/quotas.py b/nova/api/openstack/compute/contrib/quotas.py
index b1a461431..ddfe5bf08 100644
--- a/nova/api/openstack/compute/contrib/quotas.py
+++ b/nova/api/openstack/compute/contrib/quotas.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/rescue.py b/nova/api/openstack/compute/contrib/rescue.py
index c62ed5894..b6cf3a918 100644
--- a/nova/api/openstack/compute/contrib/rescue.py
+++ b/nova/api/openstack/compute/contrib/rescue.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack, LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/scheduler_hints.py b/nova/api/openstack/compute/contrib/scheduler_hints.py
index 5e54fbd37..637698b31 100644
--- a/nova/api/openstack/compute/contrib/scheduler_hints.py
+++ b/nova/api/openstack/compute/contrib/scheduler_hints.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/security_groups.py b/nova/api/openstack/compute/contrib/security_groups.py
index 092e89b9b..af97a2a6b 100644
--- a/nova/api/openstack/compute/contrib/security_groups.py
+++ b/nova/api/openstack/compute/contrib/security_groups.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2012 Justin Santa Barbara
# All Rights Reserved.
#
@@ -622,11 +622,11 @@ class NativeSecurityGroupExceptions(object):
raise exc.HTTPNotFound(explanation=msg)
-class NativeNovaSecurityGroupAPI(compute_api.SecurityGroupAPI,
- NativeSecurityGroupExceptions):
+class NativeNovaSecurityGroupAPI(NativeSecurityGroupExceptions,
+ compute_api.SecurityGroupAPI):
pass
-class NativeQuantumSecurityGroupAPI(quantum_driver.SecurityGroupAPI,
- NativeSecurityGroupExceptions):
+class NativeQuantumSecurityGroupAPI(NativeSecurityGroupExceptions,
+ quantum_driver.SecurityGroupAPI):
pass
diff --git a/nova/api/openstack/compute/contrib/server_diagnostics.py b/nova/api/openstack/compute/contrib/server_diagnostics.py
index 1be4b664c..7711eb653 100644
--- a/nova/api/openstack/compute/contrib/server_diagnostics.py
+++ b/nova/api/openstack/compute/contrib/server_diagnostics.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/services.py b/nova/api/openstack/compute/contrib/services.py
index 0f91bf13f..3afd5ff45 100644
--- a/nova/api/openstack/compute/contrib/services.py
+++ b/nova/api/openstack/compute/contrib/services.py
@@ -1,7 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
diff --git a/nova/api/openstack/compute/contrib/simple_tenant_usage.py b/nova/api/openstack/compute/contrib/simple_tenant_usage.py
index f219689f7..f759e90b0 100644
--- a/nova/api/openstack/compute/contrib/simple_tenant_usage.py
+++ b/nova/api/openstack/compute/contrib/simple_tenant_usage.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/contrib/used_limits.py b/nova/api/openstack/compute/contrib/used_limits.py
index a5e0b378b..df40fe91a 100644
--- a/nova/api/openstack/compute/contrib/used_limits.py
+++ b/nova/api/openstack/compute/contrib/used_limits.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/api/openstack/compute/contrib/user_data.py b/nova/api/openstack/compute/contrib/user_data.py
index 1f58c102d..3e69a65cc 100644
--- a/nova/api/openstack/compute/contrib/user_data.py
+++ b/nova/api/openstack/compute/contrib/user_data.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/api/openstack/compute/extensions.py b/nova/api/openstack/compute/extensions.py
index 4e49482f5..5e6633f1d 100644
--- a/nova/api/openstack/compute/extensions.py
+++ b/nova/api/openstack/compute/extensions.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/flavors.py b/nova/api/openstack/compute/flavors.py
index 8aa57a2b1..a0d33abd4 100644
--- a/nova/api/openstack/compute/flavors.py
+++ b/nova/api/openstack/compute/flavors.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/image_metadata.py b/nova/api/openstack/compute/image_metadata.py
index 7e78d6324..65ed72a23 100644
--- a/nova/api/openstack/compute/image_metadata.py
+++ b/nova/api/openstack/compute/image_metadata.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/images.py b/nova/api/openstack/compute/images.py
index 703d2fe2d..82db21c9e 100644
--- a/nova/api/openstack/compute/images.py
+++ b/nova/api/openstack/compute/images.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/ips.py b/nova/api/openstack/compute/ips.py
index 7b196d956..ee917e65e 100644
--- a/nova/api/openstack/compute/ips.py
+++ b/nova/api/openstack/compute/ips.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/limits.py b/nova/api/openstack/compute/limits.py
index 767280a45..2f69d5737 100644
--- a/nova/api/openstack/compute/limits.py
+++ b/nova/api/openstack/compute/limits.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/server_metadata.py b/nova/api/openstack/compute/server_metadata.py
index 0de5d536f..7dc6b0194 100644
--- a/nova/api/openstack/compute/server_metadata.py
+++ b/nova/api/openstack/compute/server_metadata.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py
index cc33537af..3464cfdbd 100644
--- a/nova/api/openstack/compute/servers.py
+++ b/nova/api/openstack/compute/servers.py
@@ -1,4 +1,4 @@
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# Copyright 2011 Piston Cloud Computing, Inc
# All Rights Reserved.
#
@@ -17,7 +17,6 @@
import base64
import os
import re
-import socket
from oslo.config import cfg
import webob
@@ -704,16 +703,12 @@ class Controller(wsgi.Controller):
raise exc.HTTPBadRequest(explanation=expl)
def _validate_access_ipv4(self, address):
- try:
- socket.inet_aton(address)
- except socket.error:
+ if not utils.is_valid_ipv4(address):
expl = _('accessIPv4 is not proper IPv4 format')
raise exc.HTTPBadRequest(explanation=expl)
def _validate_access_ipv6(self, address):
- try:
- socket.inet_pton(socket.AF_INET6, address)
- except socket.error:
+ if not utils.is_valid_ipv6(address):
expl = _('accessIPv6 is not proper IPv6 format')
raise exc.HTTPBadRequest(explanation=expl)
@@ -830,7 +825,7 @@ class Controller(wsgi.Controller):
max_count = server_dict.get('max_count', min_count)
try:
- min_count = int(min_count)
+ min_count = int(str(min_count))
except ValueError:
msg = _('min_count must be an integer value')
raise exc.HTTPBadRequest(explanation=msg)
@@ -839,7 +834,7 @@ class Controller(wsgi.Controller):
raise exc.HTTPBadRequest(explanation=msg)
try:
- max_count = int(max_count)
+ max_count = int(str(max_count))
except ValueError:
msg = _('max_count must be an integer value')
raise exc.HTTPBadRequest(explanation=msg)
diff --git a/nova/api/openstack/compute/versions.py b/nova/api/openstack/compute/versions.py
index 5c416908e..0d2117053 100644
--- a/nova/api/openstack/compute/versions.py
+++ b/nova/api/openstack/compute/versions.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/views/addresses.py b/nova/api/openstack/compute/views/addresses.py
index e1d75a9aa..fd9c3d25e 100644
--- a/nova/api/openstack/compute/views/addresses.py
+++ b/nova/api/openstack/compute/views/addresses.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/views/flavors.py b/nova/api/openstack/compute/views/flavors.py
index fbbe5c45e..6cfb114e0 100644
--- a/nova/api/openstack/compute/views/flavors.py
+++ b/nova/api/openstack/compute/views/flavors.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/views/images.py b/nova/api/openstack/compute/views/images.py
index 6438f0aa9..cc0718a4e 100644
--- a/nova/api/openstack/compute/views/images.py
+++ b/nova/api/openstack/compute/views/images.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/views/limits.py b/nova/api/openstack/compute/views/limits.py
index 4ccf40de7..8ef49afd7 100644
--- a/nova/api/openstack/compute/views/limits.py
+++ b/nova/api/openstack/compute/views/limits.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/compute/views/servers.py b/nova/api/openstack/compute/views/servers.py
index 939515468..165d363a4 100644
--- a/nova/api/openstack/compute/views/servers.py
+++ b/nova/api/openstack/compute/views/servers.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# Copyright 2011 Piston Cloud Computing, Inc.
# All Rights Reserved.
#
diff --git a/nova/api/openstack/compute/views/versions.py b/nova/api/openstack/compute/views/versions.py
index 105921ff0..7e8d15f0b 100644
--- a/nova/api/openstack/compute/views/versions.py
+++ b/nova/api/openstack/compute/views/versions.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py
index 94ce76ec7..b2cdacd1e 100644
--- a/nova/api/openstack/extensions.py
+++ b/nova/api/openstack/extensions.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2011 Justin Santa Barbara
# All Rights Reserved.
#
diff --git a/nova/api/openstack/urlmap.py b/nova/api/openstack/urlmap.py
index aa49226b3..d67b66c4d 100644
--- a/nova/api/openstack/urlmap.py
+++ b/nova/api/openstack/urlmap.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index 8c77f1c9c..5b9900f72 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -878,9 +878,6 @@ class Resource(wsgi.Application):
def __call__(self, request):
"""WSGI method that controls (de)serialization and method dispatch."""
- LOG.info("%(method)s %(url)s" % {"method": request.method,
- "url": request.url})
-
# Identify the action, its arguments, and the requested
# content type
action_args = self.get_action_args(request.environ)
@@ -923,7 +920,7 @@ class Resource(wsgi.Application):
return Fault(webob.exc.HTTPBadRequest(explanation=msg))
if body:
- LOG.info(_("Action: '%(action)s', body: %(body)s") % locals())
+ LOG.debug(_("Action: '%(action)s', body: %(body)s") % locals())
LOG.debug(_("Calling method %s") % meth)
# Now, deserialize the request body...
@@ -988,15 +985,6 @@ class Resource(wsgi.Application):
response = resp_obj.serialize(request, accept,
self.default_serializers)
- try:
- msg_dict = dict(url=request.url, status=response.status_int)
- msg = _("%(url)s returned with HTTP %(status)d") % msg_dict
- except AttributeError, e:
- msg_dict = dict(url=request.url, e=e)
- msg = _("%(url)s returned a fault: %(e)s") % msg_dict
-
- LOG.info(msg)
-
return response
def get_method(self, request, action, content_type, body):
diff --git a/nova/api/openstack/xmlutil.py b/nova/api/openstack/xmlutil.py
index 290732759..a2f5b7506 100644
--- a/nova/api/openstack/xmlutil.py
+++ b/nova/api/openstack/xmlutil.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/api/sizelimit.py b/nova/api/sizelimit.py
index 1e88f183e..f1bf3cf1b 100644
--- a/nova/api/sizelimit.py
+++ b/nova/api/sizelimit.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
#
# 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/api/validator.py b/nova/api/validator.py
index 9304387fd..2e7356391 100644
--- a/nova/api/validator.py
+++ b/nova/api/validator.py
@@ -18,7 +18,6 @@
import base64
import re
-import socket
from nova.openstack.common import log as logging
@@ -94,14 +93,6 @@ def validate_image_path(val):
return True
-def validate_ipv4(addr):
- try:
- socket.inet_aton(addr)
- except (socket.error, TypeError):
- return False
- return True
-
-
def validate_user_data(user_data):
"""Check if the user_data is encoded properly."""
try:
diff --git a/nova/availability_zones.py b/nova/availability_zones.py
index 61486517d..45b790081 100644
--- a/nova/availability_zones.py
+++ b/nova/availability_zones.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/cells/messaging.py b/nova/cells/messaging.py
index db49cc8fd..f83f141dc 100644
--- a/nova/cells/messaging.py
+++ b/nova/cells/messaging.py
@@ -784,8 +784,13 @@ class _BroadcastMessageMethods(_BaseMessageMethods):
# if we actually want this code to remain..
self.db.instance_create(message.ctxt, instance)
if info_cache:
- self.db.instance_info_cache_update(message.ctxt, instance_uuid,
- info_cache, update_cells=False)
+ try:
+ self.db.instance_info_cache_update(message.ctxt,
+ instance_uuid, info_cache, update_cells=False)
+ except exception.InstanceInfoCacheNotFound:
+ # Can happen if we try to update a deleted instance's
+ # network information.
+ pass
def instance_destroy_at_top(self, message, instance, **kwargs):
"""Destroy an instance from the DB if we're a top level cell."""
diff --git a/nova/cert/__init__.py b/nova/cert/__init__.py
index 74cec6938..74704e5e6 100644
--- a/nova/cert/__init__.py
+++ b/nova/cert/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack, LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/cert/manager.py b/nova/cert/manager.py
index d1ffbd5a7..de959c8e7 100644
--- a/nova/cert/manager.py
+++ b/nova/cert/manager.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack, LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/compute/api.py b/nova/compute/api.py
index d45ee6703..76d4d06ba 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -332,6 +332,19 @@ class API(base.Base):
LOG.warn(msg)
raise exception.InvalidMetadataSize(reason=msg)
+ def _check_requested_secgroups(self, context, secgroups):
+ """
+ Check if the security group requested exists and belongs to
+ the project.
+ """
+ for secgroup in secgroups:
+ # NOTE(sdague): default is handled special
+ if secgroup == "default":
+ continue
+ if not self.security_group_api.get(context, secgroup):
+ raise exception.SecurityGroupNotFoundForProject(
+ project_id=context.project_id, security_group_id=secgroup)
+
def _check_requested_networks(self, context, requested_networks):
"""
Check if the networks requested belongs to the project
@@ -447,7 +460,7 @@ class API(base.Base):
image_href, kernel_id, ramdisk_id,
min_count, max_count,
display_name, display_description,
- key_name, key_data, security_group,
+ key_name, key_data, security_groups,
availability_zone, user_data,
metadata, injected_files,
access_ip_v4, access_ip_v6,
@@ -460,8 +473,8 @@ class API(base.Base):
if not metadata:
metadata = {}
- if not security_group:
- security_group = 'default'
+ if not security_groups:
+ security_groups = ['default']
if not instance_type:
instance_type = instance_types.get_default_instance_type()
@@ -504,6 +517,7 @@ class API(base.Base):
self._check_metadata_properties_quota(context, metadata)
self._check_injected_file_quota(context, injected_files)
+ self._check_requested_secgroups(context, security_groups)
self._check_requested_networks(context, requested_networks)
if image_href:
@@ -597,7 +611,8 @@ class API(base.Base):
options = base_options.copy()
instance = self.create_db_entry_for_new_instance(
context, instance_type, image, options,
- security_group, block_device_mapping, num_instances, i)
+ security_groups, block_device_mapping,
+ num_instances, i)
instances.append(instance)
instance_uuids.append(instance['uuid'])
@@ -626,7 +641,7 @@ class API(base.Base):
'instance_type': instance_type,
'instance_uuids': instance_uuids,
'block_device_mapping': block_device_mapping,
- 'security_group': security_group,
+ 'security_group': security_groups,
}
return (instances, request_spec, filter_properties)
@@ -776,21 +791,18 @@ class API(base.Base):
def _populate_instance_for_bdm(self, context, instance, instance_type,
image, block_device_mapping):
"""Populate instance block device mapping information."""
- # FIXME(comstud): Why do the block_device_mapping DB calls
- # require elevated context?
- elevated = context.elevated()
instance_uuid = instance['uuid']
image_properties = image.get('properties', {})
mappings = image_properties.get('mappings', [])
if mappings:
- self._update_image_block_device_mapping(elevated,
+ self._update_image_block_device_mapping(context,
instance_type, instance_uuid, mappings)
image_bdm = image_properties.get('block_device_mapping', [])
for mapping in (image_bdm, block_device_mapping):
if not mapping:
continue
- self._update_block_device_mapping(elevated,
+ self._update_block_device_mapping(context,
instance_type, instance_uuid, mapping)
def _populate_instance_shutdown_terminate(self, instance, image,
@@ -859,7 +871,6 @@ class API(base.Base):
instance['system_metadata']['image_base_image_ref'] = base_image_ref
self.security_group_api.populate_security_groups(instance,
security_groups)
-
return instance
#NOTE(bcwaldon): No policy check since this is only used by scheduler and
@@ -1069,6 +1080,10 @@ class API(base.Base):
migration_ref)
downsize_reservations = self._reserve_quota_delta(context,
deltas)
+
+ self._record_action_start(context, instance,
+ instance_actions.CONFIRM_RESIZE)
+
self.compute_rpcapi.confirm_resize(context,
instance, migration_ref,
host=src_host, cast=False,
@@ -1308,11 +1323,14 @@ class API(base.Base):
def get(self, context, instance_id):
"""Get a single instance with the given instance_id."""
# NOTE(ameade): we still need to support integer ids for ec2
- if uuidutils.is_uuid_like(instance_id):
- instance = self.db.instance_get_by_uuid(context, instance_id)
- elif utils.is_int_like(instance_id):
- instance = self.db.instance_get(context, instance_id)
- else:
+ try:
+ if uuidutils.is_uuid_like(instance_id):
+ instance = self.db.instance_get_by_uuid(context, instance_id)
+ elif utils.is_int_like(instance_id):
+ instance = self.db.instance_get(context, instance_id)
+ else:
+ raise exception.InstanceNotFound(instance_id=instance_id)
+ except exception.InvalidID:
raise exception.InstanceNotFound(instance_id=instance_id)
check_policy(context, 'get', instance)
@@ -1578,17 +1596,10 @@ class API(base.Base):
mapping = []
for bdm in bdms:
- if bdm.no_device:
+ if bdm['no_device']:
continue
- m = {}
- for attr in ('device_name', 'snapshot_id', 'volume_id',
- 'volume_size', 'delete_on_termination', 'no_device',
- 'virtual_name'):
- val = getattr(bdm, attr)
- if val is not None:
- m[attr] = val
-
- volume_id = m.get('volume_id')
+
+ volume_id = bdm.get('volume_id')
if volume_id:
# create snapshot based on volume_id
volume = self.volume_api.get(context, volume_id)
@@ -1598,11 +1609,10 @@ class API(base.Base):
name = _('snapshot for %s') % image_meta['name']
snapshot = self.volume_api.create_snapshot_force(
context, volume, name, volume['display_description'])
- m['snapshot_id'] = snapshot['id']
- del m['volume_id']
+ bdm['snapshot_id'] = snapshot['id']
+ del bdm['volume_id']
- if m:
- mapping.append(m)
+ mapping.append(bdm)
for m in block_device.mappings_prepend_dev(properties.get('mappings',
[])):
@@ -1644,13 +1654,13 @@ class API(base.Base):
#disk format of vhd is non-shrinkable
if orig_image.get('disk_format') == 'vhd':
- min_ram = instance['instance_type']['memory_mb']
min_disk = instance['instance_type']['root_gb']
else:
#set new image values to the original image values
- min_ram = orig_image.get('min_ram')
min_disk = orig_image.get('min_disk')
+ min_ram = orig_image.get('min_ram')
+
return min_ram, min_disk
def _get_block_device_info(self, context, instance_uuid):
@@ -1677,8 +1687,7 @@ class API(base.Base):
@wrap_check_policy
@check_instance_lock
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.STOPPED,
- vm_states.RESCUED, vm_states.PAUSED,
- vm_states.SUSPENDED],
+ vm_states.PAUSED, vm_states.SUSPENDED],
task_state=[None, task_states.REBOOTING,
task_states.REBOOTING_HARD,
task_states.RESUMING,
@@ -1755,7 +1764,7 @@ class API(base.Base):
"""
Remove old image properties that we're storing as instance
system metadata. These properties start with 'image_'.
- Then add the properites for the new image.
+ Then add the properties for the new image.
"""
# FIXME(comstud): There's a race condition here in that
@@ -2408,7 +2417,7 @@ class API(base.Base):
bdms = self.get_instance_bdms(context, instance)
for bdm in bdms:
- if (block_device.strip_dev(bdm.device_name) ==
+ if (block_device.strip_dev(bdm['device_name']) ==
block_device.strip_dev(instance['root_device_name'])):
return True
else:
@@ -2438,10 +2447,10 @@ class API(base.Base):
raising an exception.
"""
LOG.debug(_('vm evacuation scheduled'))
- host = instance['host']
- service = self.db.service_get_by_compute_host(context, host)
+ inst_host = instance['host']
+ service = self.db.service_get_by_compute_host(context, inst_host)
if self.servicegroup_api.service_is_up(service):
- msg = (_('Instance compute service state on %(host)s '
+ msg = (_('Instance compute service state on %(inst_host)s '
'expected to be down, but it was up.'
) % locals())
LOG.error(msg)
@@ -3001,21 +3010,6 @@ class SecurityGroupAPI(base.Base, security_group_base.SecurityGroupBase):
self.trigger_handler('instance_remove_security_group',
context, instance, security_group_name)
- def rule_exists(self, security_group, new_rule):
- """Indicates whether the specified rule is already
- defined in the given security group.
- """
- for rule in security_group['rules']:
- is_duplicate = True
- keys = ('group_id', 'cidr', 'from_port', 'to_port', 'protocol')
- for key in keys:
- if rule.get(key) != new_rule.get(key):
- is_duplicate = False
- break
- if is_duplicate:
- return rule.get('id') or True
- return False
-
def get_rule(self, context, id):
self.ensure_default(context)
try:
@@ -3108,15 +3102,6 @@ class SecurityGroupAPI(base.Base, security_group_base.SecurityGroupBase):
msg = _("Security group id should be integer")
self.raise_invalid_property(msg)
- def create_security_group_rule(self, context, security_group, new_rule):
- if self.rule_exists(security_group, new_rule):
- msg = (_('This rule already exists in group %s') %
- new_rule['parent_group_id'])
- self.raise_group_already_exists(msg)
- return self.add_rules(context, new_rule['parent_group_id'],
- security_group['name'],
- [new_rule])[0]
-
def trigger_handler(self, event, *args):
handle = getattr(self.sgh, 'trigger_%s_refresh' % event)
handle(*args)
@@ -3174,9 +3159,4 @@ class SecurityGroupAPI(base.Base, security_group_base.SecurityGroupBase):
return [{'name': group['name']} for group in groups]
def populate_security_groups(self, instance, security_groups):
- # Use 'default' security_group if none specified.
- if security_groups is None:
- security_groups = ['default']
- elif not isinstance(security_groups, list):
- security_groups = [security_groups]
instance['security_groups'] = security_groups
diff --git a/nova/compute/cells_api.py b/nova/compute/cells_api.py
index 32f09ee90..d5a07490b 100644
--- a/nova/compute/cells_api.py
+++ b/nova/compute/cells_api.py
@@ -393,18 +393,6 @@ class ComputeCellsAPI(compute_api.API):
super(ComputeCellsAPI, self).unpause(context, instance)
self._cast_to_cells(context, instance, 'unpause')
- def set_host_enabled(self, context, host, enabled):
- """Sets the specified host's ability to accept new instances."""
- # FIXME(comstud): Since there's no instance here, we have no
- # idea which cell should be the target.
- pass
-
- def host_power_action(self, context, host, action):
- """Reboots, shuts down or powers up the host."""
- # FIXME(comstud): Since there's no instance here, we have no
- # idea which cell should be the target.
- pass
-
def get_diagnostics(self, context, instance):
"""Retrieve diagnostics for the given instance."""
# FIXME(comstud): Cache this?
diff --git a/nova/compute/claims.py b/nova/compute/claims.py
index fc534fd23..51717ba18 100644
--- a/nova/compute/claims.py
+++ b/nova/compute/claims.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/compute/instance_actions.py b/nova/compute/instance_actions.py
index cbb517387..32d280128 100644
--- a/nova/compute/instance_actions.py
+++ b/nova/compute/instance_actions.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py
index 73105b33f..3060e0bc2 100644
--- a/nova/compute/instance_types.py
+++ b/nova/compute/instance_types.py
@@ -28,7 +28,7 @@ from oslo.config import cfg
from nova import context
from nova import db
from nova import exception
-from nova.openstack.common.db.sqlalchemy import session as db_session
+from nova.openstack.common.db import exception as db_exc
from nova.openstack.common import log as logging
from nova import utils
@@ -134,7 +134,7 @@ def create(name, memory, vcpus, root_gb, ephemeral_gb=None, flavorid=None,
try:
return db.instance_type_create(context.get_admin_context(), kwargs)
- except db_session.DBError, e:
+ except db_exc.DBError, e:
LOG.exception(_('DB error: %s') % e)
raise exception.InstanceTypeCreateFailed()
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 99b97e921..e172e6ad8 100755
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -68,6 +68,7 @@ from nova.openstack.common import rpc
from nova.openstack.common import timeutils
from nova import paths
from nova import quota
+from nova import safe_utils
from nova.scheduler import rpcapi as scheduler_rpcapi
from nova import utils
from nova.virt import driver
@@ -192,11 +193,11 @@ def reverts_task_state(function):
try:
return function(self, context, *args, **kwargs)
except exception.UnexpectedTaskStateError:
- LOG.exception(_("Possibly task preempted."))
# Note(maoy): unexpected task state means the current
# task is preempted. Do not clear task state in this
# case.
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_("Possibly task preempted."))
except Exception:
with excutils.save_and_reraise_exception():
try:
@@ -247,7 +248,7 @@ def wrap_instance_event(function):
@functools.wraps(function)
def decorated_function(self, context, *args, **kwargs):
wrapped_func = utils.get_wrapped_function(function)
- keyed_args = utils.getcallargs(wrapped_func, context, *args,
+ keyed_args = safe_utils.getcallargs(wrapped_func, context, *args,
**kwargs)
instance_uuid = keyed_args['instance']['uuid']
@@ -314,6 +315,10 @@ class ComputeVirtAPI(virtapi.VirtAPI):
return self._compute.conductor_api.agent_build_get_by_triple(
context, hypervisor, os, architecture)
+ def instance_type_get(self, context, instance_type_id):
+ return self._compute.conductor_api.instance_type_get(context,
+ instance_type_id)
+
class ComputeManager(manager.SchedulerDependentManager):
"""Manages the running instances from creation to destruction."""
@@ -384,21 +389,14 @@ class ComputeManager(manager.SchedulerDependentManager):
"""Return a list of instance records that match the instances found
on the hypervisor.
"""
- local_instances = []
try:
- # Try to find all local instances by uuid.
- # FIXME(comstud): Would be nice to consolidate this into
- # a single query to nova-conductor.
- for uuid in self.driver.list_instance_uuids():
- try:
- instance = self.conductor_api.instance_get_by_uuid(
- context, uuid)
- local_instances.append(instance)
- except exception.InstanceNotFound as e:
- LOG.error(_('Instance %(uuid)s found in the '
- 'hypervisor, but not in the database'),
- locals())
- continue
+ driver_uuids = self.driver.list_instance_uuids()
+ local_instances = self.conductor_api.instance_get_all_by_filters(
+ context, {'uuid': driver_uuids})
+ local_instance_uuids = [inst['uuid'] for inst in local_instances]
+ for uuid in set(driver_uuids) - set(local_instance_uuids):
+ LOG.error(_('Instance %(uuid)s found in the hypervisor, but '
+ 'not in the database'), locals())
return local_instances
except NotImplementedError:
pass
@@ -406,9 +404,9 @@ class ComputeManager(manager.SchedulerDependentManager):
# The driver doesn't support uuids listing, so we'll have
# to brute force.
driver_instances = self.driver.list_instances()
- all_instances = self.conductor_api.instance_get_all(context)
- name_map = dict([(instance['name'], instance)
- for instance in all_instances])
+ instances = self.conductor_api.instance_get_all_by_host(context,
+ self.host)
+ name_map = dict((instance['name'], instance) for instance in instances)
local_instances = []
for driver_instance in driver_instances:
instance = name_map.get(driver_instance)
@@ -448,8 +446,6 @@ class ComputeManager(manager.SchedulerDependentManager):
def _init_instance(self, context, instance):
'''Initialize this instance during service init.'''
- db_state = instance['power_state']
- drv_state = self._get_power_state(context, instance)
closing_vm_states = (vm_states.DELETED,
vm_states.SOFT_DELETED)
@@ -458,12 +454,6 @@ class ComputeManager(manager.SchedulerDependentManager):
if instance['vm_state'] in closing_vm_states:
return
- expect_running = (db_state == power_state.RUNNING and
- drv_state != db_state)
-
- LOG.debug(_('Current state is %(drv_state)s, state in DB is '
- '%(db_state)s.'), locals(), instance=instance)
-
net_info = compute_utils.get_nw_info_for_instance(instance)
# We're calling plug_vifs to ensure bridge and iptables
@@ -471,6 +461,31 @@ class ComputeManager(manager.SchedulerDependentManager):
legacy_net_info = self._legacy_nw_info(net_info)
self.driver.plug_vifs(instance, legacy_net_info)
+ if instance['task_state'] == task_states.RESIZE_MIGRATING:
+ # We crashed during resize/migration, so roll back for safety
+ try:
+ self.driver.finish_revert_migration(
+ instance, self._legacy_nw_info(net_info),
+ self._get_instance_volume_block_device_info(context,
+ instance))
+ except Exception, e:
+ LOG.exception(_('Failed to revert crashed migration'),
+ instance=instance)
+ finally:
+ LOG.info(_('Instance found in migrating state during '
+ 'startup. Resetting task_state'),
+ instance=instance)
+ instance = self._instance_update(context, instance['uuid'],
+ task_state=None)
+
+ db_state = instance['power_state']
+ drv_state = self._get_power_state(context, instance)
+ expect_running = (db_state == power_state.RUNNING and
+ drv_state != db_state)
+
+ LOG.debug(_('Current state is %(drv_state)s, state in DB is '
+ '%(db_state)s.'), locals(), instance=instance)
+
if expect_running and CONF.resume_guests_state_on_host_boot:
LOG.info(
_('Rebooting instance after nova-compute restart.'),
@@ -769,17 +784,30 @@ class ComputeManager(manager.SchedulerDependentManager):
block_device_info = self._prep_block_device(
context, instance, bdms)
+ set_access_ip = (is_first_time and
+ not instance['access_ip_v4'] and
+ not instance['access_ip_v6'])
+
instance = self._spawn(context, instance, image_meta,
network_info, block_device_info,
- injected_files, admin_password)
+ injected_files, admin_password,
+ set_access_ip=set_access_ip)
except exception.InstanceNotFound:
# the instance got deleted during the spawn
- try:
- self._deallocate_network(context, instance)
- except Exception:
- msg = _('Failed to dealloc network for deleted instance')
- LOG.exception(msg, instance=instance)
- raise
+ with excutils.save_and_reraise_exception():
+ try:
+ self._deallocate_network(context, instance)
+ except Exception:
+ msg = _('Failed to dealloc network '
+ 'for deleted instance')
+ LOG.exception(msg, instance=instance)
+ except exception.UnexpectedTaskStateError as e:
+ actual_task_state = e.kwargs.get('actual', None)
+ if actual_task_state == 'deleting':
+ msg = _('Instance was deleted during spawn.')
+ LOG.debug(msg, instance=instance)
+ else:
+ raise
except Exception:
exc_info = sys.exc_info()
# try to re-schedule instance:
@@ -788,11 +816,6 @@ class ComputeManager(manager.SchedulerDependentManager):
is_first_time, request_spec, filter_properties)
else:
# Spawn success:
- if (is_first_time and not instance['access_ip_v4']
- and not instance['access_ip_v6']):
- instance = self._update_access_ip(context, instance,
- network_info)
-
self._notify_about_instance_usage(context, instance,
"create.end", network_info=network_info,
extra_usage_info=extra_usage_info)
@@ -822,8 +845,8 @@ class ComputeManager(manager.SchedulerDependentManager):
self._deallocate_network(context, instance)
except Exception:
# do not attempt retry if network de-allocation failed:
- self._log_original_error(exc_info, instance_uuid)
- raise
+ with excutils.save_and_reraise_exception():
+ self._log_original_error(exc_info, instance_uuid)
try:
method_args = (request_spec, admin_password, injected_files,
@@ -897,32 +920,6 @@ class ComputeManager(manager.SchedulerDependentManager):
LOG.warn(_("Instance build timed out. Set to error state."),
instance=instance)
- def _update_access_ip(self, context, instance, nw_info):
- """Update the access ip values for a given instance.
-
- If CONF.default_access_ip_network_name is set, this method will
- grab the corresponding network and set the access ip values
- accordingly. Note that when there are multiple ips to choose from,
- an arbitrary one will be chosen.
- """
-
- network_name = CONF.default_access_ip_network_name
- if not network_name:
- return instance
-
- update_info = {}
- for vif in nw_info:
- if vif['network']['label'] == network_name:
- for ip in vif.fixed_ips():
- if ip['version'] == 4:
- update_info['access_ip_v4'] = ip['address']
- if ip['version'] == 6:
- update_info['access_ip_v6'] = ip['address']
- if update_info:
- instance = self._instance_update(context, instance['uuid'],
- **update_info)
- return instance
-
def _check_instance_exists(self, context, instance):
"""Ensure an instance with the same name is not already present."""
if self.driver.instance_exists(instance['name']):
@@ -1011,9 +1008,9 @@ class ComputeManager(manager.SchedulerDependentManager):
conductor_api=self.conductor_api,
security_groups=security_groups)
except Exception:
- LOG.exception(_('Instance failed network setup'),
- instance=instance)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_('Instance failed network setup'),
+ instance=instance)
LOG.debug(_('Instance network_info: |%s|'), network_info,
instance=instance)
@@ -1025,12 +1022,13 @@ class ComputeManager(manager.SchedulerDependentManager):
try:
return self._setup_block_device_mapping(context, instance, bdms)
except Exception:
- LOG.exception(_('Instance failed block device setup'),
- instance=instance)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_('Instance failed block device setup'),
+ instance=instance)
def _spawn(self, context, instance, image_meta, network_info,
- block_device_info, injected_files, admin_password):
+ block_device_info, injected_files, admin_password,
+ set_access_ip=False):
"""Spawn an instance with error logging and update its power state."""
instance = self._instance_update(context, instance['uuid'],
vm_state=vm_states.BUILDING,
@@ -1042,16 +1040,44 @@ class ComputeManager(manager.SchedulerDependentManager):
self._legacy_nw_info(network_info),
block_device_info)
except Exception:
- LOG.exception(_('Instance failed to spawn'), instance=instance)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_('Instance failed to spawn'), instance=instance)
current_power_state = self._get_power_state(context, instance)
+
+ update_data = dict(power_state=current_power_state,
+ vm_state=vm_states.ACTIVE,
+ task_state=None,
+ expected_task_state=task_states.SPAWNING,
+ launched_at=timeutils.utcnow())
+
+ def _set_access_ip_values():
+ """Add access ip values for a given instance.
+
+ If CONF.default_access_ip_network_name is set, this method will
+ grab the corresponding network and set the access ip values
+ accordingly. Note that when there are multiple ips to choose
+ from, an arbitrary one will be chosen.
+ """
+
+ network_name = CONF.default_access_ip_network_name
+ if not network_name:
+ return
+
+ for vif in network_info:
+ if vif['network']['label'] == network_name:
+ for ip in vif.fixed_ips():
+ if ip['version'] == 4:
+ update_data['access_ip_v4'] = ip['address']
+ if ip['version'] == 6:
+ update_data['access_ip_v6'] = ip['address']
+ return
+
+ if set_access_ip:
+ _set_access_ip_values()
+
return self._instance_update(context, instance['uuid'],
- power_state=current_power_state,
- vm_state=vm_states.ACTIVE,
- task_state=None,
- expected_task_state=task_states.SPAWNING,
- launched_at=timeutils.utcnow())
+ **update_data)
def _notify_about_instance_usage(self, context, instance, event_suffix,
network_info=None, system_metadata=None,
@@ -1153,8 +1179,14 @@ class ComputeManager(manager.SchedulerDependentManager):
except exception.NetworkNotFound:
network_info = network_model.NetworkInfo()
- # tear down allocated network structure
- self._deallocate_network(context, instance)
+ try:
+ # tear down allocated network structure
+ self._deallocate_network(context, instance)
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ LOG.error(_('Failed to deallocate network for instance.'),
+ instance=instance)
+ self._set_instance_error_state(context, instance['uuid'])
# NOTE(vish) get bdms before destroying the instance
vol_bdms = self._get_volume_bdms(bdms)
@@ -1556,10 +1588,14 @@ class ComputeManager(manager.SchedulerDependentManager):
# Fall through and reset task_state to None
current_power_state = self._get_power_state(context, instance)
- instance = self._instance_update(context, instance['uuid'],
- power_state=current_power_state,
- vm_state=vm_states.ACTIVE,
- task_state=None)
+ try:
+ instance = self._instance_update(context, instance['uuid'],
+ power_state=current_power_state,
+ vm_state=vm_states.ACTIVE,
+ task_state=None)
+ except exception.InstanceNotFound:
+ LOG.warn(_("Instance disappeared during reboot"),
+ context=context, instance=instance)
self._notify_about_instance_usage(context, instance, "reboot.end")
@@ -2324,6 +2360,10 @@ class ComputeManager(manager.SchedulerDependentManager):
network_info = self._inject_network_info(context, instance=instance)
self.reset_network(context, instance)
+ # NOTE(russellb) We just want to bump updated_at. See bug 1143466.
+ self._instance_update(context, instance['uuid'],
+ updated_at=timeutils.utcnow())
+
self._notify_about_instance_usage(
context, instance, "create_ip.end", network_info=network_info)
@@ -2345,6 +2385,10 @@ class ComputeManager(manager.SchedulerDependentManager):
instance=instance)
self.reset_network(context, instance)
+ # NOTE(russellb) We just want to bump updated_at. See bug 1143466.
+ self._instance_update(context, instance['uuid'],
+ updated_at=timeutils.utcnow())
+
self._notify_about_instance_usage(
context, instance, "delete_ip.end", network_info=network_info)
@@ -2763,13 +2807,15 @@ class ComputeManager(manager.SchedulerDependentManager):
network_info = self.network_api.allocate_port_for_instance(
context, instance, port_id, network_id, requested_ip,
self.conductor_api)
+ if len(network_info) != 1:
+ LOG.error(_('allocate_port_for_instance returned %(port)s ports') %
+ dict(ports=len(network_info)))
+ raise exception.InterfaceAttachFailed(instance=instance)
image_meta = _get_image_meta(context, instance['image_ref'])
legacy_net_info = self._legacy_nw_info(network_info)
- for (network, mapping) in legacy_net_info:
- if mapping['vif_uuid'] == port_id:
- self.driver.attach_interface(instance, image_meta,
- [(network, mapping)])
- return (network, mapping)
+ (network, mapping) = legacy_net_info[0]
+ self.driver.attach_interface(instance, image_meta, legacy_net_info)
+ return legacy_net_info[0]
def detach_interface(self, context, instance, port_id):
"""Detach an network adapter from an instance."""
@@ -3647,11 +3693,18 @@ class ComputeManager(manager.SchedulerDependentManager):
:param context: security context
"""
new_resource_tracker_dict = {}
- nodenames = self.driver.get_available_nodes()
+ nodenames = set(self.driver.get_available_nodes())
for nodename in nodenames:
rt = self._get_resource_tracker(nodename)
rt.update_available_resource(context)
new_resource_tracker_dict[nodename] = rt
+
+ # delete nodes that the driver no longer reports
+ known_nodes = set(self._resource_tracker_dict.keys())
+ for nodename in known_nodes - nodenames:
+ rt = self._get_resource_tracker(nodename)
+ rt.update_available_resource(context, delete=True)
+
self._resource_tracker_dict = new_resource_tracker_dict
@manager.periodic_task(spacing=CONF.running_deleted_instance_poll_interval)
@@ -3710,22 +3763,20 @@ class ComputeManager(manager.SchedulerDependentManager):
def _running_deleted_instances(self, context):
"""Returns a list of instances nova thinks is deleted,
- but the hypervisor thinks is still running. This method
- should be pushed down to the virt layer for efficiency.
+ but the hypervisor thinks is still running.
"""
+ timeout = CONF.running_deleted_instance_timeout
+
def deleted_instance(instance):
- timeout = CONF.running_deleted_instance_timeout
- present = instance['name'] in present_name_labels
- erroneously_running = instance['deleted'] and present
+ erroneously_running = instance['deleted']
old_enough = (not instance['deleted_at'] or
timeutils.is_older_than(instance['deleted_at'],
timeout))
if erroneously_running and old_enough:
return True
return False
- present_name_labels = set(self.driver.list_instances())
- instances = self.conductor_api.instance_get_all_by_host(context,
- self.host)
+
+ instances = self._get_instances_on_driver(context)
return [i for i in instances if deleted_instance(i)]
@contextlib.contextmanager
diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py
index efb95dd7b..fab64017d 100644
--- a/nova/compute/resource_tracker.py
+++ b/nova/compute/resource_tracker.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -226,7 +226,7 @@ class ResourceTracker(object):
return self.compute_node is None
@lockutils.synchronized(COMPUTE_RESOURCE_SEMAPHORE, 'nova-')
- def update_available_resource(self, context):
+ def update_available_resource(self, context, delete=False):
"""Override in-memory calculations of compute node resource usage based
on data audited from the hypervisor layer.
@@ -237,11 +237,15 @@ class ResourceTracker(object):
LOG.audit(_("Auditing locally available compute resources"))
resources = self.driver.get_available_resource(self.nodename)
if not resources:
- # The virt driver does not support this function
- LOG.audit(_("Virt driver does not support "
- "'get_available_resource' Compute tracking is disabled."))
- self.compute_node = None
- return
+ if delete:
+ self._delete_compute_node(context)
+ return
+ else:
+ # The virt driver does not support this function
+ LOG.audit(_("Virt driver does not support "
+ "'get_available_resource' Compute tracking is disabled."))
+ self.compute_node = None
+ return
self._verify_resources(resources)
@@ -270,6 +274,13 @@ class ResourceTracker(object):
self._sync_compute_node(context, resources)
+ def _delete_compute_node(self, context):
+ """Delete a compute node DB record."""
+ if self.compute_node:
+ LOG.audit(_("Deleting compute node %s") % self.compute_node['id'])
+ self.compute_node = self.conductor_api.compute_node_delete(
+ context, self.compute_node)
+
def _sync_compute_node(self, context, resources):
"""Create or update the compute node DB record."""
if not self.compute_node:
diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py
index 67dfc6a6b..914c45471 100644
--- a/nova/compute/rpcapi.py
+++ b/nova/compute/rpcapi.py
@@ -50,9 +50,9 @@ def _compute_topic(topic, ctxt, host, instance):
if not instance:
raise exception.NovaException(_('No compute host specified'))
host = instance['host']
- if not host:
- raise exception.NovaException(_('Unable to find host for '
- 'Instance %s') % instance['uuid'])
+ if not host:
+ raise exception.NovaException(_('Unable to find host for '
+ 'Instance %s') % instance['uuid'])
return rpc.queue_get_for(ctxt, topic, host)
diff --git a/nova/compute/stats.py b/nova/compute/stats.py
index b6a30d38f..0d0c7b97c 100644
--- a/nova/compute/stats.py
+++ b/nova/compute/stats.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/compute/task_states.py b/nova/compute/task_states.py
index 8e2b8344a..6787761e9 100644
--- a/nova/compute/task_states.py
+++ b/nova/compute/task_states.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/compute/utils.py b/nova/compute/utils.py
index 8c1f1d577..bd4cd869e 100644
--- a/nova/compute/utils.py
+++ b/nova/compute/utils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
#
# 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/compute/vm_mode.py b/nova/compute/vm_mode.py
index cc1ca6978..71da62b45 100644
--- a/nova/compute/vm_mode.py
+++ b/nova/compute/vm_mode.py
@@ -29,7 +29,7 @@ choose what sort of VM to boot.
from nova import exception
-HVM = "hvm" # Fully virtualizated
+HVM = "hvm" # Fully virtualized
XEN = "xen" # Xen 3.0 paravirtualized
UML = "uml" # User Mode Linux paravirtualized
EXE = "exe" # Executables in containers
diff --git a/nova/compute/vm_states.py b/nova/compute/vm_states.py
index 94a566cce..249b693bc 100644
--- a/nova/compute/vm_states.py
+++ b/nova/compute/vm_states.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/conductor/api.py b/nova/conductor/api.py
index 6bc2d3f25..0b46c3d2f 100644
--- a/nova/conductor/api.py
+++ b/nova/conductor/api.py
@@ -276,6 +276,9 @@ class LocalAPI(object):
return self._manager.compute_node_update(context, node, values,
prune_stats)
+ def compute_node_delete(self, context, node):
+ return self._manager.compute_node_delete(context, node)
+
def service_update(self, context, service, values):
return self._manager.service_update(context, service, values)
@@ -364,7 +367,7 @@ class API(object):
self.ping(context, '1.21 GigaWatts', timeout=timeout)
break
except rpc_common.Timeout as e:
- LOG.exception(_('Timed out waiting for nova-conductor. '
+ LOG.warning(_('Timed out waiting for nova-conductor. '
'Is it running? Or did this service start '
'before nova-conductor?'))
@@ -605,6 +608,9 @@ class API(object):
return self.conductor_rpcapi.compute_node_update(context, node,
values, prune_stats)
+ def compute_node_delete(self, context, node):
+ return self.conductor_rpcapi.compute_node_delete(context, node)
+
def service_update(self, context, service, values):
return self.conductor_rpcapi.service_update(context, service, values)
diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py
index 1c54b1f0b..2a0853491 100644
--- a/nova/conductor/manager.py
+++ b/nova/conductor/manager.py
@@ -39,17 +39,17 @@ allowed_updates = ['task_state', 'vm_state', 'expected_task_state',
'instance_type_id', 'root_device_name', 'launched_on',
'progress', 'vm_mode', 'default_ephemeral_device',
'default_swap_device', 'root_device_name',
- 'system_metadata',
+ 'system_metadata', 'updated_at'
]
# Fields that we want to convert back into a datetime object.
-datetime_fields = ['launched_at', 'terminated_at']
+datetime_fields = ['launched_at', 'terminated_at', 'updated_at']
class ConductorManager(manager.SchedulerDependentManager):
"""Mission: TBD."""
- RPC_API_VERSION = '1.43'
+ RPC_API_VERSION = '1.44'
def __init__(self, *args, **kwargs):
super(ConductorManager, self).__init__(service_name='conductor',
@@ -352,6 +352,10 @@ class ConductorManager(manager.SchedulerDependentManager):
prune_stats)
return jsonutils.to_primitive(result)
+ def compute_node_delete(self, context, node):
+ result = self.db.compute_node_delete(context, node['id'])
+ return jsonutils.to_primitive(result)
+
@rpc_common.client_exceptions(exception.ServiceNotFound)
def service_update(self, context, service, values):
svc = self.db.service_update(context, service['id'], values)
diff --git a/nova/conductor/rpcapi.py b/nova/conductor/rpcapi.py
index f7b7a7814..6c0705e8b 100644
--- a/nova/conductor/rpcapi.py
+++ b/nova/conductor/rpcapi.py
@@ -81,6 +81,7 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy):
quota_rollback
1.42 - Added get_ec2_ids, aggregate_metadata_get_by_host
1.43 - Added compute_stop
+ 1.44 - Added compute_node_delete
"""
BASE_RPC_API_VERSION = '1.0'
@@ -346,6 +347,11 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy):
prune_stats=prune_stats)
return self.call(context, msg, version='1.33')
+ def compute_node_delete(self, context, node):
+ node_p = jsonutils.to_primitive(node)
+ msg = self.make_msg('compute_node_delete', node=node_p)
+ return self.call(context, msg, version='1.44')
+
def service_update(self, context, service, values):
service_p = jsonutils.to_primitive(service)
msg = self.make_msg('service_update', service=service_p, values=values)
diff --git a/nova/console/api.py b/nova/console/api.py
index a2bc40ae0..91966a7ff 100644
--- a/nova/console/api.py
+++ b/nova/console/api.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/console/fake.py b/nova/console/fake.py
index e97d545ea..7e96f43f3 100644
--- a/nova/console/fake.py
+++ b/nova/console/fake.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/console/manager.py b/nova/console/manager.py
index 77be2ad4d..32fa75261 100644
--- a/nova/console/manager.py
+++ b/nova/console/manager.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/console/vmrc.py b/nova/console/vmrc.py
index d7c66a00d..ed3a2afb3 100644
--- a/nova/console/vmrc.py
+++ b/nova/console/vmrc.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/console/vmrc_manager.py b/nova/console/vmrc_manager.py
index f1ea41796..28d23ce9c 100644
--- a/nova/console/vmrc_manager.py
+++ b/nova/console/vmrc_manager.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/console/websocketproxy.py b/nova/console/websocketproxy.py
index ce9243d46..f7fdea173 100644
--- a/nova/console/websocketproxy.py
+++ b/nova/console/websocketproxy.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/console/xvp.py b/nova/console/xvp.py
index c090e84d4..1e9fbcb5d 100644
--- a/nova/console/xvp.py
+++ b/nova/console/xvp.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -26,6 +26,7 @@ from oslo.config import cfg
from nova import context
from nova import db
from nova import exception
+from nova.openstack.common import excutils
from nova.openstack.common import log as logging
from nova import paths
from nova import utils
@@ -119,8 +120,8 @@ class XVPConsoleProxy(object):
with open(CONF.console_xvp_conf, 'w') as cfile:
cfile.write(config)
except IOError:
- LOG.exception(_("Failed to write configuration file"))
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_("Failed to write configuration file"))
def _xvp_stop(self):
LOG.debug(_('Stopping xvp'))
diff --git a/nova/consoleauth/__init__.py b/nova/consoleauth/__init__.py
index 3100ee15c..0b231f56e 100644
--- a/nova/consoleauth/__init__.py
+++ b/nova/consoleauth/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/nova/consoleauth/manager.py b/nova/consoleauth/manager.py
index 56e94dffd..fe5bfd861 100644
--- a/nova/consoleauth/manager.py
+++ b/nova/consoleauth/manager.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,12 +22,12 @@ import time
from oslo.config import cfg
-from nova.common import memorycache
from nova.compute import rpcapi as compute_rpcapi
from nova.conductor import api as conductor_api
from nova import manager
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
+from nova.openstack.common import memorycache
LOG = logging.getLogger(__name__)
diff --git a/nova/context.py b/nova/context.py
index 831a91b11..714948e90 100644
--- a/nova/context.py
+++ b/nova/context.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
diff --git a/nova/crypto.py b/nova/crypto.py
index 4d72aa624..736e99961 100644
--- a/nova/crypto.py
+++ b/nova/crypto.py
@@ -38,6 +38,7 @@ from pyasn1.type import univ
from nova import context
from nova import db
from nova import exception
+from nova.openstack.common import excutils
from nova.openstack.common import fileutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
@@ -387,8 +388,8 @@ def _sign_csr(csr_text, ca_folder):
with open(inbound, 'w') as csrfile:
csrfile.write(csr_text)
except IOError:
- LOG.exception(_('Failed to write inbound.csr'))
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_('Failed to write inbound.csr'))
LOG.debug(_('Flags path: %s'), ca_folder)
start = os.getcwd()
diff --git a/nova/db/api.py b/nova/db/api.py
index d14999b45..fd932c9ef 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -195,11 +195,19 @@ def compute_node_create(context, values):
def compute_node_update(context, compute_id, values, prune_stats=False):
"""Set the given properties on a computeNode and update it.
- Raises NotFound if computeNode does not exist.
+ Raises ComputeHostNotFound if computeNode does not exist.
"""
return IMPL.compute_node_update(context, compute_id, values, prune_stats)
+def compute_node_delete(context, compute_id):
+ """Delete a computeNode from the database.
+
+ Raises ComputeHostNotFound if computeNode does not exist.
+ """
+ return IMPL.compute_node_delete(context, compute_id)
+
+
def compute_node_get_by_host(context, host):
return IMPL.compute_node_get_by_host(context, host)
@@ -627,11 +635,6 @@ def instance_get_all_by_host_and_not_type(context, host, type_id=None):
return IMPL.instance_get_all_by_host_and_not_type(context, host, type_id)
-def instance_get_all_by_reservation(context, reservation_id):
- """Get all instances belonging to a reservation."""
- return IMPL.instance_get_all_by_reservation(context, reservation_id)
-
-
def instance_get_floating_address(context, instance_id):
"""Get the first floating ip address of an instance."""
return IMPL.instance_get_floating_address(context, instance_id)
@@ -872,25 +875,6 @@ def network_update(context, network_id, values):
return IMPL.network_update(context, network_id, values)
-###################
-
-
-def iscsi_target_count_by_host(context, host):
- """Return count of export devices."""
- return IMPL.iscsi_target_count_by_host(context, host)
-
-
-def iscsi_target_create_safe(context, values):
- """Create an iscsi_target from the values dictionary.
-
- The device is not returned. If the create violates the unique
- constraints because the iscsi_target and host already exist,
- no exception is raised.
-
- """
- return IMPL.iscsi_target_create_safe(context, values)
-
-
###############
@@ -970,11 +954,6 @@ def reservation_get(context, uuid):
return IMPL.reservation_get(context, uuid)
-def reservation_destroy(context, uuid):
- """Destroy the reservation or raise if it does not exist."""
- return IMPL.reservation_destroy(context, uuid)
-
-
###################
@@ -1010,11 +989,6 @@ def reservation_expire(context):
###################
-def volume_get_iscsi_target_num(context, volume_id):
- """Get the target num (tid) allocated to the volume."""
- return IMPL.volume_get_iscsi_target_num(context, volume_id)
-
-
def get_ec2_volume_id_by_uuid(context, volume_id):
return IMPL.get_ec2_volume_id_by_uuid(context, volume_id)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 1baa192a3..96c77bce3 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -30,8 +30,7 @@ import uuid
from oslo.config import cfg
from sqlalchemy import and_
from sqlalchemy import Boolean
-from sqlalchemy import exc as sqla_exc
-from sqlalchemy.exc import IntegrityError
+from sqlalchemy.exc import DataError
from sqlalchemy.exc import NoSuchTableError
from sqlalchemy import Integer
from sqlalchemy import MetaData
@@ -52,6 +51,7 @@ import nova.context
from nova import db
from nova.db.sqlalchemy import models
from nova import exception
+from nova.openstack.common.db import exception as db_exc
from nova.openstack.common.db.sqlalchemy import session as db_session
from nova.openstack.common.db.sqlalchemy import utils as sqlalchemyutils
from nova.openstack.common import log as logging
@@ -143,30 +143,15 @@ def require_aggregate_exists(f):
def _retry_on_deadlock(f):
"""Decorator to retry a DB API call if Deadlock was received."""
- def _is_deadlock_exc(dberr_info):
- deadlock_str = 'Deadlock found when trying to get lock'
- try:
- if not isinstance(dberr_info, sqla_exc.OperationalError):
- return False
- if deadlock_str in dberr_info.message:
- LOG.warn(_("Deadlock detected when running "
- "'%(func_name)s': Retrying..."),
- dict(func_name=f.__name__))
- return True
- except Exception:
- pass
- return False
-
@functools.wraps(f)
def wrapped(*args, **kwargs):
while True:
try:
return f(*args, **kwargs)
- except db_session.DBError as db_err:
- exc_info = sys.exc_info()
- dberr_info = db_err.inner_exception
- if not _is_deadlock_exc(dberr_info):
- raise exc_info[0], exc_info[1], exc_info[2]
+ except db_exc.DBDeadlock:
+ LOG.warn(_("Deadlock detected when running "
+ "'%(func_name)s': Retrying..."),
+ dict(func_name=f.__name__))
# Retry!
time.sleep(0.5)
continue
@@ -550,6 +535,17 @@ def compute_node_update(context, compute_id, values, prune_stats=False):
return compute_ref
+@require_admin_context
+def compute_node_delete(context, compute_id):
+ """Delete a ComputeNode record."""
+ result = model_query(context, models.ComputeNode).\
+ filter_by(id=compute_id).\
+ soft_delete()
+
+ if not result:
+ raise exception.ComputeHostNotFound(host=compute_id)
+
+
def compute_node_get_by_host(context, host):
"""Get all capacity entries for the given host."""
result = model_query(context, models.ComputeNode, read_deleted="no").\
@@ -759,6 +755,7 @@ def floating_ip_count_by_project(context, project_id, session=None):
@require_context
+@_retry_on_deadlock
def floating_ip_fixed_ip_associate(context, floating_address,
fixed_address, host):
session = get_session()
@@ -1264,7 +1261,7 @@ def virtual_interface_create(context, values):
vif_ref = models.VirtualInterface()
vif_ref.update(values)
vif_ref.save()
- except db_session.DBError:
+ except db_exc.DBError:
raise exception.VirtualInterfaceCreateException()
return vif_ref
@@ -1373,17 +1370,19 @@ def _validate_unique_server_name(context, session, name):
if not CONF.osapi_compute_unique_server_name_scope:
return
- search_opts = {'deleted': False}
+ lowername = name.lower()
+ base_query = model_query(context, models.Instance, session=session,
+ read_deleted=False).\
+ filter(func.lower(models.Instance.hostname) == lowername)
+
if CONF.osapi_compute_unique_server_name_scope == 'project':
- search_opts['project_id'] = context.project_id
- instance_list = instance_get_all_by_filters(context, search_opts,
- 'created_at', 'desc',
- session=session)
+ instance_with_same_name = base_query.\
+ filter_by(project_id=context.project_id).\
+ count()
+
elif CONF.osapi_compute_unique_server_name_scope == 'global':
- instance_list = instance_get_all_by_filters(context.elevated(),
- search_opts,
- 'created_at', 'desc',
- session=session)
+ instance_with_same_name = base_query.count()
+
else:
msg = _('Unknown osapi_compute_unique_server_name_scope value: %s'
' Flag must be empty, "global" or'
@@ -1391,10 +1390,8 @@ def _validate_unique_server_name(context, session, name):
LOG.warn(msg)
return
- lowername = name.lower()
- for instance in instance_list:
- if instance['hostname'].lower() == lowername:
- raise exception.InstanceExists(name=instance['hostname'])
+ if instance_with_same_name > 0:
+ raise exception.InstanceExists(name=lowername)
@require_context
@@ -1511,14 +1508,19 @@ def _instance_get_by_uuid(context, uuid, session=None):
@require_context
def instance_get(context, instance_id):
- result = _build_instance_get(context).\
- filter_by(id=instance_id).\
- first()
+ try:
+ result = _build_instance_get(context).filter_by(id=instance_id).first()
- if not result:
- raise exception.InstanceNotFound(instance_id=instance_id)
+ if not result:
+ raise exception.InstanceNotFound(instance_id=instance_id)
- return result
+ return result
+ except DataError:
+ # NOTE(sdague): catch all in case the db engine chokes on the
+ # id because it's too long of an int to store.
+ msg = _("Invalid instance id %s in request") % instance_id
+ LOG.warn(msg)
+ raise exception.InvalidID(id=instance_id)
@require_context
@@ -1706,13 +1708,6 @@ def instance_get_all_by_host_and_not_type(context, host, type_id=None):
filter(models.Instance.instance_type_id != type_id).all()
-@require_context
-def instance_get_all_by_reservation(context, reservation_id):
- return _instance_get_all_query(context, project_only=True).\
- filter_by(reservation_id=reservation_id).\
- all()
-
-
# NOTE(jkoelker) This is only being left here for compat with floating
# ips. Currently the network_api doesn't return floaters
# in network_info. Once it starts return the model. This
@@ -1821,18 +1816,6 @@ def _instance_update(context, instance_uuid, values, copy_old_instance=False):
with session.begin():
instance_ref = _instance_get_by_uuid(context, instance_uuid,
session=session)
- # TODO(deva): remove extra_specs from here after it is included
- # in system_metadata. Until then, the baremetal driver
- # needs extra_specs added to instance[]
- inst_type_ref = _instance_type_get_query(context, session=session).\
- filter_by(id=instance_ref['instance_type_id']).\
- first()
- if inst_type_ref:
- instance_ref['extra_specs'] = \
- _dict_with_extra_specs(inst_type_ref).get('extra_specs', {})
- else:
- instance_ref['extra_specs'] = {}
-
if "expected_task_state" in values:
# it is not a db column so always pop out
expected = values.pop("expected_task_state")
@@ -1930,15 +1913,15 @@ def instance_info_cache_update(context, instance_uuid, values):
session=session).\
filter_by(instance_uuid=instance_uuid).\
first()
-
- if info_cache and not info_cache['deleted']:
- # NOTE(tr3buchet): let's leave it alone if it's already deleted
- info_cache.update(values)
- else:
+ if info_cache and info_cache['deleted']:
+ raise exception.InstanceInfoCacheNotFound(
+ instance_uuid=instance_uuid)
+ elif not info_cache:
# NOTE(tr3buchet): just in case someone blows away an instance's
- # cache entry
+ # cache entry, re-create it.
info_cache = models.InstanceInfoCache()
- info_cache.update({'instance_uuid': instance_uuid})
+ values['instance_uuid'] = instance_uuid
+ info_cache.update(values)
return info_cache
@@ -2079,7 +2062,7 @@ def network_create_safe(context, values):
try:
network_ref.save()
return network_ref
- except db_session.DBDuplicateEntry:
+ except db_exc.DBDuplicateEntry:
raise exception.DuplicateVlan(vlan=values['vlan'])
@@ -2321,7 +2304,7 @@ def network_update(context, network_id, values):
network_ref.update(values)
try:
network_ref.save(session=session)
- except db_session.DBDuplicateEntry:
+ except db_exc.DBDuplicateEntry:
raise exception.DuplicateVlan(vlan=values['vlan'])
return network_ref
@@ -2329,29 +2312,6 @@ def network_update(context, network_id, values):
###################
-@require_admin_context
-def iscsi_target_count_by_host(context, host):
- return model_query(context, models.IscsiTarget).\
- filter_by(host=host).\
- count()
-
-
-@require_admin_context
-def iscsi_target_create_safe(context, values):
- iscsi_target_ref = models.IscsiTarget()
-
- for (key, value) in values.iteritems():
- iscsi_target_ref[key] = value
- try:
- iscsi_target_ref.save()
- return iscsi_target_ref
- except IntegrityError:
- return None
-
-
-###################
-
-
@require_context
def quota_get(context, project_id, resource):
result = model_query(context, models.Quota, read_deleted="no").\
@@ -2547,16 +2507,6 @@ def reservation_create(context, uuid, usage, project_id, resource, delta,
return reservation_ref
-@require_admin_context
-def reservation_destroy(context, uuid):
- result = model_query(context, models.Reservation, read_deleted="no").\
- filter_by(uuid=uuid).\
- delete()
-
- if not result:
- raise exception.ReservationNotFound(uuid=uuid)
-
-
###################
@@ -2804,18 +2754,6 @@ def _ec2_snapshot_get_query(context, session=None):
session=session, read_deleted='yes')
-@require_admin_context
-def volume_get_iscsi_target_num(context, volume_id):
- result = model_query(context, models.IscsiTarget, read_deleted="yes").\
- filter_by(volume_id=volume_id).\
- first()
-
- if not result:
- raise exception.ISCSITargetNotFoundForVolume(volume_id=volume_id)
-
- return result.target_num
-
-
@require_context
def ec2_volume_create(context, volume_uuid, id=None):
"""Create ec2 compatible volume by provided uuid."""
@@ -3547,7 +3485,7 @@ def instance_type_create(context, values):
instance_type_ref.update(values)
instance_type_ref.save(session=session)
except Exception, e:
- raise db_session.DBError(e)
+ raise db_exc.DBError(e)
return _dict_with_extra_specs(instance_type_ref)
@@ -4209,7 +4147,7 @@ def s3_image_create(context, image_uuid):
s3_image_ref.update({'uuid': image_uuid})
s3_image_ref.save()
except Exception, e:
- raise db_session.DBError(e)
+ raise db_exc.DBError(e)
return s3_image_ref
@@ -4242,7 +4180,7 @@ def aggregate_create(context, values, metadata=None):
values['name'],
session=session,
read_deleted='no')
- aggregate = query.options(joinedload('_metadata')).first()
+ aggregate = query.first()
if not aggregate:
aggregate = models.Aggregate()
aggregate.update(values)
@@ -4264,7 +4202,7 @@ def aggregate_get(context, aggregate_id):
models.Aggregate,
models.Aggregate.id,
aggregate_id)
- aggregate = query.options(joinedload('_metadata')).first()
+ aggregate = query.first()
if not aggregate:
raise exception.AggregateNotFound(aggregate_id=aggregate_id)
@@ -4318,8 +4256,7 @@ def aggregate_update(context, aggregate_id, values):
models.Aggregate,
models.Aggregate.id,
aggregate_id,
- session=session).
- options(joinedload('_metadata')).first())
+ session=session).first())
if aggregate:
if "availability_zone" in values:
@@ -4614,6 +4551,10 @@ def action_event_finish(context, values):
raise exception.InstanceActionEventNotFound(action_id=action['id'],
event=values['event'])
event_ref.update(values)
+
+ if values['result'].lower() == 'error':
+ action.update({'message': 'Error'})
+
return event_ref
@@ -4729,7 +4670,7 @@ def task_log_begin_task(context, task_name, period_beginning, period_ending,
task.task_items = task_items
try:
task.save()
- except db_session.DBDuplicateEntry:
+ except db_exc.DBDuplicateEntry:
raise exception.TaskAlreadyRunning(task_name=task_name, host=host)
@@ -4767,15 +4708,13 @@ def _get_default_deleted_value(table):
@require_admin_context
-def archive_deleted_rows_for_table(context, tablename, max_rows=None):
+def archive_deleted_rows_for_table(context, tablename, max_rows):
"""Move up to max_rows rows from one tables to the corresponding
shadow table.
:returns: number of rows archived
"""
# The context argument is only used for the decorator.
- if max_rows is None:
- max_rows = 5000
engine = get_engine()
conn = engine.connect()
metadata = MetaData()
@@ -4826,8 +4765,6 @@ def archive_deleted_rows(context, max_rows=None):
:returns: Number of rows archived.
"""
# The context argument is only used for the decorator.
- if max_rows is None:
- max_rows = 5000
tablenames = []
for model_class in models.__dict__.itervalues():
if hasattr(model_class, "__tablename__"):
diff --git a/nova/db/sqlalchemy/migrate_repo/__init__.py b/nova/db/sqlalchemy/migrate_repo/__init__.py
index 4cad9a01b..74704e5e6 100644
--- a/nova/db/sqlalchemy/migrate_repo/__init__.py
+++ b/nova/db/sqlalchemy/migrate_repo/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/manage.py b/nova/db/sqlalchemy/migrate_repo/manage.py
index f4b31bbe4..3ff394182 100644
--- a/nova/db/sqlalchemy/migrate_repo/manage.py
+++ b/nova/db/sqlalchemy/migrate_repo/manage.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/133_folsom.py b/nova/db/sqlalchemy/migrate_repo/versions/133_folsom.py
index 44eac3695..1b688a883 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/133_folsom.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/133_folsom.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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
@@ -1222,4 +1222,4 @@ def upgrade(migrate_engine):
def downgrade(migrate_engine):
- LOG.exception(_('Downgrade from Folsom is unsupported.'))
+ raise NotImplementedError('Downgrade from Folsom is unsupported.')
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/134_add_counters_to_bw_usage_cache.py b/nova/db/sqlalchemy/migrate_repo/versions/134_add_counters_to_bw_usage_cache.py
index 985149e91..b4178e3c7 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/134_add_counters_to_bw_usage_cache.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/134_add_counters_to_bw_usage_cache.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/135_add_node_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/135_add_node_to_instances.py
index c30cdecdc..331183d3b 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/135_add_node_to_instances.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/135_add_node_to_instances.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/136_add_index_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/136_add_index_to_instances.py
index 397f8a62b..d3969a9c4 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/136_add_index_to_instances.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/136_add_index_to_instances.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/137_add_indexes_to_migrations.py b/nova/db/sqlalchemy/migrate_repo/versions/137_add_indexes_to_migrations.py
index 1499bd351..7dde6e83e 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/137_add_indexes_to_migrations.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/137_add_indexes_to_migrations.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/138_drop_server_name_from_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/138_drop_server_name_from_instances.py
index 2faae3a8e..d8d043b40 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/138_drop_server_name_from_instances.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/138_drop_server_name_from_instances.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/139_add_indexes_to_fixed_ips.py b/nova/db/sqlalchemy/migrate_repo/versions/139_add_indexes_to_fixed_ips.py
index 8a471c057..af50fced5 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/139_add_indexes_to_fixed_ips.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/139_add_indexes_to_fixed_ips.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py b/nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py
index 692f9599b..14ac0c5e6 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py
@@ -1,4 +1,4 @@
-# Copyright 2012 Openstack LLC.
+# Copyright 2012 Openstack Foundation
#
# 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/145_add_volume_usage_cache.py b/nova/db/sqlalchemy/migrate_repo/versions/145_add_volume_usage_cache.py
index 7adbcb938..41c4b6097 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/145_add_volume_usage_cache.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/145_add_volume_usage_cache.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/146_aggregate_zones.py b/nova/db/sqlalchemy/migrate_repo/versions/146_aggregate_zones.py
index f1cfaf5c6..0f39bf231 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/146_aggregate_zones.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/146_aggregate_zones.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/147_no_service_zones.py b/nova/db/sqlalchemy/migrate_repo/versions/147_no_service_zones.py
index d93cd1ead..a0ad90d4e 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/147_no_service_zones.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/147_no_service_zones.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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
@@ -58,8 +58,12 @@ def upgrade(migrate_engine):
})
# add host to zone
agg_hosts = Table('aggregate_hosts', meta, autoload=True)
- row = agg_hosts.insert()
- row.execute({'host': rec['host'], 'aggregate_id': agg_id})
+ num_hosts = agg_hosts.count().where(
+ agg_hosts.c.host == rec['host']).where(
+ agg_hosts.c.aggregate_id == agg_id).execute().scalar()
+ if num_hosts == 0:
+ agg_hosts.insert().execute({'host': rec['host'],
+ 'aggregate_id': agg_id})
services.drop_column('availability_zone')
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/148_add_instance_actions.py b/nova/db/sqlalchemy/migrate_repo/versions/148_add_instance_actions.py
index 6adfb1dc1..5e60d41cc 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/148_add_instance_actions.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/148_add_instance_actions.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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
@@ -68,14 +68,8 @@ def upgrade(migrate_engine):
mysql_charset='utf8',
)
- try:
- instance_actions.create()
- instance_actions_events.create()
- except Exception:
- LOG.exception("Exception while creating table 'instance_actions' or "
- "'instance_actions_events'")
- meta.drop_all(tables=[instance_actions, instance_actions_events])
- raise
+ instance_actions.create()
+ instance_actions_events.create()
Index('instance_uuid_idx',
instance_actions.c.instance_uuid).create(migrate_engine)
@@ -87,15 +81,9 @@ def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
- try:
- instance_actions = Table('instance_actions', meta, autoload=True)
- instance_actions.drop()
- except Exception:
- LOG.exception("Exception dropping table 'instance_actions'")
+ instance_actions_events = Table('instance_actions_events', meta,
+ autoload=True)
+ instance_actions_events.drop()
- try:
- instance_actions_events = Table('instance_actions_events', meta,
- autoload=True)
- instance_actions_events.drop()
- except Exception:
- LOG.exception("Exception dropping table 'instance_actions_events")
+ instance_actions = Table('instance_actions', meta, autoload=True)
+ instance_actions.drop()
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/149_inet_datatype_for_postgres.py b/nova/db/sqlalchemy/migrate_repo/versions/149_inet_datatype_for_postgres.py
index 3eb26ac7d..79ad6f014 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/149_inet_datatype_for_postgres.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/149_inet_datatype_for_postgres.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/150_add_host_to_instance_faults.py b/nova/db/sqlalchemy/migrate_repo/versions/150_add_host_to_instance_faults.py
index 3fd87e1e1..99583c098 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/150_add_host_to_instance_faults.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/150_add_host_to_instance_faults.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation
#
# 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/159_revert_ip_column_length.py b/nova/db/sqlalchemy/migrate_repo/versions/159_revert_ip_column_length.py
new file mode 100644
index 000000000..65e11c42c
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/159_revert_ip_column_length.py
@@ -0,0 +1,63 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 IBM Corp.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from sqlalchemy import MetaData, String, Table
+from sqlalchemy.dialects import postgresql
+
+TABLE_COLUMNS = [
+ # table name, column name
+ ('instances', 'access_ip_v4'),
+ ('instances', 'access_ip_v6'),
+ ('networks', 'gateway'),
+ ('networks', 'gateway_v6'),
+ ('networks', 'netmask'),
+ ('networks', 'netmask_v6'),
+ ('networks', 'broadcast'),
+ ('networks', 'dns1'),
+ ('networks', 'dns2'),
+ ('networks', 'vpn_public_address'),
+ ('networks', 'vpn_private_address'),
+ ('networks', 'dhcp_start'),
+ ('fixed_ips', 'address'),
+ ('floating_ips', 'address'),
+ ('console_pools', 'address')]
+
+
+def upgrade(migrate_engine):
+ dialect = migrate_engine.url.get_dialect()
+
+ # NOTE(maurosr): this just affects mysql; postgresql uses INET
+ # type and sqlite doesn't goes fine with alter tables, so it should be done
+ # manually. This way we'll be able to keep UCs like the one inserted on
+ # version 158 which would get lost cause sqlite is not migrated as mysql or
+ # pgsql, it copies the column and data instead of execute an alter table
+ # command.
+ if dialect is not postgresql.dialect:
+ meta = MetaData(bind=migrate_engine)
+ for table, column in TABLE_COLUMNS:
+ t = Table(table, meta, autoload=True)
+ getattr(t.c, column).alter(type=String(39))
+
+
+def downgrade(migrate_engine):
+ """Convert columns back to the larger String(43) defined in version 149."""
+ dialect = migrate_engine.url.get_dialect()
+ if dialect is not postgresql.dialect:
+ meta = MetaData(bind=migrate_engine)
+ for table, column in TABLE_COLUMNS:
+ t = Table(table, meta, autoload=True)
+ getattr(t.c, column).alter(type=String(43))
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/159_sqlite_downgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/159_sqlite_downgrade.sql
new file mode 100644
index 000000000..381d8f26b
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/159_sqlite_downgrade.sql
@@ -0,0 +1,81 @@
+BEGIN TRANSACTION;
+ /* create networks_backup table with the fields like networks was before
+ the upgrade */
+ CREATE TABLE networks_backup(
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted INTEGER,
+ id INTEGER NOT NULL,
+ injected BOOLEAN,
+ cidr VARCHAR(43),
+ netmask VARCHAR(43),
+ bridge VARCHAR(255),
+ gateway VARCHAR(43),
+ broadcast VARCHAR(43),
+ dns1 VARCHAR(43),
+ vlan INTEGER,
+ vpn_public_address VARCHAR(43),
+ vpn_public_port INTEGER,
+ vpn_private_address VARCHAR(43),
+ dhcp_start VARCHAR(43),
+ project_id VARCHAR(255),
+ host VARCHAR(255),
+ cidr_v6 VARCHAR(43),
+ gateway_v6 VARCHAR(43),
+ label VARCHAR(255),
+ netmask_v6 VARCHAR(43),
+ bridge_interface VARCHAR(255),
+ multi_host BOOLEAN,
+ dns2 VARCHAR(43),
+ uuid VARCHAR(36),
+ priority INTEGER,
+ rxtx_base INTEGER,
+ PRIMARY KEY (id)
+ );
+
+ /* copy data currently on networks to the backup table and drop networks
+ table */
+ INSERT INTO networks_backup SELECT * FROM networks;
+ DROP TABLE networks;
+
+ CREATE TABLE networks (
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted INTEGER,
+ id INTEGER NOT NULL,
+ injected BOOLEAN,
+ cidr VARCHAR(43),
+ netmask VARCHAR(43),
+ bridge VARCHAR(255),
+ gateway VARCHAR(43),
+ broadcast VARCHAR(43),
+ dns1 VARCHAR(43),
+ vlan INTEGER,
+ vpn_public_address VARCHAR(43),
+ vpn_public_port INTEGER,
+ vpn_private_address VARCHAR(43),
+ dhcp_start VARCHAR(43),
+ project_id VARCHAR(255),
+ host VARCHAR(255),
+ cidr_v6 VARCHAR(43),
+ gateway_v6 VARCHAR(43),
+ label VARCHAR(255),
+ netmask_v6 VARCHAR(43),
+ bridge_interface VARCHAR(255),
+ multi_host BOOLEAN,
+ dns2 VARCHAR(43),
+ uuid VARCHAR(36),
+ priority INTEGER,
+ rxtx_base INTEGER,
+ PRIMARY KEY (id),
+ CHECK (injected IN (0, 1)),
+ CHECK (multi_host IN (0, 1)),
+ CONSTRAINT uniq_vlan_x_deleted UNIQUE (vlan, deleted)
+);
+
+ /* Get data from backup table and drop it next */
+ INSERT INTO networks SELECT * FROM networks_backup;
+ DROP TABLE networks_backup;
+COMMIT;
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/159_sqlite_upgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/159_sqlite_upgrade.sql
new file mode 100644
index 000000000..206155baa
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/159_sqlite_upgrade.sql
@@ -0,0 +1,79 @@
+BEGIN TRANSACTION;
+ /* Create a backup table with the new fields size */
+ CREATE TABLE networks_backup(
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted INTEGER,
+ id INTEGER NOT NULL,
+ injected BOOLEAN,
+ cidr VARCHAR(43),
+ netmask VARCHAR(39),
+ bridge VARCHAR(255),
+ gateway VARCHAR(39),
+ broadcast VARCHAR(39),
+ dns1 VARCHAR(39),
+ vlan INTEGER,
+ vpn_public_address VARCHAR(39),
+ vpn_public_port INTEGER,
+ vpn_private_address VARCHAR(39),
+ dhcp_start VARCHAR(39),
+ project_id VARCHAR(255),
+ host VARCHAR(255),
+ cidr_v6 VARCHAR(43),
+ gateway_v6 VARCHAR(39),
+ label VARCHAR(255),
+ netmask_v6 VARCHAR(39),
+ bridge_interface VARCHAR(255),
+ multi_host BOOLEAN,
+ dns2 VARCHAR(39),
+ uuid VARCHAR(36),
+ priority INTEGER,
+ rxtx_base INTEGER,
+ PRIMARY KEY (id)
+ );
+
+ /* get data from networks and the drop it */
+ INSERT INTO networks_backup SELECT * FROM networks;
+ DROP TABLE networks;
+
+ CREATE TABLE networks (
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted INTEGER,
+ id INTEGER NOT NULL,
+ injected BOOLEAN,
+ cidr VARCHAR(43),
+ netmask VARCHAR(39),
+ bridge VARCHAR(255),
+ gateway VARCHAR(39),
+ broadcast VARCHAR(39),
+ dns1 VARCHAR(39),
+ vlan INTEGER,
+ vpn_public_address VARCHAR(39),
+ vpn_public_port INTEGER,
+ vpn_private_address VARCHAR(39),
+ dhcp_start VARCHAR(39),
+ project_id VARCHAR(255),
+ host VARCHAR(255),
+ cidr_v6 VARCHAR(43),
+ gateway_v6 VARCHAR(39),
+ label VARCHAR(255),
+ netmask_v6 VARCHAR(39),
+ bridge_interface VARCHAR(255),
+ multi_host BOOLEAN,
+ dns2 VARCHAR(39),
+ uuid VARCHAR(36),
+ priority INTEGER,
+ rxtx_base INTEGER,
+ PRIMARY KEY (id),
+ CHECK (injected IN (0, 1)),
+ CHECK (multi_host IN (0, 1)),
+ CONSTRAINT uniq_vlan_x_deleted UNIQUE (vlan, deleted)
+ );
+
+ /* get data from networks_backup back and drop it */
+ INSERT INTO networks SELECT * FROM networks_backup;
+ DROP TABLE networks_backup;
+COMMIT;
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/160_fix_system_metadata_deleted.py b/nova/db/sqlalchemy/migrate_repo/versions/160_fix_system_metadata_deleted.py
new file mode 100644
index 000000000..d7909f897
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/160_fix_system_metadata_deleted.py
@@ -0,0 +1,33 @@
+# Copyright 2013 Rackspace Hosting
+#
+# 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.
+
+import sqlalchemy
+
+
+def upgrade(migrate_engine):
+ meta = sqlalchemy.MetaData()
+ meta.bind = migrate_engine
+ sys_meta = sqlalchemy.Table('instance_system_metadata', meta,
+ autoload=True)
+ # is None does not work here.
+ sys_meta.update().\
+ where(sys_meta.c.deleted == None).\
+ values(deleted=0).\
+ execute()
+
+
+def downgrade(migration_engine):
+ # This migration only corrects NULL to be 0. There's no action to
+ # revert this.
+ pass
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/__init__.py b/nova/db/sqlalchemy/migrate_repo/versions/__init__.py
index 4cad9a01b..74704e5e6 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/__init__.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/models.py b/nova/db/sqlalchemy/models.py
index 95456bf98..a675357df 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -164,12 +164,6 @@ class Instance(BASE, NovaBase):
ramdisk_id = Column(String(255))
hostname = Column(String(255))
-# image_ref = Column(Integer, ForeignKey('images.id'), nullable=True)
-# kernel_id = Column(Integer, ForeignKey('images.id'), nullable=True)
-# ramdisk_id = Column(Integer, ForeignKey('images.id'), nullable=True)
-# ramdisk = relationship(Ramdisk, backref=backref('instances', order_by=id))
-# kernel = relationship(Kernel, backref=backref('instances', order_by=id))
-
launch_index = Column(Integer)
key_name = Column(String(255))
key_data = Column(Text)
@@ -841,29 +835,16 @@ class Aggregate(BASE, NovaBase):
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(255))
_hosts = relationship(AggregateHost,
- lazy="joined",
- secondary="aggregate_hosts",
primaryjoin='and_('
- 'Aggregate.id == AggregateHost.aggregate_id,'
- 'AggregateHost.deleted == 0,'
- 'Aggregate.deleted == 0)',
- secondaryjoin='and_('
- 'AggregateHost.aggregate_id == Aggregate.id, '
- 'AggregateHost.deleted == 0,'
- 'Aggregate.deleted == 0)',
- backref='aggregates')
+ 'Aggregate.id == AggregateHost.aggregate_id,'
+ 'AggregateHost.deleted == 0,'
+ 'Aggregate.deleted == 0)')
_metadata = relationship(AggregateMetadata,
- secondary="aggregate_metadata",
- primaryjoin='and_('
+ primaryjoin='and_('
'Aggregate.id == AggregateMetadata.aggregate_id,'
'AggregateMetadata.deleted == 0,'
- 'Aggregate.deleted == 0)',
- secondaryjoin='and_('
- 'AggregateMetadata.aggregate_id == Aggregate.id, '
- 'AggregateMetadata.deleted == 0,'
- 'Aggregate.deleted == 0)',
- backref='aggregates')
+ 'Aggregate.deleted == 0)')
def _extra_keys(self):
return ['hosts', 'metadetails', 'availability_zone']
diff --git a/nova/db/sqlalchemy/types.py b/nova/db/sqlalchemy/types.py
index 5a04a0253..ef9113413 100644
--- a/nova/db/sqlalchemy/types.py
+++ b/nova/db/sqlalchemy/types.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/exception.py b/nova/exception.py
index cad1c5c02..0e6c004d6 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -31,6 +31,7 @@ import webob.exc
from nova.openstack.common import excutils
from nova.openstack.common import log as logging
+from nova import safe_utils
LOG = logging.getLogger(__name__)
@@ -71,6 +72,11 @@ class ProcessExecutionError(IOError):
IOError.__init__(self, message)
+def _cleanse_dict(original):
+ """Strip all admin_password, new_pass, rescue_pass keys from a dict."""
+ return dict((k, v) for k, v in original.iteritems() if not "_pass" in k)
+
+
def wrap_exception(notifier=None, publisher_id=None, event_type=None,
level=None):
"""This decorator wraps a method to catch any exceptions that may
@@ -89,8 +95,10 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None,
except Exception, e:
with excutils.save_and_reraise_exception():
if notifier:
- payload = dict(args=args, exception=e)
- payload.update(kw)
+ payload = dict(exception=e)
+ call_dict = safe_utils.getcallargs(f, *args, **kw)
+ cleansed = _cleanse_dict(call_dict)
+ payload.update({'args': cleansed})
# Use a temp vars so we don't shadow
# our outer definitions.
@@ -423,6 +431,10 @@ class InvalidUUID(Invalid):
message = _("Expected a uuid but received %(uuid)s.")
+class InvalidID(Invalid):
+ message = _("Invalid ID received %(id)s.")
+
+
class InvalidPeriodicTaskArg(Invalid):
message = _("Unexpected argument for periodic task creation: %(arg)s.")
@@ -1060,6 +1072,11 @@ class InstanceNotFound(NotFound):
message = _("Instance %(instance_id)s could not be found.")
+class InstanceInfoCacheNotFound(NotFound):
+ message = _("Info cache for instance %(instance_uuid)s could not be "
+ "found.")
+
+
class NodeNotFound(NotFound):
message = _("Node %(node_id)s could not be found.")
@@ -1080,6 +1097,10 @@ class CouldNotFetchImage(NovaException):
message = _("Could not fetch image %(image_id)s")
+class CouldNotUploadImage(NovaException):
+ message = _("Could not upload image %(image_id)s")
+
+
class TaskAlreadyRunning(NovaException):
message = _("Task %(task_name)s is already running on host %(host)s")
diff --git a/nova/filters.py b/nova/filters.py
index a3339eff8..59028a542 100644
--- a/nova/filters.py
+++ b/nova/filters.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2012 OpenStack, LLC.
+# Copyright (c) 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/hooks.py b/nova/hooks.py
index 8a9c77e73..c6fede8a8 100644
--- a/nova/hooks.py
+++ b/nova/hooks.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/image/glance.py b/nova/image/glance.py
index 79614d6a7..eb0d72b81 100644
--- a/nova/image/glance.py
+++ b/nova/image/glance.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/ipv6/__init__.py b/nova/ipv6/__init__.py
index 99ff05356..7abdae5e4 100644
--- a/nova/ipv6/__init__.py
+++ b/nova/ipv6/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
#
# 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/ipv6/api.py b/nova/ipv6/api.py
index 7f94abcfb..06a0891d9 100644
--- a/nova/ipv6/api.py
+++ b/nova/ipv6/api.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
#
# 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/loadables.py b/nova/loadables.py
index 964845184..96da88d0a 100644
--- a/nova/loadables.py
+++ b/nova/loadables.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2012 OpenStack, LLC.
+# Copyright (c) 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/locale/nova.pot b/nova/locale/nova.pot
index 1b3d0474c..4fcebf25e 100644
--- a/nova/locale/nova.pot
+++ b/nova/locale/nova.pot
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: nova jenkins.nova.propose.translation.update.169\n"
+"Project-Id-Version: nova jenkins.nova.propose.translation.update.177\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-02-25 00:04+0000\n"
+"POT-Creation-Date: 2013-03-05 00:03+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -175,7 +175,7 @@ msgid "Volume %(volume_id)s is not attached to anything"
msgstr ""
#: nova/exception.py:234 nova/api/ec2/cloud.py:463
-#: nova/api/openstack/compute/contrib/keypairs.py:98 nova/compute/api.py:2691
+#: nova/api/openstack/compute/contrib/keypairs.py:98 nova/compute/api.py:2708
msgid "Keypair data is invalid"
msgstr ""
@@ -205,7 +205,7 @@ msgstr ""
msgid "Invalid port range %(from_port)s:%(to_port)s. %(msg)s"
msgstr ""
-#: nova/exception.py:262 nova/api/ec2/cloud.py:617
+#: nova/exception.py:262 nova/api/ec2/cloud.py:625
#, python-format
msgid "Invalid IP protocol %(protocol)s."
msgstr ""
@@ -220,7 +220,7 @@ msgstr ""
msgid "Invalid cidr %(cidr)s."
msgstr ""
-#: nova/exception.py:274 nova/openstack/common/db/sqlalchemy/session.py:345
+#: nova/exception.py:274 nova/openstack/common/db/exception.py:44
msgid "Invalid Parameter: Unicode is not supported by the current database."
msgstr ""
@@ -397,58 +397,63 @@ msgstr ""
#: nova/exception.py:427
#, python-format
-msgid "Unexpected argument for periodic task creation: %(arg)s."
+msgid "Invalid ID received %(id)s."
msgstr ""
#: nova/exception.py:431
+#, python-format
+msgid "Unexpected argument for periodic task creation: %(arg)s."
+msgstr ""
+
+#: nova/exception.py:435
msgid "Constraint not met."
msgstr ""
-#: nova/exception.py:436
+#: nova/exception.py:440
msgid "Resource could not be found."
msgstr ""
-#: nova/exception.py:441
+#: nova/exception.py:445
#, python-format
msgid "No agent-build associated with id %(id)s."
msgstr ""
-#: nova/exception.py:445
+#: nova/exception.py:449
#, python-format
msgid "Volume %(volume_id)s could not be found."
msgstr ""
-#: nova/exception.py:449
+#: nova/exception.py:453
#, python-format
msgid "Snapshot %(snapshot_id)s could not be found."
msgstr ""
-#: nova/exception.py:453
+#: nova/exception.py:457
#, python-format
msgid "No target id found for volume %(volume_id)s."
msgstr ""
-#: nova/exception.py:457
+#: nova/exception.py:461
#, python-format
msgid "No disk at %(location)s"
msgstr ""
-#: nova/exception.py:461
+#: nova/exception.py:465
#, python-format
msgid "Could not find a handler for %(driver_type)s volume."
msgstr ""
-#: nova/exception.py:465
+#: nova/exception.py:469
#, python-format
msgid "Invalid image href %(image_href)s."
msgstr ""
-#: nova/exception.py:469
+#: nova/exception.py:473
#, python-format
msgid "Image %(image_id)s could not be found."
msgstr ""
-#: nova/exception.py:473
+#: nova/exception.py:477
#, python-format
msgid ""
"Image %(image_id)s could not be found. The nova EC2 API assigns image ids"
@@ -456,802 +461,812 @@ msgid ""
"image ids since adding this image?"
msgstr ""
-#: nova/exception.py:480
+#: nova/exception.py:484
#, python-format
msgid "Project %(project_id)s could not be found."
msgstr ""
-#: nova/exception.py:484
+#: nova/exception.py:488
msgid "Cannot find SR to read/write VDI."
msgstr ""
-#: nova/exception.py:488
+#: nova/exception.py:492
#, python-format
msgid "Network %(network_id)s is duplicated."
msgstr ""
-#: nova/exception.py:492
+#: nova/exception.py:496
#, python-format
msgid "Network %(network_id)s is still in use."
msgstr ""
-#: nova/exception.py:496
+#: nova/exception.py:500
#, python-format
msgid "%(req)s is required to create a network."
msgstr ""
-#: nova/exception.py:500
+#: nova/exception.py:504
#, python-format
msgid "Network %(network_id)s could not be found."
msgstr ""
-#: nova/exception.py:504
+#: nova/exception.py:508
#, python-format
msgid "Port id %(port_id)s could not be found."
msgstr ""
-#: nova/exception.py:508
+#: nova/exception.py:512
#, python-format
msgid "Network could not be found for bridge %(bridge)s"
msgstr ""
-#: nova/exception.py:512
+#: nova/exception.py:516
#, python-format
msgid "Network could not be found for uuid %(uuid)s"
msgstr ""
-#: nova/exception.py:516
+#: nova/exception.py:520
#, python-format
msgid "Network could not be found with cidr %(cidr)s."
msgstr ""
-#: nova/exception.py:520
+#: nova/exception.py:524
#, python-format
msgid "Network could not be found for instance %(instance_id)s."
msgstr ""
-#: nova/exception.py:524
+#: nova/exception.py:528
msgid "No networks defined."
msgstr ""
-#: nova/exception.py:528
+#: nova/exception.py:532
#, python-format
msgid ""
"Either Network uuid %(network_uuid)s is not present or is not assigned to"
" the project %(project_id)s."
msgstr ""
-#: nova/exception.py:533
+#: nova/exception.py:537
msgid "Could not find the datastore reference(s) which the VM uses."
msgstr ""
-#: nova/exception.py:537
+#: nova/exception.py:541
#, python-format
msgid "Port %(port_id)s is still in use."
msgstr ""
-#: nova/exception.py:541
+#: nova/exception.py:545
#, python-format
msgid "Port %(port_id)s not usable for instance %(instance)s."
msgstr ""
-#: nova/exception.py:545
+#: nova/exception.py:549
#, python-format
msgid "No free port available for instance %(instance)s."
msgstr ""
-#: nova/exception.py:549
+#: nova/exception.py:553
#, python-format
msgid "No fixed IP associated with id %(id)s."
msgstr ""
-#: nova/exception.py:553
+#: nova/exception.py:557
#, python-format
msgid "Fixed ip not found for address %(address)s."
msgstr ""
-#: nova/exception.py:557
+#: nova/exception.py:561
#, python-format
msgid "Instance %(instance_uuid)s has zero fixed ips."
msgstr ""
-#: nova/exception.py:561
+#: nova/exception.py:565
#, python-format
msgid "Network host %(host)s has zero fixed ips in network %(network_id)s."
msgstr ""
-#: nova/exception.py:566
+#: nova/exception.py:570
#, python-format
msgid "Instance %(instance_uuid)s doesn't have fixed ip '%(ip)s'."
msgstr ""
-#: nova/exception.py:570
+#: nova/exception.py:574
#, python-format
msgid ""
"Fixed IP address (%(address)s) does not exist in network "
"(%(network_uuid)s)."
msgstr ""
-#: nova/exception.py:575
+#: nova/exception.py:579
#, python-format
msgid ""
"Fixed IP address %(address)s is already in use on instance "
"%(instance_uuid)s."
msgstr ""
-#: nova/exception.py:580
+#: nova/exception.py:584
#, python-format
msgid "More than one instance is associated with fixed ip address '%(address)s'."
msgstr ""
-#: nova/exception.py:585
+#: nova/exception.py:589
#, python-format
msgid "Fixed IP address %(address)s is invalid."
msgstr ""
-#: nova/exception.py:589
+#: nova/exception.py:593
msgid "Zero fixed ips available."
msgstr ""
-#: nova/exception.py:593
+#: nova/exception.py:597
msgid "Zero fixed ips could be found."
msgstr ""
-#: nova/exception.py:602
+#: nova/exception.py:606
#, python-format
msgid "Floating ip %(address)s already exists."
msgstr ""
-#: nova/exception.py:606
+#: nova/exception.py:610
#, python-format
msgid "Floating ip not found for id %(id)s."
msgstr ""
-#: nova/exception.py:610
+#: nova/exception.py:614
#, python-format
msgid "The DNS entry %(name)s already exists in domain %(domain)s."
msgstr ""
-#: nova/exception.py:614
+#: nova/exception.py:618
#, python-format
msgid "Floating ip not found for address %(address)s."
msgstr ""
-#: nova/exception.py:618
+#: nova/exception.py:622
#, python-format
msgid "Floating ip not found for host %(host)s."
msgstr ""
-#: nova/exception.py:622
+#: nova/exception.py:626
#, python-format
msgid "Multiple floating ips are found for address %(address)s."
msgstr ""
-#: nova/exception.py:626
+#: nova/exception.py:630
msgid "Floating ip pool not found."
msgstr ""
-#: nova/exception.py:631
+#: nova/exception.py:635
msgid "Zero floating ips available."
msgstr ""
-#: nova/exception.py:636
+#: nova/exception.py:640
#, python-format
msgid "Floating ip %(address)s is associated."
msgstr ""
-#: nova/exception.py:640
+#: nova/exception.py:644
#, python-format
msgid "Floating ip %(address)s is not associated."
msgstr ""
-#: nova/exception.py:644
+#: nova/exception.py:648
msgid "Zero floating ips exist."
msgstr ""
-#: nova/exception.py:648
+#: nova/exception.py:652
#, python-format
msgid "Interface %(interface)s not found."
msgstr ""
-#: nova/exception.py:652
+#: nova/exception.py:656
msgid "Cannot disassociate auto assigined floating ip"
msgstr ""
-#: nova/exception.py:656
+#: nova/exception.py:660
#, python-format
msgid "Keypair %(name)s not found for user %(user_id)s"
msgstr ""
-#: nova/exception.py:660
+#: nova/exception.py:664
#, python-format
msgid "Certificate %(certificate_id)s not found."
msgstr ""
-#: nova/exception.py:664
+#: nova/exception.py:668
#, python-format
msgid "Service %(service_id)s could not be found."
msgstr ""
-#: nova/exception.py:668
+#: nova/exception.py:672
#, python-format
msgid "Host %(host)s could not be found."
msgstr ""
-#: nova/exception.py:672
+#: nova/exception.py:676
#, python-format
msgid "Compute host %(host)s could not be found."
msgstr ""
-#: nova/exception.py:676
+#: nova/exception.py:680
#, python-format
msgid "Could not find binary %(binary)s on host %(host)s."
msgstr ""
-#: nova/exception.py:680
+#: nova/exception.py:684
#, python-format
msgid "Invalid reservation expiration %(expire)s."
msgstr ""
-#: nova/exception.py:684
+#: nova/exception.py:688
#, python-format
msgid ""
"Change would make usage less than 0 for the following resources: "
"%(unders)s"
msgstr ""
-#: nova/exception.py:689
+#: nova/exception.py:693
msgid "Quota could not be found"
msgstr ""
-#: nova/exception.py:693
+#: nova/exception.py:697
#, python-format
msgid "Unknown quota resources %(unknown)s."
msgstr ""
-#: nova/exception.py:697
+#: nova/exception.py:701
#, python-format
msgid "Quota for project %(project_id)s could not be found."
msgstr ""
-#: nova/exception.py:701
+#: nova/exception.py:705
#, python-format
msgid "Quota class %(class_name)s could not be found."
msgstr ""
-#: nova/exception.py:705
+#: nova/exception.py:709
#, python-format
msgid "Quota usage for project %(project_id)s could not be found."
msgstr ""
-#: nova/exception.py:709
+#: nova/exception.py:713
#, python-format
msgid "Quota reservation %(uuid)s could not be found."
msgstr ""
-#: nova/exception.py:713
+#: nova/exception.py:717
#, python-format
msgid "Quota exceeded for resources: %(overs)s"
msgstr ""
-#: nova/exception.py:717
+#: nova/exception.py:721
#, python-format
msgid "Security group %(security_group_id)s not found."
msgstr ""
-#: nova/exception.py:721
+#: nova/exception.py:725
#, python-format
msgid "Security group %(security_group_id)s not found for project %(project_id)s."
msgstr ""
-#: nova/exception.py:726
+#: nova/exception.py:730
#, python-format
msgid "Security group with rule %(rule_id)s not found."
msgstr ""
-#: nova/exception.py:730
+#: nova/exception.py:734
#, python-format
msgid ""
"Security group %(security_group_id)s is already associated with the "
"instance %(instance_id)s"
msgstr ""
-#: nova/exception.py:735
+#: nova/exception.py:739
#, python-format
msgid ""
"Security group %(security_group_id)s is not associated with the instance "
"%(instance_id)s"
msgstr ""
-#: nova/exception.py:740
+#: nova/exception.py:744
#, python-format
msgid "Security group default rule (%rule_id)s not found."
msgstr ""
-#: nova/exception.py:744
+#: nova/exception.py:748
msgid ""
"Network requires port_security_enabled and subnet associated in order to "
"apply security groups."
msgstr ""
-#: nova/exception.py:749
+#: nova/exception.py:753
msgid "No Unique Match Found."
msgstr ""
-#: nova/exception.py:754
+#: nova/exception.py:758
#, python-format
msgid "Migration %(migration_id)s could not be found."
msgstr ""
-#: nova/exception.py:758
+#: nova/exception.py:762
#, python-format
msgid "Migration not found for instance %(instance_id)s with status %(status)s."
msgstr ""
-#: nova/exception.py:763
+#: nova/exception.py:767
#, python-format
msgid "Console pool %(pool_id)s could not be found."
msgstr ""
-#: nova/exception.py:767
+#: nova/exception.py:771
#, python-format
msgid ""
"Console pool of type %(console_type)s for compute host %(compute_host)s "
"on proxy host %(host)s not found."
msgstr ""
-#: nova/exception.py:773
+#: nova/exception.py:777
#, python-format
msgid "Console %(console_id)s could not be found."
msgstr ""
-#: nova/exception.py:777
+#: nova/exception.py:781
#, python-format
msgid "Console for instance %(instance_uuid)s could not be found."
msgstr ""
-#: nova/exception.py:781
+#: nova/exception.py:785
#, python-format
msgid ""
"Console for instance %(instance_uuid)s in pool %(pool_id)s could not be "
"found."
msgstr ""
-#: nova/exception.py:786
+#: nova/exception.py:790
#, python-format
msgid "Invalid console type %(console_type)s"
msgstr ""
-#: nova/exception.py:790
+#: nova/exception.py:794
#, python-format
msgid "Instance type %(instance_type_id)s could not be found."
msgstr ""
-#: nova/exception.py:794
+#: nova/exception.py:798
#, python-format
msgid "Instance type with name %(instance_type_name)s could not be found."
msgstr ""
-#: nova/exception.py:799
+#: nova/exception.py:803
#, python-format
msgid "Flavor %(flavor_id)s could not be found."
msgstr ""
-#: nova/exception.py:803
+#: nova/exception.py:807
#, python-format
msgid "Flavor access not found for %(flavor_id)s / %(project_id)s combination."
msgstr ""
-#: nova/exception.py:808
+#: nova/exception.py:812
#, python-format
msgid "Cell %(cell_name)s doesn't exist."
msgstr ""
-#: nova/exception.py:812
+#: nova/exception.py:816
#, python-format
msgid "Inconsistency in cell routing: %(reason)s"
msgstr ""
-#: nova/exception.py:816
+#: nova/exception.py:820
#, python-format
msgid "Service API method not found: %(detail)s"
msgstr ""
-#: nova/exception.py:820
+#: nova/exception.py:824
msgid "Timeout waiting for response from cell"
msgstr ""
-#: nova/exception.py:824
+#: nova/exception.py:828
#, python-format
msgid "Cell message has reached maximum hop count: %(hop_count)s"
msgstr ""
-#: nova/exception.py:828
+#: nova/exception.py:832
msgid "No cells available matching scheduling criteria."
msgstr ""
-#: nova/exception.py:832
+#: nova/exception.py:836
#, python-format
msgid "Exception received during cell processing: %(exc_name)s."
msgstr ""
-#: nova/exception.py:836
+#: nova/exception.py:840
#, python-format
msgid "Cell is not known for instance %(instance_uuid)s"
msgstr ""
-#: nova/exception.py:840
+#: nova/exception.py:844
#, python-format
msgid "Scheduler Host Filter %(filter_name)s could not be found."
msgstr ""
-#: nova/exception.py:844
+#: nova/exception.py:848
#, python-format
msgid "Scheduler cost function %(cost_fn_str)s could not be found."
msgstr ""
-#: nova/exception.py:849
+#: nova/exception.py:853
#, python-format
msgid "Scheduler weight flag not found: %(flag_name)s"
msgstr ""
-#: nova/exception.py:853
+#: nova/exception.py:857
#, python-format
msgid "Instance %(instance_uuid)s has no metadata with key %(metadata_key)s."
msgstr ""
-#: nova/exception.py:858
+#: nova/exception.py:862
#, python-format
msgid ""
"Instance %(instance_uuid)s has no system metadata with key "
"%(metadata_key)s."
msgstr ""
-#: nova/exception.py:863
+#: nova/exception.py:867
#, python-format
msgid ""
"Instance Type %(instance_type_id)s has no extra specs with key "
"%(extra_specs_key)s."
msgstr ""
-#: nova/exception.py:868
+#: nova/exception.py:872
#, python-format
msgid "File %(file_path)s could not be found."
msgstr ""
-#: nova/exception.py:872
+#: nova/exception.py:876
msgid "Zero files could be found."
msgstr ""
-#: nova/exception.py:876
+#: nova/exception.py:880
#, python-format
msgid "Virtual switch associated with the network adapter %(adapter)s not found."
msgstr ""
-#: nova/exception.py:881
+#: nova/exception.py:885
#, python-format
msgid "Network adapter %(adapter)s could not be found."
msgstr ""
-#: nova/exception.py:885
+#: nova/exception.py:889
#, python-format
msgid "Class %(class_name)s could not be found: %(exception)s"
msgstr ""
-#: nova/exception.py:889
+#: nova/exception.py:893
msgid "Action not allowed."
msgstr ""
-#: nova/exception.py:893
+#: nova/exception.py:897
msgid "Rotation is not allowed for snapshots"
msgstr ""
-#: nova/exception.py:897
+#: nova/exception.py:901
msgid "Rotation param is required for backup image_type"
msgstr ""
-#: nova/exception.py:901
+#: nova/exception.py:905
#, python-format
msgid "Key pair %(key_name)s already exists."
msgstr ""
-#: nova/exception.py:905
+#: nova/exception.py:909
#, python-format
msgid "Instance %(name)s already exists."
msgstr ""
-#: nova/exception.py:909
+#: nova/exception.py:913
#, python-format
msgid "Instance Type with name %(name)s already exists."
msgstr ""
-#: nova/exception.py:913
+#: nova/exception.py:917
#, python-format
msgid "Instance Type with ID %(flavor_id)s already exists."
msgstr ""
-#: nova/exception.py:917
+#: nova/exception.py:921
#, python-format
msgid ""
"Flavor access alreay exists for flavor %(flavor_id)s and project "
"%(project_id)s combination."
msgstr ""
-#: nova/exception.py:922
+#: nova/exception.py:926
#, python-format
msgid "%(path)s is not on shared storage: %(reason)s"
msgstr ""
-#: nova/exception.py:926
+#: nova/exception.py:930
#, python-format
msgid "%(path)s is not on local storage: %(reason)s"
msgstr ""
-#: nova/exception.py:930
+#: nova/exception.py:934
msgid "Migration error"
msgstr ""
-#: nova/exception.py:934
+#: nova/exception.py:938
#, python-format
msgid "Malformed message body: %(reason)s"
msgstr ""
-#: nova/exception.py:940
+#: nova/exception.py:944
#, python-format
msgid "Could not find config at %(path)s"
msgstr ""
-#: nova/exception.py:944
+#: nova/exception.py:948
#, python-format
msgid "Could not load paste app '%(name)s' from %(path)s"
msgstr ""
-#: nova/exception.py:948
+#: nova/exception.py:952
msgid "When resizing, instances must change flavor!"
msgstr ""
-#: nova/exception.py:952
+#: nova/exception.py:956
#, python-format
msgid "Resize error: %(reason)s"
msgstr ""
-#: nova/exception.py:956
+#: nova/exception.py:960
msgid "Image is larger than instance type allows"
msgstr ""
-#: nova/exception.py:960
+#: nova/exception.py:964
msgid "Instance type's memory is too small for requested image."
msgstr ""
-#: nova/exception.py:964
+#: nova/exception.py:968
msgid "Instance type's disk is too small for requested image."
msgstr ""
-#: nova/exception.py:968
+#: nova/exception.py:972
#, python-format
msgid "Insufficient free memory on compute node to start %(uuid)s."
msgstr ""
-#: nova/exception.py:972
+#: nova/exception.py:976
msgid "Could not fetch bandwidth/cpu/disk metrics for this host."
msgstr ""
-#: nova/exception.py:976
+#: nova/exception.py:980
#, python-format
msgid "No valid host was found. %(reason)s"
msgstr ""
-#: nova/exception.py:980
+#: nova/exception.py:984
msgid "Quota exceeded"
msgstr ""
-#: nova/exception.py:987
+#: nova/exception.py:991
#, python-format
msgid ""
"Quota exceeded for %(overs)s: Requested %(req)s, but already used "
"%(used)d of %(allowed)d %(resource)s"
msgstr ""
-#: nova/exception.py:992
+#: nova/exception.py:996
msgid "Maximum number of floating ips exceeded"
msgstr ""
-#: nova/exception.py:996
+#: nova/exception.py:1000
#, python-format
msgid "Maximum number of metadata items exceeds %(allowed)d"
msgstr ""
-#: nova/exception.py:1000
+#: nova/exception.py:1004
msgid "Personality file limit exceeded"
msgstr ""
-#: nova/exception.py:1004
+#: nova/exception.py:1008
msgid "Personality file path too long"
msgstr ""
-#: nova/exception.py:1008
+#: nova/exception.py:1012
msgid "Personality file content too long"
msgstr ""
-#: nova/exception.py:1012
+#: nova/exception.py:1016
msgid "Maximum number of key pairs exceeded"
msgstr ""
-#: nova/exception.py:1016
+#: nova/exception.py:1020
msgid "Maximum number of security groups or rules exceeded"
msgstr ""
-#: nova/exception.py:1020
+#: nova/exception.py:1024
#, python-format
msgid ""
"Aggregate %(aggregate_id)s: action '%(action)s' caused an error: "
"%(reason)s."
msgstr ""
-#: nova/exception.py:1025
+#: nova/exception.py:1029
#, python-format
msgid "Aggregate %(aggregate_id)s could not be found."
msgstr ""
-#: nova/exception.py:1029
+#: nova/exception.py:1033
#, python-format
msgid "Aggregate %(aggregate_name)s already exists."
msgstr ""
-#: nova/exception.py:1033
+#: nova/exception.py:1037
#, python-format
msgid "Aggregate %(aggregate_id)s has no host %(host)s."
msgstr ""
-#: nova/exception.py:1037
+#: nova/exception.py:1041
#, python-format
msgid "Aggregate %(aggregate_id)s has no metadata with key %(metadata_key)s."
msgstr ""
-#: nova/exception.py:1042
+#: nova/exception.py:1046
#, python-format
msgid "Aggregate %(aggregate_id)s already has host %(host)s."
msgstr ""
-#: nova/exception.py:1046
+#: nova/exception.py:1050
msgid "Unable to create instance type"
msgstr ""
-#: nova/exception.py:1050
+#: nova/exception.py:1054
#, python-format
msgid "Failed to set admin password on %(instance)s because %(reason)s"
msgstr ""
-#: nova/exception.py:1056
+#: nova/exception.py:1060
#, python-format
msgid "Detected existing vlan with id %(vlan)d"
msgstr ""
-#: nova/exception.py:1060
+#: nova/exception.py:1064
#, python-format
msgid "Instance %(instance_id)s could not be found."
msgstr ""
-#: nova/exception.py:1064
+#: nova/exception.py:1068
+#, python-format
+msgid "Info cache for instance %(instance_uuid)s could not be found."
+msgstr ""
+
+#: nova/exception.py:1073
#, python-format
msgid "Node %(node_id)s could not be found."
msgstr ""
-#: nova/exception.py:1068
+#: nova/exception.py:1077
#, python-format
msgid "Node with UUID %(node_uuid)s could not be found."
msgstr ""
-#: nova/exception.py:1072
+#: nova/exception.py:1081
#, python-format
msgid "Marker %(marker)s could not be found."
msgstr ""
-#: nova/exception.py:1076
+#: nova/exception.py:1085
#, python-format
msgid "Invalid id: %(val)s (expecting \"i-...\")."
msgstr ""
-#: nova/exception.py:1080
+#: nova/exception.py:1089
#, python-format
msgid "Could not fetch image %(image_id)s"
msgstr ""
-#: nova/exception.py:1084
+#: nova/exception.py:1093
+#, python-format
+msgid "Could not upload image %(image_id)s"
+msgstr ""
+
+#: nova/exception.py:1097
#, python-format
msgid "Task %(task_name)s is already running on host %(host)s"
msgstr ""
-#: nova/exception.py:1088
+#: nova/exception.py:1101
#, python-format
msgid "Task %(task_name)s is not running on host %(host)s"
msgstr ""
-#: nova/exception.py:1092
+#: nova/exception.py:1105
#, python-format
msgid "Instance %(instance_uuid)s is locked"
msgstr ""
-#: nova/exception.py:1096
+#: nova/exception.py:1109
#, python-format
msgid "Could not mount vfat config drive. %(operation)s failed. Error: %(error)s"
msgstr ""
-#: nova/exception.py:1101
+#: nova/exception.py:1114
#, python-format
msgid "Unknown config drive format %(format)s. Select one of iso9660 or vfat."
msgstr ""
-#: nova/exception.py:1106
+#: nova/exception.py:1119
#, python-format
msgid "Failed to attach network adapter device to %(instance)s"
msgstr ""
-#: nova/exception.py:1110
+#: nova/exception.py:1123
#, python-format
msgid "Failed to detach network adapter device from %(instance)s"
msgstr ""
-#: nova/exception.py:1114
+#: nova/exception.py:1127
#, python-format
msgid ""
"User data too large. User data must be no larger than %(maxsize)s bytes "
"once base64 encoded. Your data is %(length)d bytes"
msgstr ""
-#: nova/exception.py:1120
+#: nova/exception.py:1133
msgid "User data needs to be valid base 64."
msgstr ""
-#: nova/exception.py:1124
+#: nova/exception.py:1137
#, python-format
msgid ""
"unexpected task state: expecting %(expected)s but the actual state is "
"%(actual)s"
msgstr ""
-#: nova/exception.py:1129
+#: nova/exception.py:1142
#, python-format
msgid ""
"Action for request_id %(request_id)s on instance %(instance_uuid)s not "
"found"
msgstr ""
-#: nova/exception.py:1134
+#: nova/exception.py:1147
#, python-format
msgid "Event %(event)s not found for action id %(action_id)s"
msgstr ""
-#: nova/exception.py:1138
+#: nova/exception.py:1151
#, python-format
msgid "The CA file for %(project)s could not be found"
msgstr ""
-#: nova/exception.py:1142
+#: nova/exception.py:1155
#, python-format
msgid "The CRL file for %(project)s could not be found"
msgstr ""
-#: nova/exception.py:1146
+#: nova/exception.py:1159
msgid "Instance recreate is not implemented by this virt driver."
msgstr ""
-#: nova/exception.py:1150
+#: nova/exception.py:1163
#, python-format
msgid "The service from servicegroup driver %(driver) is temporarily unavailable."
msgstr ""
-#: nova/exception.py:1155
+#: nova/exception.py:1168
#, python-format
msgid "%(binary)s attempted direct database access which is not allowed by policy"
msgstr ""
-#: nova/exception.py:1160
+#: nova/exception.py:1173
#, python-format
msgid "Virtualization type '%(virt)s' is not supported by this compute driver"
msgstr ""
-#: nova/exception.py:1165
+#: nova/exception.py:1178
#, python-format
msgid ""
"Requested hardware '%(model)s' is not supported by the '%(virt)s' virt "
@@ -1433,7 +1448,7 @@ msgid "Running cmd (subprocess): %s"
msgstr ""
#: nova/utils.py:236 nova/utils.py:314
-#: nova/openstack/common/processutils.py:114 nova/virt/powervm/common.py:86
+#: nova/openstack/common/processutils.py:114 nova/virt/powervm/common.py:88
#, python-format
msgid "Result was %s"
msgstr ""
@@ -1489,47 +1504,47 @@ msgstr ""
msgid "in dynamic looping call"
msgstr ""
-#: nova/utils.py:742
+#: nova/utils.py:756
#, python-format
msgid "Unknown byte multiplier: %s"
msgstr ""
-#: nova/utils.py:871
+#: nova/utils.py:885
#, python-format
msgid "Expected object of type: %s"
msgstr ""
-#: nova/utils.py:900
+#: nova/utils.py:914
#, python-format
msgid "Invalid server_string: %s"
msgstr ""
-#: nova/utils.py:1054
+#: nova/utils.py:1068
#, python-format
msgid "timefunc: '%(name)s' took %(total_time).2f secs"
msgstr ""
-#: nova/utils.py:1120
+#: nova/utils.py:1134
#, python-format
msgid "Reloading cached file %s"
msgstr ""
-#: nova/utils.py:1252 nova/virt/configdrive.py:177
+#: nova/utils.py:1266 nova/virt/configdrive.py:177
#, python-format
msgid "Could not remove tmpdir: %s"
msgstr ""
-#: nova/utils.py:1430
+#: nova/utils.py:1444
#, python-format
msgid "%s is not a string or unicode"
msgstr ""
-#: nova/utils.py:1434
+#: nova/utils.py:1448
#, python-format
msgid "%(name)s has less than %(min_length)s characters."
msgstr ""
-#: nova/utils.py:1439
+#: nova/utils.py:1453
#, python-format
msgid "%(name)s has more than %(max_length)s characters."
msgstr ""
@@ -1772,205 +1787,205 @@ msgstr ""
msgid "Delete key pair %s"
msgstr ""
-#: nova/api/ec2/cloud.py:604 nova/api/ec2/cloud.py:725
+#: nova/api/ec2/cloud.py:612 nova/api/ec2/cloud.py:733
msgid "Not enough parameters, need group_name or group_id"
msgstr ""
-#: nova/api/ec2/cloud.py:609
+#: nova/api/ec2/cloud.py:617
#, python-format
msgid "%s Not enough parameters to build a valid rule"
msgstr ""
-#: nova/api/ec2/cloud.py:647 nova/api/ec2/cloud.py:679
+#: nova/api/ec2/cloud.py:655 nova/api/ec2/cloud.py:687
msgid "No rule for the specified parameters."
msgstr ""
-#: nova/api/ec2/cloud.py:670
+#: nova/api/ec2/cloud.py:678
#, python-format
msgid "%s - This rule already exists in group"
msgstr ""
-#: nova/api/ec2/cloud.py:753
+#: nova/api/ec2/cloud.py:761
#, python-format
msgid "Get console output for instance %s"
msgstr ""
-#: nova/api/ec2/cloud.py:829
+#: nova/api/ec2/cloud.py:837
#, python-format
msgid "Create volume from snapshot %s"
msgstr ""
-#: nova/api/ec2/cloud.py:833 nova/api/openstack/compute/contrib/volumes.py:243
+#: nova/api/ec2/cloud.py:841 nova/api/openstack/compute/contrib/volumes.py:243
#, python-format
msgid "Create volume of %s GB"
msgstr ""
-#: nova/api/ec2/cloud.py:861
+#: nova/api/ec2/cloud.py:869
msgid "Delete Failed"
msgstr ""
-#: nova/api/ec2/cloud.py:874
+#: nova/api/ec2/cloud.py:882
#, python-format
msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s"
msgstr ""
-#: nova/api/ec2/cloud.py:882
+#: nova/api/ec2/cloud.py:890
msgid "Attach Failed."
msgstr ""
-#: nova/api/ec2/cloud.py:895 nova/api/openstack/compute/contrib/volumes.py:435
+#: nova/api/ec2/cloud.py:903 nova/api/openstack/compute/contrib/volumes.py:435
#, python-format
msgid "Detach volume %s"
msgstr ""
-#: nova/api/ec2/cloud.py:901
+#: nova/api/ec2/cloud.py:909
msgid "Detach Volume Failed."
msgstr ""
-#: nova/api/ec2/cloud.py:927 nova/api/ec2/cloud.py:984
-#: nova/api/ec2/cloud.py:1537 nova/api/ec2/cloud.py:1552
+#: nova/api/ec2/cloud.py:935 nova/api/ec2/cloud.py:992
+#: nova/api/ec2/cloud.py:1545 nova/api/ec2/cloud.py:1560
#, python-format
msgid "attribute not supported: %s"
msgstr ""
-#: nova/api/ec2/cloud.py:1058
+#: nova/api/ec2/cloud.py:1066
#, python-format
msgid "vol = %s\n"
msgstr ""
-#: nova/api/ec2/cloud.py:1217
+#: nova/api/ec2/cloud.py:1225
msgid "Allocate address"
msgstr ""
-#: nova/api/ec2/cloud.py:1221
+#: nova/api/ec2/cloud.py:1229
msgid "No more floating IPs available"
msgstr ""
-#: nova/api/ec2/cloud.py:1225
+#: nova/api/ec2/cloud.py:1233
#, python-format
msgid "Release address %s"
msgstr ""
-#: nova/api/ec2/cloud.py:1230
+#: nova/api/ec2/cloud.py:1238
msgid "Unable to release IP Address."
msgstr ""
-#: nova/api/ec2/cloud.py:1233
+#: nova/api/ec2/cloud.py:1241
#, python-format
msgid "Associate address %(public_ip)s to instance %(instance_id)s"
msgstr ""
-#: nova/api/ec2/cloud.py:1241
+#: nova/api/ec2/cloud.py:1249
msgid "Unable to associate IP Address, no fixed_ips."
msgstr ""
-#: nova/api/ec2/cloud.py:1249
+#: nova/api/ec2/cloud.py:1257
#: nova/api/openstack/compute/contrib/floating_ips.py:238
#, python-format
msgid "multiple fixed_ips exist, using the first: %s"
msgstr ""
-#: nova/api/ec2/cloud.py:1258
+#: nova/api/ec2/cloud.py:1266
msgid "Floating ip is already associated."
msgstr ""
-#: nova/api/ec2/cloud.py:1261
+#: nova/api/ec2/cloud.py:1269
msgid "l3driver call to add floating ip failed."
msgstr ""
-#: nova/api/ec2/cloud.py:1264
+#: nova/api/ec2/cloud.py:1272
msgid "Error, unable to associate floating ip."
msgstr ""
-#: nova/api/ec2/cloud.py:1272
+#: nova/api/ec2/cloud.py:1280
#, python-format
msgid "Disassociate address %s"
msgstr ""
-#: nova/api/ec2/cloud.py:1277
+#: nova/api/ec2/cloud.py:1285
msgid "Floating ip is not associated."
msgstr ""
-#: nova/api/ec2/cloud.py:1280
+#: nova/api/ec2/cloud.py:1288
#: nova/api/openstack/compute/contrib/floating_ips.py:100
msgid "Cannot disassociate auto assigned floating ip"
msgstr ""
-#: nova/api/ec2/cloud.py:1307
+#: nova/api/ec2/cloud.py:1315
msgid "Image must be available"
msgstr ""
-#: nova/api/ec2/cloud.py:1339
+#: nova/api/ec2/cloud.py:1347
msgid "Going to start terminating instances"
msgstr ""
-#: nova/api/ec2/cloud.py:1349
+#: nova/api/ec2/cloud.py:1357
#, python-format
msgid "Reboot instance %r"
msgstr ""
-#: nova/api/ec2/cloud.py:1358
+#: nova/api/ec2/cloud.py:1366
msgid "Going to stop instances"
msgstr ""
-#: nova/api/ec2/cloud.py:1367
+#: nova/api/ec2/cloud.py:1375
msgid "Going to start instances"
msgstr ""
-#: nova/api/ec2/cloud.py:1458
+#: nova/api/ec2/cloud.py:1466
#, python-format
msgid "De-registering image %s"
msgstr ""
-#: nova/api/ec2/cloud.py:1474
+#: nova/api/ec2/cloud.py:1482
msgid "imageLocation is required"
msgstr ""
-#: nova/api/ec2/cloud.py:1493
+#: nova/api/ec2/cloud.py:1501
#, python-format
msgid "Registered image %(image_location)s with id %(image_id)s"
msgstr ""
-#: nova/api/ec2/cloud.py:1555
+#: nova/api/ec2/cloud.py:1563
msgid "user or group not specified"
msgstr ""
-#: nova/api/ec2/cloud.py:1557
+#: nova/api/ec2/cloud.py:1565
msgid "only group \"all\" is supported"
msgstr ""
-#: nova/api/ec2/cloud.py:1559
+#: nova/api/ec2/cloud.py:1567
msgid "operation_type must be add or remove"
msgstr ""
-#: nova/api/ec2/cloud.py:1561
+#: nova/api/ec2/cloud.py:1569
#, python-format
msgid "Updating image %s publicity"
msgstr ""
-#: nova/api/ec2/cloud.py:1574
+#: nova/api/ec2/cloud.py:1582
#, python-format
msgid "Not allowed to modify attributes for image %s"
msgstr ""
-#: nova/api/ec2/cloud.py:1603
+#: nova/api/ec2/cloud.py:1611
#, python-format
msgid ""
"Invalid value '%(ec2_instance_id)s' for instanceId. Instance does not "
"have a volume attached at root (%(root)s)"
msgstr ""
-#: nova/api/ec2/cloud.py:1633
+#: nova/api/ec2/cloud.py:1641
#, python-format
msgid "Couldn't stop instance with in %d sec"
msgstr ""
-#: nova/api/ec2/cloud.py:1651
+#: nova/api/ec2/cloud.py:1659
#, python-format
msgid "image of %(instance)s at %(now)s"
msgstr ""
-#: nova/api/ec2/cloud.py:1684
+#: nova/api/ec2/cloud.py:1692
msgid "Invalid CIDR"
msgstr ""
@@ -2568,7 +2583,7 @@ msgstr ""
#: nova/api/openstack/compute/servers.py:1220
#: nova/api/openstack/compute/contrib/aggregates.py:143
-#: nova/api/openstack/compute/contrib/coverage_ext.py:256
+#: nova/api/openstack/compute/contrib/coverage_ext.py:277
#: nova/api/openstack/compute/contrib/keypairs.py:78
msgid "Invalid request body"
msgstr ""
@@ -2791,7 +2806,7 @@ msgid ""
"again in a few minutes"
msgstr ""
-#: nova/api/openstack/compute/contrib/cloudpipe_update.py:44
+#: nova/api/openstack/compute/contrib/cloudpipe_update.py:43
#, python-format
msgid "Unknown action %s"
msgstr ""
@@ -2808,46 +2823,46 @@ msgstr ""
msgid "Unable to get console"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:105
+#: nova/api/openstack/compute/contrib/coverage_ext.py:114
#, python-format
msgid "Can't connect to service: %s, no portspecified\n"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:108
+#: nova/api/openstack/compute/contrib/coverage_ext.py:117
#, python-format
msgid "No backdoor API command for service: %s\n"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:127
+#: nova/api/openstack/compute/contrib/coverage_ext.py:135
msgid "Coverage begin"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:161
+#: nova/api/openstack/compute/contrib/coverage_ext.py:182
msgid "Coverage not running"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:190
+#: nova/api/openstack/compute/contrib/coverage_ext.py:211
msgid "Invalid path"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:194
+#: nova/api/openstack/compute/contrib/coverage_ext.py:215
msgid "No path given for report file"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:201
+#: nova/api/openstack/compute/contrib/coverage_ext.py:222
msgid "You can't use html reports without combining"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:211
+#: nova/api/openstack/compute/contrib/coverage_ext.py:232
#, python-format
msgid "Directory conflict: %s already exists"
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:246
+#: nova/api/openstack/compute/contrib/coverage_ext.py:267
msgid "Python coverage module is not installed."
msgstr ""
-#: nova/api/openstack/compute/contrib/coverage_ext.py:254
+#: nova/api/openstack/compute/contrib/coverage_ext.py:275
#, python-format
msgid "Coverage doesn't have %s action"
msgstr ""
@@ -2874,12 +2889,12 @@ msgstr ""
msgid "Error in evacuate, %s"
msgstr ""
-#: nova/api/openstack/compute/contrib/fixed_ips.py:42
+#: nova/api/openstack/compute/contrib/fixed_ips.py:41
#, python-format
msgid "Fixed IP %s has been deleted"
msgstr ""
-#: nova/api/openstack/compute/contrib/fixed_ips.py:74
+#: nova/api/openstack/compute/contrib/fixed_ips.py:73
#, python-format
msgid "Fixed IP %s not found"
msgstr ""
@@ -2960,7 +2975,7 @@ msgstr ""
msgid "Error. Unable to associate floating ip"
msgstr ""
-#: nova/api/openstack/compute/contrib/floating_ips_bulk.py:147
+#: nova/api/openstack/compute/contrib/floating_ips_bulk.py:146
#, python-format
msgid "/%s should be specified as single address(es) not in cidr format"
msgstr ""
@@ -3312,34 +3327,34 @@ msgstr ""
msgid "Got update for instance %(instance_uuid)s: %(instance)s"
msgstr ""
-#: nova/cells/messaging.py:782
+#: nova/cells/messaging.py:787
#, python-format
msgid "Got update to delete instance %(instance_uuid)s"
msgstr ""
-#: nova/cells/messaging.py:797
+#: nova/cells/messaging.py:802
#, python-format
msgid "Got broadcast to %(delete_type)s delete instance"
msgstr ""
-#: nova/cells/messaging.py:811
+#: nova/cells/messaging.py:816
#, python-format
msgid "Got message to create instance fault: %(instance_fault)s"
msgstr ""
-#: nova/cells/messaging.py:832
+#: nova/cells/messaging.py:837
#, python-format
msgid ""
"Forcing a sync of instances, project_id=%(projid_str)s, "
"updated_since=%(since_str)s"
msgstr ""
-#: nova/cells/messaging.py:1009
+#: nova/cells/messaging.py:1014
#, python-format
msgid "Updating parents with our capabilities: %(capabs)s"
msgstr ""
-#: nova/cells/messaging.py:1029
+#: nova/cells/messaging.py:1034
#, python-format
msgid "Updating parents with our capacities: %(capacities)s"
msgstr ""
@@ -3431,207 +3446,202 @@ msgstr ""
msgid "Metadata property value greater than 255 characters"
msgstr ""
-#: nova/compute/api.py:436
+#: nova/compute/api.py:449
msgid "Failed to set instance name using multi_instance_display_name_template."
msgstr ""
-#: nova/compute/api.py:476
+#: nova/compute/api.py:489
msgid "Cannot attach one or more volumes to multiple instances"
msgstr ""
-#: nova/compute/api.py:589
+#: nova/compute/api.py:603
#, python-format
msgid "Going to run %s instances..."
msgstr ""
-#: nova/compute/api.py:701
+#: nova/compute/api.py:716
#, python-format
msgid "bdm %s"
msgstr ""
-#: nova/compute/api.py:728
+#: nova/compute/api.py:743
#, python-format
msgid "block_device_mapping %s"
msgstr ""
-#: nova/compute/api.py:1001
+#: nova/compute/api.py:1015
msgid "instance termination disabled"
msgstr ""
-#: nova/compute/api.py:1135
+#: nova/compute/api.py:1149
#, python-format
msgid "instance type %(old_inst_type_id)d not found"
msgstr ""
-#: nova/compute/api.py:1141
+#: nova/compute/api.py:1155
msgid "going to delete a resizing instance"
msgstr ""
-#: nova/compute/api.py:1151
+#: nova/compute/api.py:1165
#, python-format
msgid "instance's host %s is down, deleting from database"
msgstr ""
-#: nova/compute/api.py:1195
+#: nova/compute/api.py:1209
msgid "Going to try to soft delete instance"
msgstr ""
-#: nova/compute/api.py:1217
+#: nova/compute/api.py:1231
msgid "Going to try to terminate instance"
msgstr ""
-#: nova/compute/api.py:1267
+#: nova/compute/api.py:1281
msgid "Going to try to stop instance"
msgstr ""
-#: nova/compute/api.py:1284
+#: nova/compute/api.py:1298
msgid "Going to try to start instance"
msgstr ""
-#: nova/compute/api.py:1354
+#: nova/compute/api.py:1371
#, python-format
msgid "Searching by: %s"
msgstr ""
-#: nova/compute/api.py:1598
+#: nova/compute/api.py:1615
#, python-format
msgid "snapshot for %s"
msgstr ""
-#: nova/compute/api.py:1954
+#: nova/compute/api.py:1971
msgid "flavor_id is None. Assuming migration."
msgstr ""
-#: nova/compute/api.py:1963
+#: nova/compute/api.py:1980
#, python-format
msgid ""
"Old instance type %(current_instance_type_name)s, new instance type "
"%(new_instance_type_name)s"
msgstr ""
-#: nova/compute/api.py:2005
+#: nova/compute/api.py:2022
#, python-format
msgid "%(overs)s quota exceeded for %(pid)s, tried to resize instance."
msgstr ""
-#: nova/compute/api.py:2238
+#: nova/compute/api.py:2255
msgid "Locking"
msgstr ""
-#: nova/compute/api.py:2246
+#: nova/compute/api.py:2263
msgid "Unlocking"
msgstr ""
-#: nova/compute/api.py:2314
+#: nova/compute/api.py:2331
msgid "Volume must be attached in order to detach."
msgstr ""
-#: nova/compute/api.py:2421
+#: nova/compute/api.py:2438
#, python-format
msgid "Going to try to live migrate instance to %s"
msgstr ""
-#: nova/compute/api.py:2440
+#: nova/compute/api.py:2457
msgid "vm evacuation scheduled"
msgstr ""
-#: nova/compute/api.py:2444
+#: nova/compute/api.py:2461
#, python-format
msgid ""
-"Instance compute service state on %(host)s expected to be down, but it "
-"was up."
+"Instance compute service state on %(inst_host)s expected to be down, but "
+"it was up."
msgstr ""
-#: nova/compute/api.py:2664
+#: nova/compute/api.py:2681
msgid "Keypair name contains unsafe characters"
msgstr ""
-#: nova/compute/api.py:2668
+#: nova/compute/api.py:2685
msgid "Keypair name must be between 1 and 255 characters long"
msgstr ""
-#: nova/compute/api.py:2773
+#: nova/compute/api.py:2790
#, python-format
msgid "Security group %s is not a string or unicode"
msgstr ""
-#: nova/compute/api.py:2776
+#: nova/compute/api.py:2793
#, python-format
msgid "Security group %s cannot be empty."
msgstr ""
-#: nova/compute/api.py:2784
+#: nova/compute/api.py:2801
#, python-format
msgid ""
"Value (%(value)s) for parameter Group%(property)s is invalid. Content "
"limited to '%(allowed)'."
msgstr ""
-#: nova/compute/api.py:2790
+#: nova/compute/api.py:2807
#, python-format
msgid "Security group %s should not be greater than 255 characters."
msgstr ""
-#: nova/compute/api.py:2810
+#: nova/compute/api.py:2827
msgid "Quota exceeded, too many security groups."
msgstr ""
-#: nova/compute/api.py:2813
+#: nova/compute/api.py:2830
#, python-format
msgid "Create Security Group %s"
msgstr ""
-#: nova/compute/api.py:2820
+#: nova/compute/api.py:2837
#, python-format
msgid "Security group %s already exists"
msgstr ""
-#: nova/compute/api.py:2885
+#: nova/compute/api.py:2902
#, python-format
msgid "Unable to delete system group '%s'"
msgstr ""
-#: nova/compute/api.py:2890
+#: nova/compute/api.py:2907
msgid "Security group is still in use"
msgstr ""
-#: nova/compute/api.py:2898
+#: nova/compute/api.py:2915
msgid "Failed to update usages deallocating security group"
msgstr ""
-#: nova/compute/api.py:2901
+#: nova/compute/api.py:2918
#, python-format
msgid "Delete security group %s"
msgstr ""
-#: nova/compute/api.py:3010 nova/compute/api.py:3087
+#: nova/compute/api.py:3012 nova/compute/api.py:3089
#, python-format
msgid "Rule (%s) not found"
msgstr ""
-#: nova/compute/api.py:3026
+#: nova/compute/api.py:3028
msgid "Quota exceeded, too many security group rules."
msgstr ""
-#: nova/compute/api.py:3029
+#: nova/compute/api.py:3031
#, python-format
msgid "Authorize security group ingress %s"
msgstr ""
-#: nova/compute/api.py:3040
+#: nova/compute/api.py:3042
#, python-format
msgid "Revoke security group ingress %s"
msgstr ""
-#: nova/compute/api.py:3094
+#: nova/compute/api.py:3096
msgid "Security group id should be integer"
msgstr ""
-#: nova/compute/api.py:3099
-#, python-format
-msgid "This rule already exists in group %s"
-msgstr ""
-
#: nova/compute/claims.py:94 nova/compute/claims.py:218
#, python-format
msgid "Aborting claim: %s"
@@ -3722,569 +3732,590 @@ msgstr ""
msgid "Possibly task preempted."
msgstr ""
-#: nova/compute/manager.py:350
+#: nova/compute/manager.py:354
#, python-format
msgid "%(nodename)s is not a valid node managed by this compute host."
msgstr ""
-#: nova/compute/manager.py:379
+#: nova/compute/manager.py:383
msgid "Instance has been destroyed from under us while trying to set it to ERROR"
msgstr ""
-#: nova/compute/manager.py:398
+#: nova/compute/manager.py:397
#, python-format
msgid "Instance %(uuid)s found in the hypervisor, but not in the database"
msgstr ""
-#: nova/compute/manager.py:416
+#: nova/compute/manager.py:413
#, python-format
msgid ""
"Instance %(driver_instance)s found in the hypervisor, but not in the "
"database"
msgstr ""
-#: nova/compute/manager.py:437
+#: nova/compute/manager.py:434
#, python-format
msgid ""
"Deleting instance as its host (%(instance_host)s) is not equal to our "
"host (%(our_host)s)."
msgstr ""
-#: nova/compute/manager.py:464
+#: nova/compute/manager.py:471
+msgid "Failed to revert crashed migration"
+msgstr ""
+
+#: nova/compute/manager.py:474
+msgid "Instance found in migrating state during startup. Resetting task_state"
+msgstr ""
+
+#: nova/compute/manager.py:485
#, python-format
msgid "Current state is %(drv_state)s, state in DB is %(db_state)s."
msgstr ""
-#: nova/compute/manager.py:476
+#: nova/compute/manager.py:490
msgid "Rebooting instance after nova-compute restart."
msgstr ""
-#: nova/compute/manager.py:490
+#: nova/compute/manager.py:504
msgid "Hypervisor driver does not support resume guests"
msgstr ""
-#: nova/compute/manager.py:495
+#: nova/compute/manager.py:509
msgid "Failed to resume instance"
msgstr ""
-#: nova/compute/manager.py:505
+#: nova/compute/manager.py:519
msgid "Hypervisor driver does not support firewall rules"
msgstr ""
-#: nova/compute/manager.py:509
+#: nova/compute/manager.py:523
#, python-format
msgid "Lifecycle event %(state)d on VM %(uuid)s"
msgstr ""
-#: nova/compute/manager.py:525
+#: nova/compute/manager.py:539
#, python-format
msgid "Unexpected power state %d"
msgstr ""
-#: nova/compute/manager.py:537
+#: nova/compute/manager.py:551
#, python-format
msgid "Ignoring event %s"
msgstr ""
-#: nova/compute/manager.py:575
+#: nova/compute/manager.py:589
msgid "Checking state"
msgstr ""
-#: nova/compute/manager.py:655
+#: nova/compute/manager.py:669
#, python-format
msgid "Setting up bdm %s"
msgstr ""
-#: nova/compute/manager.py:737 nova/compute/manager.py:2077
+#: nova/compute/manager.py:751 nova/compute/manager.py:2104
#, python-format
msgid "No node specified, defaulting to %(node)s"
msgstr ""
-#: nova/compute/manager.py:780
+#: nova/compute/manager.py:794
msgid "Failed to dealloc network for deleted instance"
msgstr ""
-#: nova/compute/manager.py:805
+#: nova/compute/manager.py:800
+msgid "Instance was deleted during spawn."
+msgstr ""
+
+#: nova/compute/manager.py:826
#, python-format
msgid "Error: %s"
msgstr ""
-#: nova/compute/manager.py:840 nova/compute/manager.py:2131
+#: nova/compute/manager.py:861 nova/compute/manager.py:2158
msgid "Error trying to reschedule"
msgstr ""
-#: nova/compute/manager.py:858
+#: nova/compute/manager.py:879
msgid "Retry info not present, will not reschedule"
msgstr ""
-#: nova/compute/manager.py:863
+#: nova/compute/manager.py:884
msgid "No request spec, will not reschedule"
msgstr ""
-#: nova/compute/manager.py:869
+#: nova/compute/manager.py:890
#, python-format
msgid "Re-scheduling %(method)s: attempt %(num)d"
msgstr ""
-#: nova/compute/manager.py:897
+#: nova/compute/manager.py:918
msgid "Instance build timed out. Set to error state."
msgstr ""
-#: nova/compute/manager.py:973
+#: nova/compute/manager.py:994
#, python-format
msgid ""
"image_id=%(image_id)s, image_size_bytes=%(size_bytes)d, "
"allowed_size_bytes=%(allowed_size_bytes)d"
msgstr ""
-#: nova/compute/manager.py:979
+#: nova/compute/manager.py:1000
#, python-format
msgid ""
"Image '%(image_id)s' size %(size_bytes)d exceeded instance_type allowed "
"size %(allowed_size_bytes)d"
msgstr ""
-#: nova/compute/manager.py:989
+#: nova/compute/manager.py:1010
msgid "Starting instance..."
msgstr ""
-#: nova/compute/manager.py:1014
+#: nova/compute/manager.py:1035
msgid "Instance failed network setup"
msgstr ""
-#: nova/compute/manager.py:1018
+#: nova/compute/manager.py:1039
#, python-format
msgid "Instance network_info: |%s|"
msgstr ""
-#: nova/compute/manager.py:1028
+#: nova/compute/manager.py:1049
msgid "Instance failed block device setup"
msgstr ""
-#: nova/compute/manager.py:1045
+#: nova/compute/manager.py:1066
msgid "Instance failed to spawn"
msgstr ""
-#: nova/compute/manager.py:1069
+#: nova/compute/manager.py:1090
msgid "Deallocating network for instance"
msgstr ""
-#: nova/compute/manager.py:1145
+#: nova/compute/manager.py:1166
#, python-format
msgid "%(action_str)s instance"
msgstr ""
-#: nova/compute/manager.py:1176
+#: nova/compute/manager.py:1182
+msgid "Failed to deallocate network for instance."
+msgstr ""
+
+#: nova/compute/manager.py:1203
#, python-format
msgid "Ignoring DiskNotFound: %s"
msgstr ""
-#: nova/compute/manager.py:1179
+#: nova/compute/manager.py:1206
#, python-format
msgid "Ignoring VolumeNotFound: %s"
msgstr ""
-#: nova/compute/manager.py:1186
+#: nova/compute/manager.py:1213
#, python-format
msgid "terminating bdm %s"
msgstr ""
-#: nova/compute/manager.py:1211
+#: nova/compute/manager.py:1238
#, python-format
msgid "Ignoring volume cleanup failure due to %s"
msgstr ""
-#: nova/compute/manager.py:1254 nova/compute/manager.py:2306
-#: nova/compute/manager.py:3739
+#: nova/compute/manager.py:1281 nova/compute/manager.py:2333
+#: nova/compute/manager.py:3773
#, python-format
msgid "%s. Setting instance vm_state to ERROR"
msgstr ""
-#: nova/compute/manager.py:1394
+#: nova/compute/manager.py:1421
msgid "Rebuilding instance"
msgstr ""
-#: nova/compute/manager.py:1407
+#: nova/compute/manager.py:1434
msgid "Invalid state of instance files on shared storage"
msgstr ""
-#: nova/compute/manager.py:1411
+#: nova/compute/manager.py:1438
msgid "disk on shared storage, recreating using existing disk"
msgstr ""
-#: nova/compute/manager.py:1415
+#: nova/compute/manager.py:1442
#, python-format
msgid "disk not on shared storagerebuilding from: '%s'"
msgstr ""
-#: nova/compute/manager.py:1499
+#: nova/compute/manager.py:1526
#, python-format
msgid "bringing vm to original state: '%s'"
msgstr ""
-#: nova/compute/manager.py:1523
+#: nova/compute/manager.py:1550
msgid "Rebooting instance"
msgstr ""
-#: nova/compute/manager.py:1542
+#: nova/compute/manager.py:1569
#, python-format
msgid ""
"trying to reboot a non-running instance: (state: %(state)s expected: "
"%(running)s)"
msgstr ""
-#: nova/compute/manager.py:1552
+#: nova/compute/manager.py:1579
#, python-format
msgid "Cannot reboot instance: %(exc)s"
msgstr ""
-#: nova/compute/manager.py:1588
+#: nova/compute/manager.py:1615
msgid "instance snapshotting"
msgstr ""
-#: nova/compute/manager.py:1594
+#: nova/compute/manager.py:1621
#, python-format
msgid ""
"trying to snapshot a non-running instance: (state: %(state)s expected: "
"%(running)s)"
msgstr ""
-#: nova/compute/manager.py:1655
+#: nova/compute/manager.py:1682
#, python-format
msgid "Found %(num_images)d images (rotation: %(rotation)d)"
msgstr ""
-#: nova/compute/manager.py:1662
+#: nova/compute/manager.py:1689
#, python-format
msgid "Rotating out %d backups"
msgstr ""
-#: nova/compute/manager.py:1667
+#: nova/compute/manager.py:1694
#, python-format
msgid "Deleting image %s"
msgstr ""
-#: nova/compute/manager.py:1695
+#: nova/compute/manager.py:1722
#, python-format
msgid "Failed to set admin password. Instance %s is not running"
msgstr ""
-#: nova/compute/manager.py:1702
+#: nova/compute/manager.py:1729
msgid "Root password set"
msgstr ""
-#: nova/compute/manager.py:1709
+#: nova/compute/manager.py:1736
msgid "set_admin_password is not implemented by this driver or guest instance."
msgstr ""
-#: nova/compute/manager.py:1724
+#: nova/compute/manager.py:1751
#, python-format
msgid "set_admin_password failed: %s"
msgstr ""
-#: nova/compute/manager.py:1731
+#: nova/compute/manager.py:1758
msgid "error setting admin password"
msgstr ""
-#: nova/compute/manager.py:1744
+#: nova/compute/manager.py:1771
#, python-format
msgid ""
"trying to inject a file into a non-running (state: "
"%(current_power_state)s expected: %(expected_state)s)"
msgstr ""
-#: nova/compute/manager.py:1748
+#: nova/compute/manager.py:1775
#, python-format
msgid "injecting file to %(path)s"
msgstr ""
-#: nova/compute/manager.py:1768
+#: nova/compute/manager.py:1795
msgid ""
"Unable to find a different image to use for rescue VM, using instance's "
"current image"
msgstr ""
-#: nova/compute/manager.py:1782
+#: nova/compute/manager.py:1809
msgid "Rescuing"
msgstr ""
-#: nova/compute/manager.py:1817
+#: nova/compute/manager.py:1844
msgid "Unrescuing"
msgstr ""
-#: nova/compute/manager.py:1838
+#: nova/compute/manager.py:1865
#, python-format
msgid "Changing instance metadata according to %(diff)r"
msgstr ""
-#: nova/compute/manager.py:2035
+#: nova/compute/manager.py:2062
msgid "Instance has no source host"
msgstr ""
-#: nova/compute/manager.py:2041
+#: nova/compute/manager.py:2068
msgid "destination same as source!"
msgstr ""
-#: nova/compute/manager.py:2058
+#: nova/compute/manager.py:2085
msgid "Migrating"
msgstr ""
-#: nova/compute/manager.py:2303
+#: nova/compute/manager.py:2330
#, python-format
msgid "Failed to rollback quota for failed finish_resize: %(qr_error)s"
msgstr ""
-#: nova/compute/manager.py:2358
+#: nova/compute/manager.py:2385
msgid "Pausing"
msgstr ""
-#: nova/compute/manager.py:2376
+#: nova/compute/manager.py:2403
msgid "Unpausing"
msgstr ""
-#: nova/compute/manager.py:2414
+#: nova/compute/manager.py:2441
msgid "Retrieving diagnostics"
msgstr ""
-#: nova/compute/manager.py:2445
+#: nova/compute/manager.py:2472
msgid "Resuming"
msgstr ""
-#: nova/compute/manager.py:2465
+#: nova/compute/manager.py:2492
msgid "Reset network"
msgstr ""
-#: nova/compute/manager.py:2470
+#: nova/compute/manager.py:2497
msgid "Inject network info"
msgstr ""
-#: nova/compute/manager.py:2473
+#: nova/compute/manager.py:2500
#, python-format
msgid "network_info to inject: |%s|"
msgstr ""
-#: nova/compute/manager.py:2490
+#: nova/compute/manager.py:2517
msgid "Get console output"
msgstr ""
-#: nova/compute/manager.py:2515
+#: nova/compute/manager.py:2542
msgid "Getting vnc console"
msgstr ""
-#: nova/compute/manager.py:2543
+#: nova/compute/manager.py:2570
msgid "Getting spice console"
msgstr ""
-#: nova/compute/manager.py:2583
+#: nova/compute/manager.py:2610
#, python-format
msgid "Booting with volume %(volume_id)s at %(mountpoint)s"
msgstr ""
-#: nova/compute/manager.py:2634
+#: nova/compute/manager.py:2661
#, python-format
msgid "Attaching volume %(volume_id)s to %(mountpoint)s"
msgstr ""
-#: nova/compute/manager.py:2643
+#: nova/compute/manager.py:2670
#, python-format
msgid ""
"Failed to connect to volume %(volume_id)s while attaching at "
"%(mountpoint)s"
msgstr ""
-#: nova/compute/manager.py:2658
+#: nova/compute/manager.py:2685
#, python-format
msgid "Failed to attach volume %(volume_id)s at %(mountpoint)s"
msgstr ""
-#: nova/compute/manager.py:2688
+#: nova/compute/manager.py:2715
#, python-format
msgid "Detach volume %(volume_id)s from mountpoint %(mp)s"
msgstr ""
-#: nova/compute/manager.py:2698
+#: nova/compute/manager.py:2725
msgid "Detaching volume from unknown instance"
msgstr ""
-#: nova/compute/manager.py:2705
+#: nova/compute/manager.py:2732
#, python-format
msgid "Failed to detach volume %(volume_id)s from %(mp)s"
msgstr ""
-#: nova/compute/manager.py:2729
+#: nova/compute/manager.py:2756
msgid "Updating volume usage cache with totals"
msgstr ""
-#: nova/compute/manager.py:2785
+#: nova/compute/manager.py:2794
+#, python-format
+msgid "allocate_port_for_instance returned %(port)s ports"
+msgstr ""
+
+#: nova/compute/manager.py:2814
#, python-format
msgid "Port %(port_id)s is not attached"
msgstr ""
-#: nova/compute/manager.py:2799
+#: nova/compute/manager.py:2828
#, python-format
msgid "Host %(host)s not found"
msgstr ""
-#: nova/compute/manager.py:2928
+#: nova/compute/manager.py:2957
#, python-format
msgid "Pre live migration failed at %(dest)s"
msgstr ""
-#: nova/compute/manager.py:2956
+#: nova/compute/manager.py:2985
msgid "_post_live_migration() is started.."
msgstr ""
-#: nova/compute/manager.py:3011
+#: nova/compute/manager.py:3040
#, python-format
msgid "Migrating instance to %(dest)s finished successfully."
msgstr ""
-#: nova/compute/manager.py:3013
+#: nova/compute/manager.py:3042
msgid ""
"You may see the error \"libvirt: QEMU error: Domain not found: no domain "
"with matching name.\" This error can be safely ignored."
msgstr ""
-#: nova/compute/manager.py:3027
+#: nova/compute/manager.py:3056
msgid "Post operation of migration started"
msgstr ""
-#: nova/compute/manager.py:3167
+#: nova/compute/manager.py:3196
msgid "Updated the info_cache for instance"
msgstr ""
-#: nova/compute/manager.py:3212
+#: nova/compute/manager.py:3241
#, python-format
msgid ""
"Found %(migration_count)d unconfirmed migrations older than "
"%(confirm_window)d seconds"
msgstr ""
-#: nova/compute/manager.py:3218
+#: nova/compute/manager.py:3247
#, python-format
msgid "Setting migration %(migration_id)s to error: %(reason)s"
msgstr ""
-#: nova/compute/manager.py:3227
+#: nova/compute/manager.py:3256
#, python-format
msgid ""
"Automatically confirming migration %(migration_id)s for instance "
"%(instance_uuid)s"
msgstr ""
-#: nova/compute/manager.py:3234
+#: nova/compute/manager.py:3263
#, python-format
msgid "Instance %(instance_uuid)s not found"
msgstr ""
-#: nova/compute/manager.py:3238
+#: nova/compute/manager.py:3267
msgid "In ERROR state"
msgstr ""
-#: nova/compute/manager.py:3245
+#: nova/compute/manager.py:3274
#, python-format
msgid "In states %(vm_state)s/%(task_state)s, not RESIZED/None"
msgstr ""
-#: nova/compute/manager.py:3253
+#: nova/compute/manager.py:3282
#, python-format
msgid "Error auto-confirming resize: %(e)s. Will retry later."
msgstr ""
-#: nova/compute/manager.py:3270
+#: nova/compute/manager.py:3299
#, python-format
msgid ""
"Running instance usage audit for host %(host)s from %(begin_time)s to "
"%(end_time)s. %(number_instances)s instances."
msgstr ""
-#: nova/compute/manager.py:3289
+#: nova/compute/manager.py:3318
#, python-format
msgid "Failed to generate usage audit for instance on host %s"
msgstr ""
-#: nova/compute/manager.py:3313
+#: nova/compute/manager.py:3342
msgid "Updating bandwidth usage cache"
msgstr ""
-#: nova/compute/manager.py:3431
+#: nova/compute/manager.py:3460
msgid "Updating volume usage cache"
msgstr ""
-#: nova/compute/manager.py:3449
+#: nova/compute/manager.py:3478
msgid "Updating host status"
msgstr ""
-#: nova/compute/manager.py:3475
+#: nova/compute/manager.py:3504
#, python-format
msgid ""
"Found %(num_db_instances)s in the database and %(num_vm_instances)s on "
"the hypervisor."
msgstr ""
-#: nova/compute/manager.py:3480 nova/compute/manager.py:3529
+#: nova/compute/manager.py:3509 nova/compute/manager.py:3558
msgid "During sync_power_state the instance has a pending task. Skip."
msgstr ""
-#: nova/compute/manager.py:3516
+#: nova/compute/manager.py:3545
#, python-format
msgid ""
"During the sync_power process the instance has moved from host %(src)s to"
" host %(dst)s"
msgstr ""
-#: nova/compute/manager.py:3554
+#: nova/compute/manager.py:3583
msgid "Instance shutdown by itself. Calling the stop API."
msgstr ""
-#: nova/compute/manager.py:3566 nova/compute/manager.py:3575
-#: nova/compute/manager.py:3605
+#: nova/compute/manager.py:3595 nova/compute/manager.py:3604
+#: nova/compute/manager.py:3634
msgid "error during stop() in sync_power_state."
msgstr ""
-#: nova/compute/manager.py:3570
+#: nova/compute/manager.py:3599
msgid "Instance is suspended unexpectedly. Calling the stop API."
msgstr ""
-#: nova/compute/manager.py:3586
+#: nova/compute/manager.py:3615
msgid "Instance is paused unexpectedly. Ignore."
msgstr ""
-#: nova/compute/manager.py:3592
+#: nova/compute/manager.py:3621
msgid "Instance is unexpectedly not found. Ignore."
msgstr ""
-#: nova/compute/manager.py:3598
+#: nova/compute/manager.py:3627
msgid "Instance is not stopped. Calling the stop API."
msgstr ""
-#: nova/compute/manager.py:3614
+#: nova/compute/manager.py:3643
msgid "Instance is not (soft-)deleted."
msgstr ""
-#: nova/compute/manager.py:3622
+#: nova/compute/manager.py:3651
msgid "CONF.reclaim_instance_interval <= 0, skipping..."
msgstr ""
-#: nova/compute/manager.py:3637
+#: nova/compute/manager.py:3666
msgid "Reclaiming deleted instance"
msgstr ""
-#: nova/compute/manager.py:3692
+#: nova/compute/manager.py:3728
#, python-format
msgid ""
"Detected instance with name label '%(name)s' which is marked as DELETED "
"but still present on host."
msgstr ""
-#: nova/compute/manager.py:3699
+#: nova/compute/manager.py:3735
#, python-format
msgid ""
"Destroying instance with name label '%(name)s' which is marked as DELETED"
" but still present on host."
msgstr ""
-#: nova/compute/manager.py:3706
+#: nova/compute/manager.py:3742
#, python-format
msgid "Unrecognized value '%(action)s' for CONF.running_deleted_instance_action"
msgstr ""
@@ -4305,86 +4336,91 @@ msgstr ""
msgid "Auditing locally available compute resources"
msgstr ""
-#: nova/compute/resource_tracker.py:241
+#: nova/compute/resource_tracker.py:245
msgid ""
"Virt driver does not support 'get_available_resource' Compute tracking "
"is disabled."
msgstr ""
-#: nova/compute/resource_tracker.py:293
+#: nova/compute/resource_tracker.py:280
+#, python-format
+msgid "Deleting compute node %s"
+msgstr ""
+
+#: nova/compute/resource_tracker.py:304
#, python-format
msgid "Compute_service record created for %(host)s:%(node)s"
msgstr ""
-#: nova/compute/resource_tracker.py:299
+#: nova/compute/resource_tracker.py:310
#, python-format
msgid "Compute_service record updated for %(host)s:%(node)s"
msgstr ""
-#: nova/compute/resource_tracker.py:313
+#: nova/compute/resource_tracker.py:324
#, python-format
msgid "No service record for host %s"
msgstr ""
-#: nova/compute/resource_tracker.py:323
+#: nova/compute/resource_tracker.py:334
#, python-format
msgid "Hypervisor: free ram (MB): %s"
msgstr ""
-#: nova/compute/resource_tracker.py:324
+#: nova/compute/resource_tracker.py:335
#, python-format
msgid "Hypervisor: free disk (GB): %s"
msgstr ""
-#: nova/compute/resource_tracker.py:329
+#: nova/compute/resource_tracker.py:340
#, python-format
msgid "Hypervisor: free VCPUs: %s"
msgstr ""
-#: nova/compute/resource_tracker.py:331
+#: nova/compute/resource_tracker.py:342
msgid "Hypervisor: VCPU information unavailable"
msgstr ""
-#: nova/compute/resource_tracker.py:338
+#: nova/compute/resource_tracker.py:349
#, python-format
msgid "Free ram (MB): %s"
msgstr ""
-#: nova/compute/resource_tracker.py:339
+#: nova/compute/resource_tracker.py:350
#, python-format
msgid "Free disk (GB): %s"
msgstr ""
-#: nova/compute/resource_tracker.py:344
+#: nova/compute/resource_tracker.py:355
#, python-format
msgid "Free VCPUS: %s"
msgstr ""
-#: nova/compute/resource_tracker.py:346
+#: nova/compute/resource_tracker.py:357
msgid "Free VCPU information unavailable"
msgstr ""
-#: nova/compute/resource_tracker.py:384
+#: nova/compute/resource_tracker.py:395
#, python-format
msgid "Updating from migration %s"
msgstr ""
-#: nova/compute/resource_tracker.py:440
+#: nova/compute/resource_tracker.py:451
msgid "Instance not resizing, skipping migration."
msgstr ""
-#: nova/compute/resource_tracker.py:454
+#: nova/compute/resource_tracker.py:465
msgid "InstanceType could not be found, skipping migration."
msgstr ""
-#: nova/compute/resource_tracker.py:538
+#: nova/compute/resource_tracker.py:549
#, python-format
msgid ""
"Detected running orphan instance: %(uuid)s (consuming %(memory_mb)s MB "
"memory"
msgstr ""
-#: nova/compute/resource_tracker.py:551
+#: nova/compute/resource_tracker.py:562
#, python-format
msgid "Missing keys: %s"
msgstr ""
@@ -4403,7 +4439,7 @@ msgstr ""
msgid "Using %(prefix)s instead of %(req_prefix)s"
msgstr ""
-#: nova/conductor/api.py:367
+#: nova/conductor/api.py:370
msgid ""
"Timed out waiting for nova-conductor. Is it running? Or did this service "
"start before nova-conductor?"
@@ -4488,23 +4524,23 @@ msgstr ""
msgid "Checking Token: %(token)s, %(token_valid)s)"
msgstr ""
-#: nova/db/api.py:577
+#: nova/db/api.py:585
msgid "Failed to notify cells of instance destroy"
msgstr ""
-#: nova/db/api.py:670 nova/db/api.py:691
+#: nova/db/api.py:673 nova/db/api.py:694
msgid "Failed to notify cells of instance update"
msgstr ""
-#: nova/db/api.py:731
+#: nova/db/api.py:734
msgid "Failed to notify cells of instance info cache update"
msgstr ""
-#: nova/db/api.py:1454
+#: nova/db/api.py:1428
msgid "Failed to notify cells of bw_usage update"
msgstr ""
-#: nova/db/api.py:1608
+#: nova/db/api.py:1582
msgid "Failed to notify cells of instance fault"
msgstr ""
@@ -4513,23 +4549,28 @@ msgstr ""
msgid "Deadlock detected when running '%(func_name)s': Retrying..."
msgstr ""
-#: nova/db/sqlalchemy/api.py:202
+#: nova/db/sqlalchemy/api.py:187
msgid "model or base_model parameter should be subclass of NovaBase"
msgstr ""
-#: nova/db/sqlalchemy/api.py:215 nova/virt/baremetal/db/sqlalchemy/api.py:63
+#: nova/db/sqlalchemy/api.py:200 nova/virt/baremetal/db/sqlalchemy/api.py:64
#, python-format
msgid "Unrecognized read_deleted value '%s'"
msgstr ""
-#: nova/db/sqlalchemy/api.py:1388
+#: nova/db/sqlalchemy/api.py:1385
#, python-format
msgid ""
"Unknown osapi_compute_unique_server_name_scope value: %s Flag must be "
"empty, \"global\" or \"project\""
msgstr ""
-#: nova/db/sqlalchemy/api.py:2704
+#: nova/db/sqlalchemy/api.py:1521
+#, python-format
+msgid "Invalid instance id %s in request"
+msgstr ""
+
+#: nova/db/sqlalchemy/api.py:2654
#, python-format
msgid "Change will make usage less than 0 for the following resources: %(unders)s"
msgstr ""
@@ -4572,10 +4613,6 @@ msgstr ""
msgid "Exception while creating table."
msgstr ""
-#: nova/db/sqlalchemy/migrate_repo/versions/133_folsom.py:1225
-msgid "Downgrade from Folsom is unsupported."
-msgstr ""
-
#: nova/db/sqlalchemy/migrate_repo/versions/145_add_volume_usage_cache.py:68
msgid "volume_usage_cache table not dropped"
msgstr ""
@@ -4651,15 +4688,15 @@ msgstr ""
msgid "Bad project_id for to_global_ipv6: %s"
msgstr ""
-#: nova/network/api.py:54 nova/network/api_deprecated.py:56
+#: nova/network/api.py:54
msgid "instance is a required argument to use @refresh_cache"
msgstr ""
-#: nova/network/api.py:79 nova/network/api_deprecated.py:79
+#: nova/network/api.py:79
msgid "Failed storing info cache"
msgstr ""
-#: nova/network/api.py:227 nova/network/api_deprecated.py:216
+#: nova/network/api.py:227 nova/network/api_deprecated.py:156
#, python-format
msgid "re-assign floating IP %(address)s from instance %(instance_id)s"
msgstr ""
@@ -4773,118 +4810,123 @@ msgstr ""
msgid "This shouldn't be getting called except during testing."
msgstr ""
-#: nova/network/linux_net.py:213
+#: nova/network/linux_net.py:214
#, python-format
msgid "Attempted to remove chain %s which does not exist"
msgstr ""
-#: nova/network/linux_net.py:248
+#: nova/network/linux_net.py:249
#, python-format
msgid "Unknown chain: %r"
msgstr ""
-#: nova/network/linux_net.py:273
+#: nova/network/linux_net.py:274
#, python-format
msgid ""
"Tried to remove rule that was not there: %(chain)r %(rule)r %(wrap)r "
"%(top)r"
msgstr ""
-#: nova/network/linux_net.py:410
+#: nova/network/linux_net.py:419
msgid "IPTablesManager.apply completed with success"
msgstr ""
-#: nova/network/linux_net.py:667
+#: nova/network/linux_net.py:676
#, python-format
msgid "arping error for ip %s"
msgstr ""
-#: nova/network/linux_net.py:947
+#: nova/network/linux_net.py:726
+#, python-format
+msgid "Removed %(num)d duplicate rules for floating ip %(float)s"
+msgstr ""
+
+#: nova/network/linux_net.py:962
#, python-format
msgid "Pid %d is stale, skip killing dnsmasq"
msgstr ""
-#: nova/network/linux_net.py:992
+#: nova/network/linux_net.py:1007
#, python-format
msgid "Hupping dnsmasq threw %s"
msgstr ""
-#: nova/network/linux_net.py:994
+#: nova/network/linux_net.py:1009
#, python-format
msgid "Pid %d is stale, relaunching dnsmasq"
msgstr ""
-#: nova/network/linux_net.py:1069
+#: nova/network/linux_net.py:1084
#, python-format
msgid "killing radvd threw %s"
msgstr ""
-#: nova/network/linux_net.py:1071
+#: nova/network/linux_net.py:1086
#, python-format
msgid "Pid %d is stale, relaunching radvd"
msgstr ""
-#: nova/network/linux_net.py:1203
+#: nova/network/linux_net.py:1218
#, python-format
msgid "Error clearing stale veth %s"
msgstr ""
-#: nova/network/linux_net.py:1362
+#: nova/network/linux_net.py:1377
#, python-format
msgid "Starting VLAN interface %s"
msgstr ""
-#: nova/network/linux_net.py:1393
+#: nova/network/linux_net.py:1408
#, python-format
msgid "Failed unplugging VLAN interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1396
+#: nova/network/linux_net.py:1411
#, python-format
msgid "Unplugged VLAN interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1418
+#: nova/network/linux_net.py:1433
#, python-format
msgid "Starting Bridge %s"
msgstr ""
-#: nova/network/linux_net.py:1430
+#: nova/network/linux_net.py:1445
#, python-format
msgid "Adding interface %(interface)s to bridge %(bridge)s"
msgstr ""
-#: nova/network/linux_net.py:1463
+#: nova/network/linux_net.py:1478
#, python-format
msgid "Failed to add interface: %s"
msgstr ""
-#: nova/network/linux_net.py:1499
+#: nova/network/linux_net.py:1514
#, python-format
msgid "Failed unplugging bridge interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1502
+#: nova/network/linux_net.py:1517
#, python-format
msgid "Unplugged bridge interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1671
+#: nova/network/linux_net.py:1686
#, python-format
msgid "Starting bridge %s "
msgstr ""
-#: nova/network/linux_net.py:1679
+#: nova/network/linux_net.py:1694
#, python-format
msgid "Done starting bridge %s"
msgstr ""
-#: nova/network/linux_net.py:1698
+#: nova/network/linux_net.py:1713
#, python-format
msgid "Failed unplugging gateway interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1700
+#: nova/network/linux_net.py:1715
#, python-format
msgid "Unplugged gateway interface '%s'"
msgstr ""
@@ -5049,138 +5091,143 @@ msgstr ""
msgid "empty project id for instance %s"
msgstr ""
-#: nova/network/quantumv2/api.py:197
+#: nova/network/quantumv2/api.py:198
#, python-format
msgid ""
"Multiple security groups found matching '%s'. Use an ID to be more "
"specific."
msgstr ""
-#: nova/network/quantumv2/api.py:265
+#: nova/network/quantumv2/api.py:266
msgid "Port not found"
msgstr ""
-#: nova/network/quantumv2/api.py:273
+#: nova/network/quantumv2/api.py:274
#, python-format
msgid "Fail to delete port %(portid)s with failure: %(exception)s"
msgstr ""
-#: nova/network/quantumv2/api.py:303
+#: nova/network/quantumv2/api.py:311
#, python-format
msgid "deallocate_for_instance() for %s"
msgstr ""
-#: nova/network/quantumv2/api.py:312
+#: nova/network/quantumv2/api.py:320
#, python-format
msgid "Failed to delete quantum port %(portid)s "
msgstr ""
-#: nova/network/quantumv2/api.py:329
+#: nova/network/quantumv2/api.py:337
#, python-format
msgid "Failed to delete quantum port %(port_id)s "
msgstr ""
-#: nova/network/quantumv2/api.py:352
+#: nova/network/quantumv2/api.py:360
#, python-format
msgid "get_instance_nw_info() for %s"
msgstr ""
-#: nova/network/quantumv2/api.py:382
+#: nova/network/quantumv2/api.py:390
#, python-format
msgid ""
"Unable to update port %(portid)s on subnet %(subnet_id)s with failure: "
"%(exception)s"
msgstr ""
-#: nova/network/quantumv2/api.py:411
+#: nova/network/quantumv2/api.py:419
#, python-format
msgid "Unable to update port %(portid)s with failure: %(exception)s"
msgstr ""
-#: nova/network/quantumv2/api.py:421
+#: nova/network/quantumv2/api.py:429
#, python-format
msgid "validate_networks() for %s"
msgstr ""
-#: nova/network/quantumv2/api.py:678
+#: nova/network/quantumv2/api.py:686
#, python-format
msgid "Multiple floating IP pools matches found for name '%s'"
msgstr ""
+#: nova/network/quantumv2/api.py:786
+#, python-format
+msgid "Network %(net)s for port %(port_id)s not found!"
+msgstr ""
+
#: nova/network/security_group/quantum_driver.py:55
#, python-format
msgid "Quantum Error creating security group %s"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:103
-#: nova/network/security_group/quantum_driver.py:164
+#: nova/network/security_group/quantum_driver.py:106
+#: nova/network/security_group/quantum_driver.py:172
#, python-format
msgid "Quantum Error getting security group %s"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:107
-#: nova/network/security_group/quantum_driver.py:146
-#: nova/network/security_group/quantum_driver.py:240
+#: nova/network/security_group/quantum_driver.py:110
+#: nova/network/security_group/quantum_driver.py:154
+#: nova/network/security_group/quantum_driver.py:244
#, python-format
msgid "Quantum Error: %s"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:120
+#: nova/network/security_group/quantum_driver.py:128
msgid "Quantum Error getting security groups"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:130
+#: nova/network/security_group/quantum_driver.py:138
msgid "Security group id should be uuid"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:168
-#: nova/network/security_group/quantum_driver.py:299
-#: nova/network/security_group/quantum_driver.py:305
-#: nova/network/security_group/quantum_driver.py:331
-#: nova/network/security_group/quantum_driver.py:347
-#: nova/network/security_group/quantum_driver.py:353
-#: nova/network/security_group/quantum_driver.py:382
+#: nova/network/security_group/quantum_driver.py:176
+#: nova/network/security_group/quantum_driver.py:303
+#: nova/network/security_group/quantum_driver.py:309
+#: nova/network/security_group/quantum_driver.py:335
+#: nova/network/security_group/quantum_driver.py:351
+#: nova/network/security_group/quantum_driver.py:357
+#: nova/network/security_group/quantum_driver.py:386
msgid "Quantum Error:"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:225
+#: nova/network/security_group/quantum_driver.py:229
#, python-format
msgid "Quantum Error unable to delete %s"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:236
+#: nova/network/security_group/quantum_driver.py:240
#, python-format
msgid "Quantum Error getting security group rule %s."
msgstr ""
-#: nova/network/security_group/quantum_driver.py:315
+#: nova/network/security_group/quantum_driver.py:319
#, python-format
msgid ""
"Cannot add security group %(name)s to %(instance)s since the port "
"%(port_id)s does not meet security requirements"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:325
-#: nova/network/security_group/quantum_driver.py:375
+#: nova/network/security_group/quantum_driver.py:329
+#: nova/network/security_group/quantum_driver.py:379
#, python-format
msgid "Adding security group %(security_group_id)s to port %(port_id)s"
msgstr ""
-#: nova/network/security_group/quantum_driver.py:385
+#: nova/network/security_group/quantum_driver.py:389
#, python-format
msgid ""
"Security group %(security_group_name)s not assocaited with the instance "
"%(instance)s"
msgstr ""
-#: nova/openstack/common/excutils.py:48
+#: nova/network/security_group/security_group_base.py:137
#, python-format
-msgid "Original exception being dropped: %s"
+msgid "This rule already exists in group %s"
msgstr ""
-#: nova/openstack/common/jsonutils.py:88
+#: nova/openstack/common/excutils.py:48
#, python-format
-msgid "Max serialization depth exceeded on object: %d %s"
+msgid "Original exception being dropped: %s"
msgstr ""
#: nova/openstack/common/lockutils.py:97
@@ -5213,12 +5260,12 @@ msgstr ""
msgid "Deprecated: %s"
msgstr ""
-#: nova/openstack/common/log.py:363
+#: nova/openstack/common/log.py:358
#, python-format
msgid "syslog facility must be one of: %s"
msgstr ""
-#: nova/openstack/common/log.py:523
+#: nova/openstack/common/log.py:518
#, python-format
msgid "Fatal call to deprecated config: %(msg)s"
msgstr ""
@@ -5238,16 +5285,16 @@ msgstr ""
msgid "Failed to understand rule %(rule)r"
msgstr ""
-#: nova/openstack/common/db/sqlalchemy/session.py:423
+#: nova/openstack/common/db/sqlalchemy/session.py:435
msgid "DB exception wrapped."
msgstr ""
-#: nova/openstack/common/db/sqlalchemy/session.py:473
+#: nova/openstack/common/db/sqlalchemy/session.py:485
#, python-format
msgid "Got mysql server has gone away: %s"
msgstr ""
-#: nova/openstack/common/db/sqlalchemy/session.py:543
+#: nova/openstack/common/db/sqlalchemy/session.py:555
#, python-format
msgid "SQL connection failed. %s attempts left."
msgstr ""
@@ -5704,7 +5751,7 @@ msgstr ""
msgid "Driver must implement select_hosts"
msgstr ""
-#: nova/scheduler/driver.py:333
+#: nova/scheduler/driver.py:335
#, python-format
msgid ""
"Unable to migrate %(instance_uuid)s to %(dest)s: Lack of "
@@ -5900,109 +5947,109 @@ msgstr ""
msgid "least_cost has been deprecated in favor of the RAM Weigher."
msgstr ""
-#: nova/servicegroup/api.py:61
+#: nova/servicegroup/api.py:60
#, python-format
msgid "ServiceGroup driver defined as an instance of %s"
msgstr ""
-#: nova/servicegroup/api.py:67
+#: nova/servicegroup/api.py:66
#, python-format
msgid "unknown ServiceGroup driver name: %s"
msgstr ""
-#: nova/servicegroup/api.py:84
+#: nova/servicegroup/api.py:83
#, python-format
msgid ""
"Join new ServiceGroup member %(member_id)s to the %(group_id)s group, "
"service = %(service)s"
msgstr ""
-#: nova/servicegroup/api.py:91
+#: nova/servicegroup/api.py:90
#, python-format
msgid "Check if the given member [%s] is part of the ServiceGroup, is up"
msgstr ""
-#: nova/servicegroup/api.py:100
+#: nova/servicegroup/api.py:99
#, python-format
msgid ""
"Explicitly remove the given member %(member_id)s from the%(group_id)s "
"group monitoring"
msgstr ""
-#: nova/servicegroup/api.py:107
+#: nova/servicegroup/api.py:106
#, python-format
msgid "Returns ALL members of the [%s] ServiceGroup"
msgstr ""
-#: nova/servicegroup/api.py:115
+#: nova/servicegroup/api.py:114
#, python-format
msgid "Returns one member of the [%s] group"
msgstr ""
-#: nova/servicegroup/drivers/db.py:42
+#: nova/servicegroup/drivers/db.py:41
#, python-format
msgid ""
"DB_Driver: join new ServiceGroup member %(member_id)s to the %(group_id)s"
" group, service = %(service)s"
msgstr ""
-#: nova/servicegroup/drivers/db.py:46
+#: nova/servicegroup/drivers/db.py:45
msgid "service is a mandatory argument for DB based ServiceGroup driver"
msgstr ""
-#: nova/servicegroup/drivers/db.py:75
+#: nova/servicegroup/drivers/db.py:74
#, python-format
msgid "DB_Driver: get_all members of the %s group"
msgstr ""
-#: nova/servicegroup/drivers/db.py:98 nova/servicegroup/drivers/mc.py:103
+#: nova/servicegroup/drivers/db.py:97 nova/servicegroup/drivers/mc.py:102
msgid "Recovered model server connection!"
msgstr ""
-#: nova/servicegroup/drivers/db.py:104 nova/servicegroup/drivers/mc.py:109
+#: nova/servicegroup/drivers/db.py:103 nova/servicegroup/drivers/mc.py:108
msgid "model server went away"
msgstr ""
-#: nova/servicegroup/drivers/mc.py:45
+#: nova/servicegroup/drivers/mc.py:44
msgid "memcached_servers not defined"
msgstr ""
-#: nova/servicegroup/drivers/mc.py:53
+#: nova/servicegroup/drivers/mc.py:52
#, python-format
msgid ""
"Memcached_Driver: join new ServiceGroup member %(member_id)s to the "
"%(group_id)s group, service = %(service)s"
msgstr ""
-#: nova/servicegroup/drivers/mc.py:58
+#: nova/servicegroup/drivers/mc.py:57
msgid "service is a mandatory argument for Memcached based ServiceGroup driver"
msgstr ""
-#: nova/servicegroup/drivers/mc.py:78
+#: nova/servicegroup/drivers/mc.py:77
#, python-format
msgid "Memcached_Driver: get_all members of the %s group"
msgstr ""
-#: nova/servicegroup/drivers/zk.py:79
+#: nova/servicegroup/drivers/zk.py:80
#, python-format
msgid ""
"ZooKeeperDriver: join new member %(id)s to the %(gr)s group, "
"service=%(sr)s"
msgstr ""
-#: nova/servicegroup/drivers/zk.py:89
+#: nova/servicegroup/drivers/zk.py:90
msgid ""
"Unable to join. It is possible that either another node exists with the "
"same name, or this node just restarted. We will try again in a short "
"while to make sure."
msgstr ""
-#: nova/servicegroup/drivers/zk.py:100
+#: nova/servicegroup/drivers/zk.py:101
#, python-format
msgid "ZooKeeperDriver.leave: %(member)s from group %(group)s"
msgstr ""
-#: nova/servicegroup/drivers/zk.py:108
+#: nova/servicegroup/drivers/zk.py:109
#, python-format
msgid "ZooKeeperDriver.leave: %(id)s has not joined to the %(gr)s group"
msgstr ""
@@ -6067,19 +6114,19 @@ msgstr ""
msgid "already detached"
msgstr ""
-#: nova/tests/fakelibvirt.py:891
+#: nova/tests/fakelibvirt.py:892
msgid "Please extend mock libvirt module to support flags"
msgstr ""
-#: nova/tests/fakelibvirt.py:895
+#: nova/tests/fakelibvirt.py:896
msgid "Expected a list for 'auth' parameter"
msgstr ""
-#: nova/tests/fakelibvirt.py:899
+#: nova/tests/fakelibvirt.py:900
msgid "Expected a function in 'auth[0]' parameter"
msgstr ""
-#: nova/tests/fakelibvirt.py:903
+#: nova/tests/fakelibvirt.py:904
msgid "Expected a function in 'auth[1]' parameter"
msgstr ""
@@ -6152,17 +6199,17 @@ msgstr ""
msgid "unexpected role header"
msgstr ""
-#: nova/tests/api/openstack/compute/test_servers.py:3218
+#: nova/tests/api/openstack/compute/test_servers.py:3212
msgid ""
"Quota exceeded for instances: Requested 1, but already used 10 of 10 "
"instances"
msgstr ""
-#: nova/tests/api/openstack/compute/test_servers.py:3223
+#: nova/tests/api/openstack/compute/test_servers.py:3217
msgid "Quota exceeded for ram: Requested 4096, but already used 8192 of 10240 ram"
msgstr ""
-#: nova/tests/api/openstack/compute/test_servers.py:3228
+#: nova/tests/api/openstack/compute/test_servers.py:3222
msgid "Quota exceeded for cores: Requested 2, but already used 9 of 10 cores"
msgstr ""
@@ -6170,7 +6217,8 @@ msgstr ""
#: nova/tests/compute/test_compute.py:735
#: nova/tests/compute/test_compute.py:786
#: nova/tests/compute/test_compute.py:813
-#: nova/tests/compute/test_compute.py:2979
+#: nova/tests/compute/test_compute.py:859
+#: nova/tests/compute/test_compute.py:3002
#, python-format
msgid "Running instances: %s"
msgstr ""
@@ -6183,52 +6231,54 @@ msgstr ""
msgid "After terminating instances: %s"
msgstr ""
-#: nova/tests/compute/test_compute.py:1264
+#: nova/tests/compute/test_compute.py:1287
msgid "Internal error"
msgstr ""
-#: nova/tests/compute/test_compute.py:2990
+#: nova/tests/compute/test_compute.py:3013
#, python-format
msgid "After force-killing instances: %s"
msgstr ""
-#: nova/tests/compute/test_compute.py:3488
+#: nova/tests/compute/test_compute.py:3503
msgid "wrong host/node"
msgstr ""
-#: nova/tests/integrated/test_api_samples.py:172
+#: nova/tests/integrated/test_api_samples.py:175
#, python-format
msgid "Result: %(result)s is not a dict."
msgstr ""
-#: nova/tests/integrated/test_api_samples.py:176
+#: nova/tests/integrated/test_api_samples.py:187
#, python-format
msgid ""
-"Key mismatch:\n"
-"%(ex_keys)s\n"
-"%(res_keys)s"
+"Dictionary key mismatch:\n"
+"Extra key(s) in template:\n"
+"%(ex_delta)s\n"
+"Extra key(s) in response:\n"
+"%(res_delta)s\n"
msgstr ""
-#: nova/tests/integrated/test_api_samples.py:184
+#: nova/tests/integrated/test_api_samples.py:197
#, python-format
msgid "Result: %(result)s is not a list."
msgstr ""
-#: nova/tests/integrated/test_api_samples.py:202
-msgid "Extra items in expected:"
+#: nova/tests/integrated/test_api_samples.py:215
+msgid "Extra list items in template:"
msgstr ""
-#: nova/tests/integrated/test_api_samples.py:206
-msgid "Extra items in result:"
+#: nova/tests/integrated/test_api_samples.py:219
+msgid "Extra list items in response:"
msgstr ""
-#: nova/tests/integrated/test_api_samples.py:225
#: nova/tests/integrated/test_api_samples.py:238
+#: nova/tests/integrated/test_api_samples.py:252
#, python-format
msgid ""
"Values do not match:\n"
-"%(expected)s\n"
-"%(result)s"
+"Template: %(expected)s\n"
+"Response: %(result)s"
msgstr ""
#: nova/tests/integrated/test_login.py:31
@@ -6318,24 +6368,24 @@ msgstr ""
msgid "Key '%(key)s' not in instances '%(inst)s'"
msgstr ""
-#: nova/virt/firewall.py:180 nova/virt/libvirt/firewall.py:305
+#: nova/virt/firewall.py:184 nova/virt/libvirt/firewall.py:305
msgid "Attempted to unfilter instance which is not filtered"
msgstr ""
-#: nova/virt/firewall.py:191
+#: nova/virt/firewall.py:195
msgid "Filters added to instance"
msgstr ""
-#: nova/virt/firewall.py:193
+#: nova/virt/firewall.py:197
msgid "Provider Firewall Rules refreshed"
msgstr ""
-#: nova/virt/firewall.py:361
+#: nova/virt/firewall.py:373
#, python-format
msgid "Adding security group rule: %r"
msgstr ""
-#: nova/virt/firewall.py:494 nova/virt/xenapi/firewall.py:74
+#: nova/virt/firewall.py:506 nova/virt/xenapi/firewall.py:74
#, python-format
msgid "Adding provider rule: %s"
msgstr ""
@@ -6477,32 +6527,32 @@ msgstr ""
msgid "Injecting files into image for instance %(name)s"
msgstr ""
-#: nova/virt/baremetal/pxe.py:450
+#: nova/virt/baremetal/pxe.py:459
#, python-format
msgid "Node associated with another instance while waiting for deploy of %s"
msgstr ""
-#: nova/virt/baremetal/pxe.py:457
+#: nova/virt/baremetal/pxe.py:466
#, python-format
msgid "PXE deploy started for instance %s"
msgstr ""
-#: nova/virt/baremetal/pxe.py:462
+#: nova/virt/baremetal/pxe.py:471
#, python-format
msgid "PXE deploy completed for instance %s"
msgstr ""
-#: nova/virt/baremetal/pxe.py:466
+#: nova/virt/baremetal/pxe.py:475
#, python-format
msgid "PXE deploy failed for instance %s"
msgstr ""
-#: nova/virt/baremetal/pxe.py:468
+#: nova/virt/baremetal/pxe.py:477
#, python-format
msgid "Baremetal node deleted while waiting for deployment of instance %s"
msgstr ""
-#: nova/virt/baremetal/pxe.py:473
+#: nova/virt/baremetal/pxe.py:482
#, python-format
msgid "Timeout reached while waiting for PXE deploy of instance %s"
msgstr ""
@@ -6559,16 +6609,16 @@ msgstr ""
msgid "no pif for vif_uuid=%s"
msgstr ""
-#: nova/virt/baremetal/virtual_power_driver.py:97
+#: nova/virt/baremetal/virtual_power_driver.py:104
msgid "virtual_power_ssh_host not defined. Can not Start"
msgstr ""
-#: nova/virt/baremetal/virtual_power_driver.py:101
+#: nova/virt/baremetal/virtual_power_driver.py:108
msgid "virtual_power_host_user not defined. Can not Start"
msgstr ""
-#: nova/virt/baremetal/virtual_power_driver.py:105
-msgid "virtual_power_host_pass not defined. Can not Start"
+#: nova/virt/baremetal/virtual_power_driver.py:114
+msgid "virtual_power_host_pass/key not set. Can not Start"
msgstr ""
#: nova/virt/baremetal/volume_driver.py:121
@@ -6591,31 +6641,31 @@ msgstr ""
msgid "detach volume could not find tid for %s"
msgstr ""
-#: nova/virt/baremetal/db/sqlalchemy/api.py:201
+#: nova/virt/baremetal/db/sqlalchemy/api.py:202
msgid "instance_uuid must be supplied to bm_node_associate_and_update"
msgstr ""
-#: nova/virt/baremetal/db/sqlalchemy/api.py:213
+#: nova/virt/baremetal/db/sqlalchemy/api.py:214
#, python-format
msgid "Failed to associate instance %(i_uuid)s to baremetal node %(n_uuid)s."
msgstr ""
-#: nova/virt/baremetal/db/sqlalchemy/api.py:331
+#: nova/virt/baremetal/db/sqlalchemy/api.py:332
msgid "No more PXE IPs available"
msgstr ""
-#: nova/virt/baremetal/db/sqlalchemy/api.py:353
-#: nova/virt/baremetal/db/sqlalchemy/api.py:395
+#: nova/virt/baremetal/db/sqlalchemy/api.py:354
+#: nova/virt/baremetal/db/sqlalchemy/api.py:396
#, python-format
msgid "Baremetal interface %s not found"
msgstr ""
-#: nova/virt/baremetal/db/sqlalchemy/api.py:405
+#: nova/virt/baremetal/db/sqlalchemy/api.py:406
#, python-format
msgid "Baremetal interface %s already in use"
msgstr ""
-#: nova/virt/baremetal/db/sqlalchemy/api.py:419
+#: nova/virt/baremetal/db/sqlalchemy/api.py:420
#, python-format
msgid "Baremetal virtual interface %s not found"
msgstr ""
@@ -6877,111 +6927,111 @@ msgstr ""
msgid "Falling back to VFSLocalFS"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:54
+#: nova/virt/disk/vfs/guestfs.py:55
#, python-format
msgid "Mount guest OS image %(imgfile)s partition %(part)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:63
+#: nova/virt/disk/vfs/guestfs.py:64
#, python-format
msgid "Inspecting guest OS image %s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:67
+#: nova/virt/disk/vfs/guestfs.py:68
#, python-format
msgid "No operating system found in %s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:71
+#: nova/virt/disk/vfs/guestfs.py:72
#, python-format
msgid "Multi-boot OS %(roots)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:73
+#: nova/virt/disk/vfs/guestfs.py:74
#, python-format
msgid "Multi-boot operating system found in %s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:79
+#: nova/virt/disk/vfs/guestfs.py:80
#, python-format
msgid "Inspecting guest OS root filesystem %s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:84
+#: nova/virt/disk/vfs/guestfs.py:85
#, python-format
msgid "No mount points found in %(root)s of %(imgfile)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:89
+#: nova/virt/disk/vfs/guestfs.py:90
#, python-format
msgid "Mounting %(dev)s at %(dir)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:94
+#: nova/virt/disk/vfs/guestfs.py:95
#, python-format
msgid "Setting up appliance for %(imgfile)s %(imgfmt)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:112
+#: nova/virt/disk/vfs/guestfs.py:113
#, python-format
msgid "Error mounting %(imgfile)s with libguestfs (%(e)s)"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:119
+#: nova/virt/disk/vfs/guestfs.py:120
msgid "Tearing down appliance"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:125
+#: nova/virt/disk/vfs/guestfs.py:126
#, python-format
msgid "Failed to close augeas %s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:133
+#: nova/virt/disk/vfs/guestfs.py:134
#, python-format
msgid "Failed to shutdown appliance %s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:141
+#: nova/virt/disk/vfs/guestfs.py:142
#, python-format
msgid "Failed to close guest handle %s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:153 nova/virt/disk/vfs/localfs.py:102
+#: nova/virt/disk/vfs/guestfs.py:154 nova/virt/disk/vfs/localfs.py:102
#, python-format
msgid "Make directory path=%(path)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:158 nova/virt/disk/vfs/localfs.py:107
+#: nova/virt/disk/vfs/guestfs.py:159 nova/virt/disk/vfs/localfs.py:107
#, python-format
msgid "Append file path=%(path)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:163 nova/virt/disk/vfs/localfs.py:116
+#: nova/virt/disk/vfs/guestfs.py:164 nova/virt/disk/vfs/localfs.py:116
#, python-format
msgid "Replace file path=%(path)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:168 nova/virt/disk/vfs/localfs.py:125
+#: nova/virt/disk/vfs/guestfs.py:169 nova/virt/disk/vfs/localfs.py:125
#, python-format
msgid "Read file path=%(path)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:173 nova/virt/disk/vfs/localfs.py:131
+#: nova/virt/disk/vfs/guestfs.py:174 nova/virt/disk/vfs/localfs.py:131
#, python-format
msgid "Has file path=%(path)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:182
+#: nova/virt/disk/vfs/guestfs.py:183
#, python-format
msgid "Set permissions path=%(path)s mode=%(mode)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:187
+#: nova/virt/disk/vfs/guestfs.py:188
#, python-format
msgid "Set ownership path=%(path)s user=%(user)s group=%(group)s"
msgstr ""
-#: nova/virt/disk/vfs/guestfs.py:200
+#: nova/virt/disk/vfs/guestfs.py:201
#, python-format
msgid "chown uid=%(uid)d gid=%(gid)s"
msgstr ""
@@ -7020,23 +7070,23 @@ msgstr ""
msgid "The ISCSI initiator name can't be found. Choosing the default one"
msgstr ""
-#: nova/virt/hyperv/driver.py:147
+#: nova/virt/hyperv/driver.py:150
msgid "plug_vifs called"
msgstr ""
-#: nova/virt/hyperv/driver.py:150
+#: nova/virt/hyperv/driver.py:153
msgid "unplug_vifs called"
msgstr ""
-#: nova/virt/hyperv/driver.py:153
+#: nova/virt/hyperv/driver.py:156
msgid "ensure_filtering_rules_for_instance called"
msgstr ""
-#: nova/virt/hyperv/driver.py:157
+#: nova/virt/hyperv/driver.py:160
msgid "unfilter_instance called"
msgstr ""
-#: nova/virt/hyperv/driver.py:188
+#: nova/virt/hyperv/driver.py:191
msgid "get_console_output called"
msgstr ""
@@ -7049,7 +7099,7 @@ msgstr ""
msgid "get_available_resource called"
msgstr ""
-#: nova/virt/hyperv/hostops.py:135 nova/virt/libvirt/driver.py:3642
+#: nova/virt/hyperv/hostops.py:135 nova/virt/libvirt/driver.py:3663
#: nova/virt/xenapi/host.py:148
msgid "Updating host stats"
msgstr ""
@@ -7090,9 +7140,16 @@ msgstr ""
msgid "post_live_migration_at_destination called"
msgstr ""
-#: nova/virt/hyperv/livemigrationops.py:80
-#, python-format
-msgid "compare_cpu called %s"
+#: nova/virt/hyperv/livemigrationops.py:83
+msgid "check_can_live_migrate_destination called"
+msgstr ""
+
+#: nova/virt/hyperv/livemigrationops.py:88
+msgid "check_can_live_migrate_destination_cleanup called"
+msgstr ""
+
+#: nova/virt/hyperv/livemigrationops.py:92
+msgid "check_can_live_migrate_source called"
msgstr ""
#: nova/virt/hyperv/livemigrationutils.py:40
@@ -7337,12 +7394,12 @@ msgstr ""
msgid "Using config drive for instance: %s"
msgstr ""
-#: nova/virt/hyperv/vmops.py:203 nova/virt/libvirt/driver.py:1848
+#: nova/virt/hyperv/vmops.py:203 nova/virt/libvirt/driver.py:1847
#, python-format
msgid "Creating config drive at %(path)s"
msgstr ""
-#: nova/virt/hyperv/vmops.py:211 nova/virt/libvirt/driver.py:1854
+#: nova/virt/hyperv/vmops.py:211 nova/virt/libvirt/driver.py:1853
#, python-format
msgid "Creating config drive failed with error: %s"
msgstr ""
@@ -7481,7 +7538,7 @@ msgstr ""
msgid "Detaching physical disk from instance: %s"
msgstr ""
-#: nova/virt/hyperv/volumeops.py:157 nova/virt/libvirt/driver.py:893
+#: nova/virt/hyperv/volumeops.py:157 nova/virt/libvirt/driver.py:892
msgid "Could not determine iscsi initiator name"
msgstr ""
@@ -7515,235 +7572,235 @@ msgstr ""
msgid "Unable to determine disk bus for '%s'"
msgstr ""
-#: nova/virt/libvirt/driver.py:339
+#: nova/virt/libvirt/driver.py:338
#, python-format
msgid "Invalid cachemode %(cache_mode)s specified for disk type %(disk_type)s."
msgstr ""
-#: nova/virt/libvirt/driver.py:545
+#: nova/virt/libvirt/driver.py:544
#, python-format
msgid "Nova requires libvirt version %(major)i.%(minor)i.%(micro)i or greater."
msgstr ""
-#: nova/virt/libvirt/driver.py:553
+#: nova/virt/libvirt/driver.py:552
#, python-format
msgid "Connecting to libvirt: %s"
msgstr ""
-#: nova/virt/libvirt/driver.py:570
+#: nova/virt/libvirt/driver.py:569
#, python-format
msgid "URI %s does not support events"
msgstr ""
-#: nova/virt/libvirt/driver.py:585
+#: nova/virt/libvirt/driver.py:584
msgid "Connection to libvirt broke"
msgstr ""
-#: nova/virt/libvirt/driver.py:607 nova/virt/libvirt/driver.py:610
+#: nova/virt/libvirt/driver.py:606 nova/virt/libvirt/driver.py:609
#, python-format
msgid "Can not handle authentication request for %d credentials"
msgstr ""
-#: nova/virt/libvirt/driver.py:628
+#: nova/virt/libvirt/driver.py:627
#, python-format
msgid "Connection to libvirt failed: %s"
msgstr ""
-#: nova/virt/libvirt/driver.py:718
+#: nova/virt/libvirt/driver.py:717
#, python-format
msgid "Error from libvirt during destroy. Code=%(errcode)s Error=%(e)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:734
+#: nova/virt/libvirt/driver.py:733
msgid "During wait destroy, instance disappeared."
msgstr ""
-#: nova/virt/libvirt/driver.py:739
+#: nova/virt/libvirt/driver.py:738
msgid "Instance destroyed successfully."
msgstr ""
-#: nova/virt/libvirt/driver.py:749
+#: nova/virt/libvirt/driver.py:748
msgid "Instance may be started again."
msgstr ""
-#: nova/virt/libvirt/driver.py:758
+#: nova/virt/libvirt/driver.py:757
msgid "Going to destroy instance again."
msgstr ""
-#: nova/virt/libvirt/driver.py:777
+#: nova/virt/libvirt/driver.py:776
msgid "Error from libvirt during undefineFlags. Retrying with undefine"
msgstr ""
-#: nova/virt/libvirt/driver.py:792
+#: nova/virt/libvirt/driver.py:791
#, python-format
msgid "Error from libvirt during undefine. Code=%(errcode)s Error=%(e)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:813
+#: nova/virt/libvirt/driver.py:812
msgid "Instance may be still running, destroy it again."
msgstr ""
-#: nova/virt/libvirt/driver.py:819
+#: nova/virt/libvirt/driver.py:818
#, python-format
msgid "Error from libvirt during unfilter. Code=%(errcode)s Error=%(e)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:847
+#: nova/virt/libvirt/driver.py:846
#, python-format
msgid "Deleting instance files %(target)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:856
+#: nova/virt/libvirt/driver.py:855
#, python-format
msgid "Failed to cleanup directory %(target)s: %(e)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:899
+#: nova/virt/libvirt/driver.py:898
msgid "Could not determine fibre channel world wide node names"
msgstr ""
-#: nova/virt/libvirt/driver.py:906
+#: nova/virt/libvirt/driver.py:905
msgid "Could not determine fibre channel world wide port names"
msgstr ""
-#: nova/virt/libvirt/driver.py:911
+#: nova/virt/libvirt/driver.py:910
msgid "No Volume Connector found."
msgstr ""
-#: nova/virt/libvirt/driver.py:1033
+#: nova/virt/libvirt/driver.py:1032
msgid "During detach_volume, instance disappeared."
msgstr ""
-#: nova/virt/libvirt/driver.py:1057
+#: nova/virt/libvirt/driver.py:1056
msgid "attaching network adapter failed."
msgstr ""
-#: nova/virt/libvirt/driver.py:1077
+#: nova/virt/libvirt/driver.py:1076
msgid "During detach_interface, instance disappeared."
msgstr ""
-#: nova/virt/libvirt/driver.py:1081
+#: nova/virt/libvirt/driver.py:1080
msgid "detaching network adapter failed."
msgstr ""
-#: nova/virt/libvirt/driver.py:1170
+#: nova/virt/libvirt/driver.py:1169
msgid "Beginning live snapshot process"
msgstr ""
-#: nova/virt/libvirt/driver.py:1173
+#: nova/virt/libvirt/driver.py:1172
msgid "Beginning cold snapshot process"
msgstr ""
-#: nova/virt/libvirt/driver.py:1202
+#: nova/virt/libvirt/driver.py:1201
msgid "Snapshot extracted, beginning image upload"
msgstr ""
-#: nova/virt/libvirt/driver.py:1214
+#: nova/virt/libvirt/driver.py:1213
msgid "Snapshot image upload complete"
msgstr ""
-#: nova/virt/libvirt/driver.py:1287
+#: nova/virt/libvirt/driver.py:1286
msgid "Instance soft rebooted successfully."
msgstr ""
-#: nova/virt/libvirt/driver.py:1291
+#: nova/virt/libvirt/driver.py:1290
msgid "Failed to soft reboot instance."
msgstr ""
-#: nova/virt/libvirt/driver.py:1326
+#: nova/virt/libvirt/driver.py:1325
msgid "Instance shutdown successfully."
msgstr ""
-#: nova/virt/libvirt/driver.py:1334
+#: nova/virt/libvirt/driver.py:1333
msgid "Instance may have been rebooted during soft reboot, so return now."
msgstr ""
-#: nova/virt/libvirt/driver.py:1376
+#: nova/virt/libvirt/driver.py:1375
msgid "Instance rebooted successfully."
msgstr ""
-#: nova/virt/libvirt/driver.py:1519
+#: nova/virt/libvirt/driver.py:1518
msgid "Instance is running"
msgstr ""
-#: nova/virt/libvirt/driver.py:1526 nova/virt/powervm/operator.py:219
+#: nova/virt/libvirt/driver.py:1525 nova/virt/powervm/operator.py:219
msgid "Instance spawned successfully."
msgstr ""
-#: nova/virt/libvirt/driver.py:1542
+#: nova/virt/libvirt/driver.py:1541
#, python-format
msgid "data: %(data)r, fpath: %(fpath)r"
msgstr ""
-#: nova/virt/libvirt/driver.py:1579 nova/virt/libvirt/driver.py:1605
+#: nova/virt/libvirt/driver.py:1578 nova/virt/libvirt/driver.py:1604
#, python-format
msgid "Truncated console log returned, %d bytes ignored"
msgstr ""
-#: nova/virt/libvirt/driver.py:1594
+#: nova/virt/libvirt/driver.py:1593
msgid "Guest does not have a console available"
msgstr ""
-#: nova/virt/libvirt/driver.py:1663
+#: nova/virt/libvirt/driver.py:1662
#, python-format
msgid "Path '%(path)s' supports direct I/O"
msgstr ""
-#: nova/virt/libvirt/driver.py:1667
+#: nova/virt/libvirt/driver.py:1666
#, python-format
msgid "Path '%(path)s' does not support direct I/O: '%(ex)s'"
msgstr ""
-#: nova/virt/libvirt/driver.py:1671 nova/virt/libvirt/driver.py:1675
+#: nova/virt/libvirt/driver.py:1670 nova/virt/libvirt/driver.py:1674
#, python-format
msgid "Error on '%(path)s' while checking direct I/O: '%(ex)s'"
msgstr ""
-#: nova/virt/libvirt/driver.py:1741
+#: nova/virt/libvirt/driver.py:1740
msgid "Creating image"
msgstr ""
-#: nova/virt/libvirt/driver.py:1839
+#: nova/virt/libvirt/driver.py:1838
msgid "Using config drive"
msgstr ""
-#: nova/virt/libvirt/driver.py:1887
+#: nova/virt/libvirt/driver.py:1886
#, python-format
msgid "Injecting %(inj)s into image %(img_id)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:1896
+#: nova/virt/libvirt/driver.py:1895
#, python-format
msgid "Error injecting data into image %(img_id)s (%(e)s)"
msgstr ""
-#: nova/virt/libvirt/driver.py:1954
+#: nova/virt/libvirt/driver.py:1953
#, python-format
msgid ""
"Config requested an explicit CPU model, but the current libvirt "
"hypervisor '%s' does not support selecting CPU models"
msgstr ""
-#: nova/virt/libvirt/driver.py:1960
+#: nova/virt/libvirt/driver.py:1959
msgid "Config requested a custom CPU model, but no model name was provided"
msgstr ""
-#: nova/virt/libvirt/driver.py:1964
+#: nova/virt/libvirt/driver.py:1963
msgid "A CPU model name should not be set when a host CPU model is requested"
msgstr ""
-#: nova/virt/libvirt/driver.py:1968
+#: nova/virt/libvirt/driver.py:1967
#, python-format
msgid "CPU mode '%(mode)s' model '%(model)s' was chosen"
msgstr ""
-#: nova/virt/libvirt/driver.py:1984
+#: nova/virt/libvirt/driver.py:1983
msgid ""
"Passthrough of the host CPU was requested but this libvirt version does "
"not support this feature"
msgstr ""
-#: nova/virt/libvirt/driver.py:2294
+#: nova/virt/libvirt/driver.py:2302
#, python-format
msgid ""
"Start to_xml instance=%(instance)s network_info=%(network_info)s "
@@ -7751,80 +7808,80 @@ msgid ""
"rescue=%(rescue)sblock_device_info=%(block_device_info)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2309
+#: nova/virt/libvirt/driver.py:2317
#, python-format
msgid "End to_xml instance=%(instance)s xml=%(xml)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2326
+#: nova/virt/libvirt/driver.py:2334
#, python-format
msgid ""
"Error from libvirt while looking up %(instance_name)s: [Error Code "
"%(error_code)s] %(ex)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2494
+#: nova/virt/libvirt/driver.py:2502
msgid ""
"Cannot get the number of cpu, because this function is not implemented "
"for this platform. "
msgstr ""
-#: nova/virt/libvirt/driver.py:2547
+#: nova/virt/libvirt/driver.py:2555
#, python-format
msgid "List of domains returned by libVirt: %s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2549
+#: nova/virt/libvirt/driver.py:2557
#, python-format
msgid "libVirt can't find a domain with id: %s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2613
+#: nova/virt/libvirt/driver.py:2621
msgid "libvirt version is too old (does not support getVersion)"
msgstr ""
-#: nova/virt/libvirt/driver.py:2696
+#: nova/virt/libvirt/driver.py:2704
#, python-format
msgid "Trying to get stats for the volume %s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2720
+#: nova/virt/libvirt/driver.py:2728
#, python-format
msgid ""
"Getting block stats failed, device might have been detached. "
"Code=%(errcode)s Error=%(e)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2724
+#: nova/virt/libvirt/driver.py:2732
#, python-format
msgid ""
"Could not find domain in libvirt for instance %s. Cannot get block stats "
"for device"
msgstr ""
-#: nova/virt/libvirt/driver.py:2858
+#: nova/virt/libvirt/driver.py:2866
msgid "Block migration can not be used with shared storage."
msgstr ""
-#: nova/virt/libvirt/driver.py:2866
+#: nova/virt/libvirt/driver.py:2874
msgid "Live migration can not be used without shared storage."
msgstr ""
-#: nova/virt/libvirt/driver.py:2903
+#: nova/virt/libvirt/driver.py:2911
#, python-format
msgid ""
"Unable to migrate %(instance_uuid)s: Disk of instance is too "
"large(available on destination host:%(available)s < need:%(necessary)s)"
msgstr ""
-#: nova/virt/libvirt/driver.py:2928
+#: nova/virt/libvirt/driver.py:2936
#, python-format
msgid ""
"Instance launched has CPU info:\n"
"%s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2940
+#: nova/virt/libvirt/driver.py:2948
#, python-format
msgid ""
"CPU doesn't have compatibility.\n"
@@ -7834,62 +7891,62 @@ msgid ""
"Refer to %(u)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:2957
+#: nova/virt/libvirt/driver.py:2965
#, python-format
msgid ""
"Creating tmpfile %s to notify to other compute nodes that they should "
"mount the same storage."
msgstr ""
-#: nova/virt/libvirt/driver.py:3005
+#: nova/virt/libvirt/driver.py:3013
#, python-format
msgid "The firewall filter for %s does not exist"
msgstr ""
-#: nova/virt/libvirt/driver.py:3077
+#: nova/virt/libvirt/driver.py:3085
#, python-format
msgid "Live Migration failure: %(e)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:3170
+#: nova/virt/libvirt/driver.py:3178
#, python-format
msgid "plug_vifs() failed %(cnt)d.Retry up to %(max_retry)d for %(hostname)s."
msgstr ""
-#: nova/virt/libvirt/driver.py:3280
+#: nova/virt/libvirt/driver.py:3288
#, python-format
msgid ""
"Error from libvirt while getting description of %(instance_name)s: [Error"
" Code %(error_code)s] %(ex)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:3297
+#: nova/virt/libvirt/driver.py:3305
#, python-format
msgid "skipping %(path)s since it looks like volume"
msgstr ""
-#: nova/virt/libvirt/driver.py:3335
+#: nova/virt/libvirt/driver.py:3343
#, python-format
msgid "Getting disk size of %(i_name)s: %(e)s"
msgstr ""
-#: nova/virt/libvirt/driver.py:3381
+#: nova/virt/libvirt/driver.py:3389
msgid "Starting migrate_disk_and_power_off"
msgstr ""
-#: nova/virt/libvirt/driver.py:3440
+#: nova/virt/libvirt/driver.py:3448
msgid "Instance running successfully."
msgstr ""
-#: nova/virt/libvirt/driver.py:3446
+#: nova/virt/libvirt/driver.py:3454
msgid "Starting finish_migration"
msgstr ""
-#: nova/virt/libvirt/driver.py:3502
+#: nova/virt/libvirt/driver.py:3515
msgid "Starting finish_revert_migration"
msgstr ""
-#: nova/virt/libvirt/driver.py:3615
+#: nova/virt/libvirt/driver.py:3636
#, python-format
msgid "Checking instance files accessability%(instance_path)s"
msgstr ""
@@ -7931,144 +7988,144 @@ msgstr ""
msgid "Unknown image_type=%s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:111
+#: nova/virt/libvirt/imagecache.py:140
#, python-format
msgid "Error reading image info file %(filename)s: %(error)s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:151
+#: nova/virt/libvirt/imagecache.py:180
#, python-format
msgid "Reading image info file: %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:173
+#: nova/virt/libvirt/imagecache.py:202
#, python-format
msgid "Writing stored info to %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:299
+#: nova/virt/libvirt/imagecache.py:332
#, python-format
msgid "%s is a valid instance name"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:302
+#: nova/virt/libvirt/imagecache.py:335
#, python-format
msgid "%s has a disk file"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:304
+#: nova/virt/libvirt/imagecache.py:337
#, python-format
msgid "Instance %(instance)s is backed by %(backing)s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:317
+#: nova/virt/libvirt/imagecache.py:350
#, python-format
msgid ""
"Instance %(instance)s is using a backing file %(backing)s which does not "
"appear in the image service"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:393
+#: nova/virt/libvirt/imagecache.py:426
#, python-format
msgid "image %(id)s at (%(base_file)s): image verification failed"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:403
+#: nova/virt/libvirt/imagecache.py:436
#, python-format
msgid ""
"image %(id)s at (%(base_file)s): image verification skipped, no hash "
"stored"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:412
+#: nova/virt/libvirt/imagecache.py:445
#, python-format
msgid "%(id)s (%(base_file)s): generating checksum"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:427
+#: nova/virt/libvirt/imagecache.py:460
#, python-format
msgid "Cannot remove %(base_file)s, it does not exist"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:439
+#: nova/virt/libvirt/imagecache.py:472
#, python-format
msgid "Base file too young to remove: %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:442
+#: nova/virt/libvirt/imagecache.py:475
#, python-format
msgid "Removing base file: %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:449
+#: nova/virt/libvirt/imagecache.py:482
#, python-format
msgid "Failed to remove %(base_file)s, error was %(error)s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:460
+#: nova/virt/libvirt/imagecache.py:493
#, python-format
msgid "image %(id)s at (%(base_file)s): checking"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:484
+#: nova/virt/libvirt/imagecache.py:517
#, python-format
msgid ""
"image %(id)s at (%(base_file)s): in use: on this node %(local)d local, "
"%(remote)d on other nodes sharing this instance storage"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:496
+#: nova/virt/libvirt/imagecache.py:529
#, python-format
msgid ""
"image %(id)s at (%(base_file)s): warning -- an absent base file is in "
"use! instances: %(instance_list)s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:508
+#: nova/virt/libvirt/imagecache.py:541
#, python-format
msgid "image %(id)s at (%(base_file)s): image is not in use"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:515
+#: nova/virt/libvirt/imagecache.py:548
#, python-format
msgid "image %(id)s at (%(base_file)s): image is in use"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:539
+#: nova/virt/libvirt/imagecache.py:572
#, python-format
msgid "Skipping verification, no base directory at %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:543
+#: nova/virt/libvirt/imagecache.py:576
msgid "Verify base images"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:550
+#: nova/virt/libvirt/imagecache.py:583
#, python-format
msgid "Image id %(id)s yields fingerprint %(fingerprint)s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:568
+#: nova/virt/libvirt/imagecache.py:601
#, python-format
msgid "Unknown base file: %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:573
+#: nova/virt/libvirt/imagecache.py:606
#, python-format
msgid "Active base files: %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:576
+#: nova/virt/libvirt/imagecache.py:609
#, python-format
msgid "Corrupt base files: %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:580
+#: nova/virt/libvirt/imagecache.py:613
#, python-format
msgid "Removable base files: %s"
msgstr ""
-#: nova/virt/libvirt/imagecache.py:588
+#: nova/virt/libvirt/imagecache.py:621
msgid "Verification complete"
msgstr ""
@@ -8109,36 +8166,36 @@ msgstr ""
msgid "Can't retrieve root device path from instance libvirt configuration"
msgstr ""
-#: nova/virt/libvirt/vif.py:263 nova/virt/libvirt/vif.py:382
-#: nova/virt/libvirt/vif.py:469
+#: nova/virt/libvirt/vif.py:264 nova/virt/libvirt/vif.py:383
+#: nova/virt/libvirt/vif.py:470
#, python-format
msgid ""
"vif_type=%(vif_type)s instance=%(instance)s network=%(network)s "
"mapping=%(mapping)s"
msgstr ""
-#: nova/virt/libvirt/vif.py:269 nova/virt/libvirt/vif.py:388
-#: nova/virt/libvirt/vif.py:475
+#: nova/virt/libvirt/vif.py:270 nova/virt/libvirt/vif.py:389
+#: nova/virt/libvirt/vif.py:476
msgid "vif_type parameter must be present for this vif_driver implementation"
msgstr ""
-#: nova/virt/libvirt/vif.py:290 nova/virt/libvirt/vif.py:401
-#: nova/virt/libvirt/vif.py:488
+#: nova/virt/libvirt/vif.py:291 nova/virt/libvirt/vif.py:402
+#: nova/virt/libvirt/vif.py:489
#, python-format
msgid "Unexpected vif_type=%s"
msgstr ""
-#: nova/virt/libvirt/vif.py:302
+#: nova/virt/libvirt/vif.py:303
#, python-format
msgid "Ensuring vlan %(vlan)s and bridge %(bridge)s"
msgstr ""
-#: nova/virt/libvirt/vif.py:312
+#: nova/virt/libvirt/vif.py:313
#, python-format
msgid "Ensuring bridge %s"
msgstr ""
-#: nova/virt/libvirt/vif.py:418 nova/virt/libvirt/vif.py:447
+#: nova/virt/libvirt/vif.py:419 nova/virt/libvirt/vif.py:448
msgid "Failed while unplugging vif"
msgstr ""
@@ -8302,48 +8359,48 @@ msgstr ""
msgid "Uncompressed image file not found"
msgstr ""
-#: nova/virt/powervm/common.py:57
+#: nova/virt/powervm/common.py:59
msgid "Connection error connecting PowerVM manager"
msgstr ""
-#: nova/virt/powervm/common.py:69
+#: nova/virt/powervm/common.py:71
#, python-format
msgid "Running cmd (SSH-as-root): %s"
msgstr ""
-#: nova/virt/powervm/common.py:115
+#: nova/virt/powervm/common.py:117
msgid "File transfer to PowerVM manager failed"
msgstr ""
-#: nova/virt/powervm/common.py:134
+#: nova/virt/powervm/common.py:136
#, python-format
msgid "ftp GET %(remote_path)s to: %(local_path)s"
msgstr ""
-#: nova/virt/powervm/common.py:140
+#: nova/virt/powervm/common.py:142
msgid "File transfer from PowerVM manager failed"
msgstr ""
-#: nova/virt/powervm/driver.py:118
+#: nova/virt/powervm/driver.py:120
msgid "In get_host_ip_addr"
msgstr ""
-#: nova/virt/powervm/driver.py:121
+#: nova/virt/powervm/driver.py:123
#, python-format
msgid "Attempting to resolve %s"
msgstr ""
-#: nova/virt/powervm/driver.py:123
+#: nova/virt/powervm/driver.py:125
#, python-format
msgid "%(hostname)s was successfully resolved to %(ip_addr)s"
msgstr ""
-#: nova/virt/powervm/driver.py:166
+#: nova/virt/powervm/driver.py:168
#, python-format
msgid "%(inst_name)s captured in %(snapshot_time)s seconds"
msgstr ""
-#: nova/virt/powervm/driver.py:286
+#: nova/virt/powervm/driver.py:288
#, python-format
msgid "Unrecognized root disk information: %s"
msgstr ""
@@ -8938,7 +8995,7 @@ msgstr ""
msgid "Migrated VM to host %s"
msgstr ""
-#: nova/virt/vmwareapi/vmops.py:1050 nova/virt/xenapi/vmops.py:1263
+#: nova/virt/vmwareapi/vmops.py:1050 nova/virt/xenapi/vmops.py:1273
#, python-format
msgid "Found %(instance_count)d hung reboots older than %(timeout)d seconds"
msgstr ""
@@ -9096,19 +9153,19 @@ msgstr ""
msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
msgstr ""
-#: nova/virt/xenapi/agent.py:88 nova/virt/xenapi/vmops.py:1506
+#: nova/virt/xenapi/agent.py:88 nova/virt/xenapi/vmops.py:1516
#, python-format
msgid "TIMEOUT: The call to %(method)s timed out. args=%(args)r"
msgstr ""
-#: nova/virt/xenapi/agent.py:92 nova/virt/xenapi/vmops.py:1510
+#: nova/virt/xenapi/agent.py:92 nova/virt/xenapi/vmops.py:1520
#, python-format
msgid ""
"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. "
"args=%(args)r"
msgstr ""
-#: nova/virt/xenapi/agent.py:97 nova/virt/xenapi/vmops.py:1515
+#: nova/virt/xenapi/agent.py:97 nova/virt/xenapi/vmops.py:1525
#, python-format
msgid "The call to %(method)s returned an error: %(e)s. args=%(args)r"
msgstr ""
@@ -9790,7 +9847,7 @@ msgstr ""
msgid "This domU must be running on the host specified by xenapi_connection_url"
msgstr ""
-#: nova/virt/xenapi/vmops.py:133 nova/virt/xenapi/vmops.py:740
+#: nova/virt/xenapi/vmops.py:133 nova/virt/xenapi/vmops.py:750
#, python-format
msgid "Updating progress to %(progress)d"
msgstr ""
@@ -9804,187 +9861,187 @@ msgstr ""
msgid "Error: Agent is disabled"
msgstr ""
-#: nova/virt/xenapi/vmops.py:267
+#: nova/virt/xenapi/vmops.py:277
msgid "Starting instance"
msgstr ""
-#: nova/virt/xenapi/vmops.py:336
+#: nova/virt/xenapi/vmops.py:346
msgid "Removing kernel/ramdisk files from dom0"
msgstr ""
-#: nova/virt/xenapi/vmops.py:409
+#: nova/virt/xenapi/vmops.py:419
#, python-format
msgid "Block device information present: %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:440
+#: nova/virt/xenapi/vmops.py:450
msgid "Failed to spawn, rolling back"
msgstr ""
-#: nova/virt/xenapi/vmops.py:519
+#: nova/virt/xenapi/vmops.py:529
msgid "Detected ISO image type, creating blank VM for install"
msgstr ""
-#: nova/virt/xenapi/vmops.py:536
+#: nova/virt/xenapi/vmops.py:546
msgid "Auto configuring disk, attempting to resize partition..."
msgstr ""
-#: nova/virt/xenapi/vmops.py:582
+#: nova/virt/xenapi/vmops.py:592
msgid "Starting VM"
msgstr ""
-#: nova/virt/xenapi/vmops.py:588
+#: nova/virt/xenapi/vmops.py:598
msgid "Waiting for instance state to become running"
msgstr ""
-#: nova/virt/xenapi/vmops.py:602
+#: nova/virt/xenapi/vmops.py:612
#, python-format
msgid ""
"Latest agent build for %(hypervisor)s/%(os)s/%(architecture)s is "
"%(version)s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:605
+#: nova/virt/xenapi/vmops.py:615
#, python-format
msgid "No agent build found for %(hypervisor)s/%(os)s/%(architecture)s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:616
+#: nova/virt/xenapi/vmops.py:626
#, python-format
msgid "Instance agent version: %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:643
+#: nova/virt/xenapi/vmops.py:653
msgid "Setting VCPU weight"
msgstr ""
-#: nova/virt/xenapi/vmops.py:651
+#: nova/virt/xenapi/vmops.py:661
#, python-format
msgid "Could not find VM with name %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:709
+#: nova/virt/xenapi/vmops.py:719
msgid "Finished snapshot and upload for VM"
msgstr ""
-#: nova/virt/xenapi/vmops.py:713
+#: nova/virt/xenapi/vmops.py:723
#, python-format
msgid "Migrating VHD '%(vdi_uuid)s' with seq_num %(seq_num)d"
msgstr ""
-#: nova/virt/xenapi/vmops.py:721
+#: nova/virt/xenapi/vmops.py:731
msgid "Failed to transfer vhd to new host"
msgstr ""
-#: nova/virt/xenapi/vmops.py:758
+#: nova/virt/xenapi/vmops.py:768
#, python-format
msgid "Resizing down VDI %(vdi_uuid)s from %(old_gb)dGB to %(new_gb)dGB"
msgstr ""
-#: nova/virt/xenapi/vmops.py:764 nova/virt/xenapi/vmops.py:814
+#: nova/virt/xenapi/vmops.py:774 nova/virt/xenapi/vmops.py:824
msgid "Clean shutdown did not complete successfully, trying hard shutdown."
msgstr ""
-#: nova/virt/xenapi/vmops.py:843
+#: nova/virt/xenapi/vmops.py:853
msgid "Resize down not allowed without auto_disk_config"
msgstr ""
-#: nova/virt/xenapi/vmops.py:888
+#: nova/virt/xenapi/vmops.py:898
#, python-format
msgid "Resizing up VDI %(vdi_uuid)s from %(old_gb)dGB to %(new_gb)dGB"
msgstr ""
-#: nova/virt/xenapi/vmops.py:893
+#: nova/virt/xenapi/vmops.py:903
msgid "Resize complete"
msgstr ""
-#: nova/virt/xenapi/vmops.py:937
+#: nova/virt/xenapi/vmops.py:947
msgid "Starting halted instance found during reboot"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1028
+#: nova/virt/xenapi/vmops.py:1038
msgid "Unable to find root VBD/VDI for VM"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1032
+#: nova/virt/xenapi/vmops.py:1042
msgid "Destroying VDIs"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1059
+#: nova/virt/xenapi/vmops.py:1069
msgid "Using RAW or VHD, skipping kernel and ramdisk deletion"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1066
+#: nova/virt/xenapi/vmops.py:1076
msgid "instance has a kernel or ramdisk but not both"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1073
+#: nova/virt/xenapi/vmops.py:1083
msgid "kernel/ramdisk files removed"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1100
+#: nova/virt/xenapi/vmops.py:1110
msgid "Destroying VM"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1129
+#: nova/virt/xenapi/vmops.py:1139
msgid "VM is not present, skipping destroy..."
msgstr ""
-#: nova/virt/xenapi/vmops.py:1180
+#: nova/virt/xenapi/vmops.py:1190
#, python-format
msgid "Instance is already in Rescue Mode: %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1214
+#: nova/virt/xenapi/vmops.py:1224
msgid "VM is not present, skipping soft delete..."
msgstr ""
-#: nova/virt/xenapi/vmops.py:1267
+#: nova/virt/xenapi/vmops.py:1277
msgid "Automatically hard rebooting"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1327
+#: nova/virt/xenapi/vmops.py:1337
msgid "Fetching VM ref while BUILDING failed"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1410
+#: nova/virt/xenapi/vmops.py:1420
msgid "Injecting network info to xenstore"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1429
+#: nova/virt/xenapi/vmops.py:1439
msgid "Creating vifs"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1438
+#: nova/virt/xenapi/vmops.py:1448
#, python-format
msgid "Creating VIF for network %(network_ref)s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1441
+#: nova/virt/xenapi/vmops.py:1451
#, python-format
msgid "Created VIF %(vif_ref)s, network %(network_ref)s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1469
+#: nova/virt/xenapi/vmops.py:1479
msgid "Injecting hostname to xenstore"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1565
+#: nova/virt/xenapi/vmops.py:1575
#, python-format
msgid ""
"Destination host:%(hostname)s must be in the same aggregate as the source"
" server"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1597
+#: nova/virt/xenapi/vmops.py:1607
msgid "Migrate Receive failed"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1646
+#: nova/virt/xenapi/vmops.py:1656
msgid "VM.assert_can_migratefailed"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1682
+#: nova/virt/xenapi/vmops.py:1692
msgid "Migrate Send failed"
msgstr ""
@@ -10059,9 +10116,17 @@ msgstr ""
msgid "Skipping detach because VBD for %(instance_name)s was not found"
msgstr ""
-#: nova/virt/xenapi/imageupload/glance.py:35
+#: nova/virt/xenapi/imageupload/glance.py:64
+#, python-format
+msgid ""
+"Asking xapi to upload to glance %(vdi_uuids)s as ID %(image_id)s glance "
+"server: %(glance_host)s:%(glance_port)d attempt "
+"%(attempt_num)d/%(max_attempts)d"
+msgstr ""
+
+#: nova/virt/xenapi/imageupload/glance.py:77
#, python-format
-msgid "Asking xapi to upload to glance %(vdi_uuids)s as ID %(image_id)s"
+msgid "upload_vhd failed: %r"
msgstr ""
#: nova/vnc/xvp_proxy.py:95 nova/vnc/xvp_proxy.py:100
diff --git a/nova/network/api_deprecated.py b/nova/network/api_deprecated.py
index b84a08a6d..1f23d90f7 100644
--- a/nova/network/api_deprecated.py
+++ b/nova/network/api_deprecated.py
@@ -22,82 +22,20 @@ This version of the api is deprecated in Grizzly and will be removed.
It is provided just in case a third party manager is in use.
"""
-import functools
-import inspect
-
from nova.db import base
from nova import exception
+from nova.network import api as shiny_api
from nova.network import model as network_model
from nova.network import rpcapi as network_rpcapi
from nova.openstack.common import log as logging
-from nova import policy
LOG = logging.getLogger(__name__)
-def refresh_cache(f):
- """
- Decorator to update the instance_info_cache
-
- Requires context and instance as function args
- """
- argspec = inspect.getargspec(f)
-
- @functools.wraps(f)
- def wrapper(self, context, *args, **kwargs):
- res = f(self, context, *args, **kwargs)
-
- try:
- # get the instance from arguments (or raise ValueError)
- instance = kwargs.get('instance')
- if not instance:
- instance = args[argspec.args.index('instance') - 2]
- except ValueError:
- msg = _('instance is a required argument to use @refresh_cache')
- raise Exception(msg)
-
- update_instance_cache_with_nw_info(self, context, instance,
- nw_info=res)
-
- # return the original function's return value
- return res
- return wrapper
-
-
-def update_instance_cache_with_nw_info(api, context, instance,
- nw_info=None):
-
- try:
- if not isinstance(nw_info, network_model.NetworkInfo):
- nw_info = None
- if not nw_info:
- nw_info = api._get_instance_nw_info(context, instance)
- # update cache
- cache = {'network_info': nw_info.json()}
- api.db.instance_info_cache_update(context, instance['uuid'], cache)
- except Exception:
- LOG.exception(_('Failed storing info cache'), instance=instance)
-
-
-def wrap_check_policy(func):
- """Check policy corresponding to the wrapped methods prior to execution."""
-
- @functools.wraps(func)
- def wrapped(self, context, *args, **kwargs):
- action = func.__name__
- check_policy(context, action)
- return func(self, context, *args, **kwargs)
-
- return wrapped
-
-
-def check_policy(context, action):
- target = {
- 'project_id': context.project_id,
- 'user_id': context.user_id,
- }
- _action = 'network:%s' % action
- policy.enforce(context, _action, target)
+refresh_cache = shiny_api.refresh_cache
+_update_instance_cache = shiny_api.update_instance_cache_with_nw_info
+update_instance_cache_with_nw_info = _update_instance_cache
+wrap_check_policy = shiny_api.wrap_check_policy
class API(base.Base):
@@ -159,8 +97,8 @@ class API(base.Base):
@wrap_check_policy
def get_floating_ips_by_fixed_address(self, context, fixed_address):
- return self.network_rpcapi.get_floating_ips_by_fixed_address(context,
- fixed_address)
+ args = (context, fixed_address)
+ return self.network_rpcapi.get_floating_ips_by_fixed_address(*args)
@wrap_check_policy
def get_backdoor_port(self, context, host):
@@ -170,12 +108,12 @@ class API(base.Base):
def get_instance_id_by_floating_address(self, context, address):
# NOTE(tr3buchet): i hate this
return self.network_rpcapi.get_instance_id_by_floating_address(context,
- address)
+ address)
@wrap_check_policy
def get_vifs_by_instance(self, context, instance):
return self.network_rpcapi.get_vifs_by_instance(context,
- instance['id'])
+ instance['id'])
@wrap_check_policy
def get_vif_by_mac_address(self, context, mac_address):
@@ -189,14 +127,16 @@ class API(base.Base):
# will probably need to move into a network supervisor
# at some point.
return self.network_rpcapi.allocate_floating_ip(context,
- context.project_id, pool, False)
+ context.project_id,
+ pool,
+ False)
@wrap_check_policy
def release_floating_ip(self, context, address,
affect_auto_assigned=False):
"""Removes (deallocates) a floating ip with address from a project."""
- return self.network_rpcapi.deallocate_floating_ip(context, address,
- affect_auto_assigned)
+ args = (context, address, affect_auto_assigned)
+ return self.network_rpcapi.deallocate_floating_ip(*args)
@wrap_check_policy
@refresh_cache
@@ -207,8 +147,8 @@ class API(base.Base):
ensures floating ip is allocated to the project in context
"""
- orig_instance_uuid = self.network_rpcapi.associate_floating_ip(context,
- floating_address, fixed_address, affect_auto_assigned)
+ args = (context, floating_address, fixed_address, affect_auto_assigned)
+ orig_instance_uuid = self.network_rpcapi.associate_floating_ip(*args)
if orig_instance_uuid:
msg_dict = dict(address=floating_address,
@@ -227,12 +167,14 @@ class API(base.Base):
affect_auto_assigned=False):
"""Disassociates a floating ip from fixed ip it is associated with."""
self.network_rpcapi.disassociate_floating_ip(context, address,
- affect_auto_assigned)
+ affect_auto_assigned)
@wrap_check_policy
@refresh_cache
def allocate_for_instance(self, context, instance, vpn,
- requested_networks, macs=None):
+ requested_networks, macs=None,
+ conductor_api=None, security_groups=None,
+ **kwargs):
"""Allocates all network structures for an instance.
TODO(someone): document the rest of these parameters.
@@ -246,8 +188,7 @@ class API(base.Base):
args = {}
args['vpn'] = vpn
args['requested_networks'] = requested_networks
- args['instance_id'] = instance['id']
- args['instance_uuid'] = instance['uuid']
+ args['instance_id'] = instance['uuid']
args['project_id'] = instance['project_id']
args['host'] = instance['host']
args['rxtx_factor'] = instance['instance_type']['rxtx_factor']
@@ -256,7 +197,7 @@ class API(base.Base):
return network_model.NetworkInfo.hydrate(nw_info)
@wrap_check_policy
- def deallocate_for_instance(self, context, instance):
+ def deallocate_for_instance(self, context, instance, **kwargs):
"""Deallocates all network structures related to instance."""
args = {}
@@ -267,28 +208,32 @@ class API(base.Base):
@wrap_check_policy
@refresh_cache
- def add_fixed_ip_to_instance(self, context, instance, network_id):
+ def add_fixed_ip_to_instance(self, context, instance, network_id,
+ conductor_api=None, **kwargs):
"""Adds a fixed ip to instance from specified network."""
args = {'instance_id': instance['uuid'],
'host': instance['host'],
- 'network_id': network_id}
+ 'network_id': network_id,
+ 'rxtx_factor': None}
self.network_rpcapi.add_fixed_ip_to_instance(context, **args)
@wrap_check_policy
@refresh_cache
- def remove_fixed_ip_from_instance(self, context, instance, address):
+ def remove_fixed_ip_from_instance(self, context, instance, address,
+ conductor=None, **kwargs):
"""Removes a fixed ip from instance from specified network."""
args = {'instance_id': instance['uuid'],
'host': instance['host'],
- 'address': address}
+ 'address': address,
+ 'rxtx_factor': None}
self.network_rpcapi.remove_fixed_ip_from_instance(context, **args)
@wrap_check_policy
def add_network_to_project(self, context, project_id, network_uuid=None):
"""Force adds another network to a project."""
self.network_rpcapi.add_network_to_project(context, project_id,
- network_uuid)
+ network_uuid)
@wrap_check_policy
def associate(self, context, network_uuid, host=_sentinel,
@@ -302,18 +247,17 @@ class API(base.Base):
self.network_rpcapi.associate(context, network_uuid, associations)
@wrap_check_policy
- def get_instance_nw_info(self, context, instance, update_cache=True):
+ def get_instance_nw_info(self, context, instance, conductor_api=None,
+ **kwargs):
"""Returns all network info related to an instance."""
result = self._get_instance_nw_info(context, instance)
- if update_cache:
- update_instance_cache_with_nw_info(self, context, instance,
- result)
+ update_instance_cache_with_nw_info(self, context, instance,
+ result, conductor_api)
return result
def _get_instance_nw_info(self, context, instance):
"""Returns all network info related to an instance."""
- args = {'instance_id': instance['id'],
- 'instance_uuid': instance['uuid'],
+ args = {'instance_id': instance['uuid'],
'rxtx_factor': instance['instance_type']['rxtx_factor'],
'host': instance['host'],
'project_id': instance['project_id']}
@@ -398,7 +342,7 @@ class API(base.Base):
@wrap_check_policy
def setup_networks_on_host(self, context, instance, host=None,
- teardown=False):
+ teardown=False):
"""Setup or teardown the network structures on hosts related to
instance"""
host = host or instance['host']
@@ -422,8 +366,8 @@ class API(base.Base):
return network['multi_host']
def _get_floating_ip_addresses(self, context, instance):
- floating_ips = self.db.instance_floating_address_get_all(context,
- instance['uuid'])
+ args = (context, instance['uuid'])
+ floating_ips = self.db.instance_floating_address_get_all(*args)
return [floating_ip['address'] for floating_ip in floating_ips]
@wrap_check_policy
@@ -463,3 +407,20 @@ class API(base.Base):
args['host'] = migration['dest_compute']
self.network_rpcapi.migrate_instance_finish(context, **args)
+
+ # NOTE(jkoelker) These functions where added to the api after
+ # deprecation. Stubs provided for support documentation
+ def allocate_port_for_instance(self, context, instance, port_id,
+ network_id=None, requested_ip=None,
+ conductor_api=None):
+ raise NotImplementedError()
+
+ def deallocate_port_for_instance(self, context, instance, port_id,
+ conductor_api=None):
+ raise NotImplementedError()
+
+ def list_ports(self, *args, **kwargs):
+ raise NotImplementedError()
+
+ def show_port(self, *args, **kwargs):
+ raise NotImplementedError()
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index 29b882a02..cb23e77b6 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -29,8 +29,10 @@ from oslo.config import cfg
from nova import db
from nova import exception
+from nova.openstack.common import excutils
from nova.openstack.common import fileutils
from nova.openstack.common import importutils
+from nova.openstack.common import jsonutils
from nova.openstack.common import lockutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
@@ -41,9 +43,9 @@ LOG = logging.getLogger(__name__)
linux_net_opts = [
- cfg.StrOpt('dhcpbridge_flagfile',
- default='/etc/nova/nova-dhcpbridge.conf',
- help='location of flagfile for dhcpbridge'),
+ cfg.MultiStrOpt('dhcpbridge_flagfile',
+ default=['/etc/nova/nova-dhcpbridge.conf'],
+ help='location of flagfiles for dhcpbridge'),
cfg.StrOpt('networks_path',
default=paths.state_path_def('networks'),
help='Location to keep network config files'),
@@ -275,6 +277,14 @@ class IptablesTable(object):
{'chain': chain, 'rule': rule,
'top': top, 'wrap': wrap})
+ def remove_rules_regex(self, regex):
+ """Remove all rules matching regex."""
+ if isinstance(regex, basestring):
+ regex = re.compile(regex)
+ num_rules = len(self.rules)
+ self.rules = filter(lambda r: not regex.match(str(r)), self.rules)
+ return num_rules - len(self.rules)
+
def empty_chain(self, chain, wrap=True):
"""Remove all rules from a chain."""
chained_rules = [rule for rule in self.rules
@@ -710,6 +720,12 @@ def ensure_vpn_forward(public_ip, port, private_ip):
def ensure_floating_forward(floating_ip, fixed_ip, device, network):
"""Ensure floating ip forwarding rule."""
+ # NOTE(vish): Make sure we never have duplicate rules for the same ip
+ regex = '.*\s+%s(/32|\s+|$)' % floating_ip
+ num_rules = iptables_manager.ipv4['nat'].remove_rules_regex(regex)
+ if num_rules:
+ msg = _('Removed %(num)d duplicate rules for floating ip %(float)s')
+ LOG.warn(msg % {'num': num_rules, 'float': floating_ip})
for chain, rule in floating_forward_rules(floating_ip, fixed_ip, device):
iptables_manager.ipv4['nat'].add_rule(chain, rule)
iptables_manager.apply()
@@ -994,7 +1010,7 @@ def restart_dhcp(context, dev, network_ref):
LOG.debug(_('Pid %d is stale, relaunching dnsmasq'), pid)
cmd = ['env',
- 'CONFIG_FILE=%s' % CONF.dhcpbridge_flagfile,
+ 'CONFIG_FILE=%s' % jsonutils.dumps(CONF.dhcpbridge_flagfile),
'NETWORK_ID=%s' % str(network_ref['id']),
'dnsmasq',
'--strict-order',
@@ -1390,9 +1406,9 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
utils.execute('ip', 'link', 'delete', vlan_interface,
run_as_root=True, check_exit_code=[0, 2, 254])
except exception.ProcessExecutionError:
- LOG.error(_("Failed unplugging VLAN interface '%s'"),
- vlan_interface)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.error(_("Failed unplugging VLAN interface '%s'"),
+ vlan_interface)
LOG.debug(_("Unplugged VLAN interface '%s'"), vlan_interface)
@classmethod
@@ -1496,8 +1512,9 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
utils.execute('ip', 'link', 'delete', bridge, run_as_root=True,
check_exit_code=[0, 2, 254])
except exception.ProcessExecutionError:
- LOG.error(_("Failed unplugging bridge interface '%s'"), bridge)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.error(_("Failed unplugging bridge interface '%s'"),
+ bridge)
LOG.debug(_("Unplugged bridge interface '%s'"), bridge)
@@ -1695,8 +1712,9 @@ class QuantumLinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
utils.execute('ip', 'link', 'delete', dev, run_as_root=True,
check_exit_code=[0, 2, 254])
except exception.ProcessExecutionError:
- LOG.error(_("Failed unplugging gateway interface '%s'"), dev)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.error(_("Failed unplugging gateway interface '%s'"),
+ dev)
LOG.debug(_("Unplugged gateway interface '%s'"), dev)
return dev
diff --git a/nova/network/model.py b/nova/network/model.py
index bfd4639ee..32415be78 100644
--- a/nova/network/model.py
+++ b/nova/network/model.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/network/quantumv2/__init__.py b/nova/network/quantumv2/__init__.py
index 5d3cf5770..bda0392a9 100644
--- a/nova/network/quantumv2/__init__.py
+++ b/nova/network/quantumv2/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py
index 851a544dc..5537048a7 100644
--- a/nova/network/quantumv2/api.py
+++ b/nova/network/quantumv2/api.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved
# Copyright (c) 2012 NEC Corporation
#
@@ -172,9 +172,10 @@ class API(base.Base):
available_macs.discard(port['mac_address'])
network_id = port['network_id']
ports[network_id] = port
- elif fixed_ip:
+ elif fixed_ip and network_id:
fixed_ips[network_id] = fixed_ip
- net_ids.append(network_id)
+ if network_id:
+ net_ids.append(network_id)
nets = self._get_available_networks(context, instance['project_id'],
net_ids)
@@ -278,8 +279,15 @@ class API(base.Base):
self.trigger_security_group_members_refresh(context, instance)
self.trigger_instance_add_security_group_refresh(context, instance)
- return self.get_instance_nw_info(context, instance, networks=nets,
- conductor_api=kwargs.get('conductor_api'))
+ nw_info = self.get_instance_nw_info(context, instance, networks=nets,
+ conductor_api=kwargs.get('conductor_api'))
+ # NOTE(danms): Only return info about ports we created in this run.
+ # In the initial allocation case, this will be everything we created,
+ # and in later runs will only be what was created that time. Thus,
+ # this only affects the attach case, not the original use for this
+ # method.
+ return network_model.NetworkInfo([port for port in nw_info
+ if port['id'] in created_port_ids])
def _refresh_quantum_extensions_cache(self):
if (not self.last_quantum_extension_sync or
@@ -774,6 +782,12 @@ class API(base.Base):
network_name = net['name']
break
+ if network_name is None:
+ raise exception.NotFound(_('Network %(net)s for '
+ 'port %(port_id)s not found!') %
+ {'net': port['network_id'],
+ 'port': port['id']})
+
network_IPs = [network_model.FixedIP(address=ip_address)
for ip_address in [ip['ip_address']
for ip in port['fixed_ips']]]
diff --git a/nova/network/security_group/quantum_driver.py b/nova/network/security_group/quantum_driver.py
index 918c839e9..e6f88e20c 100644
--- a/nova/network/security_group/quantum_driver.py
+++ b/nova/network/security_group/quantum_driver.py
@@ -27,6 +27,7 @@ from nova import context
from nova import exception
from nova.network import quantumv2
from nova.network.security_group import security_group_base
+from nova.openstack.common import excutils
from nova.openstack.common import log as logging
from nova.openstack.common import uuidutils
@@ -90,13 +91,16 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
nova_rule['to_port'] = -1
else:
nova_rule['to_port'] = rule['port_range_max']
- nova_rule['group_id'] = rule['source_group_id']
- nova_rule['cidr'] = rule['source_ip_prefix']
+ nova_rule['group_id'] = rule['remote_group_id']
+ nova_rule['cidr'] = rule['remote_ip_prefix']
return nova_rule
def get(self, context, name=None, id=None, map_exception=False):
quantum = quantumv2.get_client(context)
try:
+ if not id and name:
+ id = quantumv20.find_resourceid_by_name_or_id(
+ quantum, 'security_group', name)
group = quantum.show_security_group(id).get('security_group')
except q_exc.QuantumClientException as e:
if e.status_code == 404:
@@ -113,8 +117,13 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
search_opts=None):
"""Returns list of security group rules owned by tenant."""
quantum = quantumv2.get_client(context)
+ search_opts = {}
+ if names:
+ search_opts['name'] = names
+ if ids:
+ search_opts['id'] = ids
try:
- security_groups = quantum.list_security_groups().get(
+ security_groups = quantum.list_security_groups(**search_opts).get(
'security_groups')
except q_exc.QuantumClientException as e:
LOG.exception(_("Quantum Error getting security groups"))
@@ -197,9 +206,9 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
new_rule['ethertype'] = 'IPv4'
else:
new_rule['ethertype'] = utils.get_ip_version(rule.get('cidr'))
- new_rule['source_ip_prefix'] = rule.get('cidr')
+ new_rule['remote_ip_prefix'] = rule.get('cidr')
new_rule['security_group_id'] = rule.get('parent_group_id')
- new_rule['source_group_id'] = rule.get('group_id')
+ new_rule['remote_group_id'] = rule.get('group_id')
if rule['from_port'] != -1:
new_rule['port_range_min'] = rule['from_port']
if rule['to_port'] != -1:
@@ -207,10 +216,6 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
new_rules.append(new_rule)
return {'security_group_rules': new_rules}
- def create_security_group_rule(self, context, security_group, new_rule):
- return self.add_rules(context, new_rule['parent_group_id'],
- security_group['name'], [new_rule])[0]
-
def remove_rules(self, context, security_group, rule_ids):
quantum = quantumv2.get_client(context)
rule_ids = set(rule_ids)
@@ -328,8 +333,8 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
'port_id': port['id']})
quantum.update_port(port['id'], {'port': updated_port})
except Exception:
- LOG.exception(_("Quantum Error:"))
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_("Quantum Error:"))
@wrap_check_security_groups_policy
def remove_from_instance(self, context, instance, security_group_name):
@@ -388,10 +393,6 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
'instance': instance['uuid']})
self.raise_not_found(msg)
- def rule_exists(self, security_group, new_rule):
- # Handled by quantum
- pass
-
def populate_security_groups(self, instance, security_groups):
# Setting to emply list since we do not want to populate this field
# in the nova database if using the quantum driver
diff --git a/nova/network/security_group/security_group_base.py b/nova/network/security_group/security_group_base.py
index 499f808b1..4a82bd881 100644
--- a/nova/network/security_group/security_group_base.py
+++ b/nova/network/security_group/security_group_base.py
@@ -132,6 +132,30 @@ class SecurityGroupBase(object):
return values
+ def create_security_group_rule(self, context, security_group, new_rule):
+ if self.rule_exists(security_group, new_rule):
+ msg = (_('This rule already exists in group %s') %
+ new_rule['parent_group_id'])
+ self.raise_group_already_exists(msg)
+ return self.add_rules(context, new_rule['parent_group_id'],
+ security_group['name'],
+ [new_rule])[0]
+
+ def rule_exists(self, security_group, new_rule):
+ """Indicates whether the specified rule is already
+ defined in the given security group.
+ """
+ for rule in security_group['rules']:
+ is_duplicate = True
+ keys = ('group_id', 'cidr', 'from_port', 'to_port', 'protocol')
+ for key in keys:
+ if rule.get(key) != new_rule.get(key):
+ is_duplicate = False
+ break
+ if is_duplicate:
+ return rule.get('id') or True
+ return False
+
def validate_property(self, value, property, allowed):
pass
@@ -174,9 +198,6 @@ class SecurityGroupBase(object):
def add_rules(self, context, id, name, vals):
raise NotImplementedError()
- def create_security_group_rule(self, context, security_group, new_rule):
- raise NotImplementedError()
-
def remove_rules(self, context, security_group, rule_ids):
raise NotImplementedError()
@@ -192,5 +213,26 @@ class SecurityGroupBase(object):
def remove_from_instance(self, context, instance, security_group_name):
raise NotImplementedError()
- def rule_exists(self, security_group, new_rule):
+ @staticmethod
+ def raise_invalid_property(msg):
+ raise NotImplementedError()
+
+ @staticmethod
+ def raise_group_already_exists(msg):
+ raise NotImplementedError()
+
+ @staticmethod
+ def raise_invalid_group(msg):
+ raise NotImplementedError()
+
+ @staticmethod
+ def raise_invalid_cidr(cidr, decoding_exception=None):
+ raise NotImplementedError()
+
+ @staticmethod
+ def raise_over_quota(msg):
+ raise NotImplementedError()
+
+ @staticmethod
+ def raise_not_found(msg):
raise NotImplementedError()
diff --git a/nova/notifications.py b/nova/notifications.py
index 79d43126a..16a49dcf6 100644
--- a/nova/notifications.py
+++ b/nova/notifications.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -26,6 +26,7 @@ from nova import db
from nova.image import glance
from nova import network
from nova.network import model as network_model
+from nova.openstack.common import excutils
from nova.openstack.common import log
from nova.openstack.common.notifier import api as notifier_api
from nova.openstack.common import timeutils
@@ -33,27 +34,25 @@ from nova import utils
LOG = log.getLogger(__name__)
-notify_state_opt = cfg.StrOpt('notify_on_state_change', default=None,
- help='If set, send compute.instance.update notifications on instance '
- 'state changes. Valid values are None for no notifications, '
- '"vm_state" for notifications on VM state changes, or '
- '"vm_and_task_state" for notifications on VM and task state '
- 'changes.')
-
-notify_any_opt = cfg.BoolOpt('notify_on_any_change', default=False,
- help='If set, send compute.instance.update notifications on instance '
- 'state changes. Valid values are False for no notifications, '
- 'True for notifications on any instance changes.')
-
-notify_api_faults = cfg.BoolOpt('notify_api_faults', default=False,
- help='If set, send api.fault notifications on caught exceptions '
- 'in the API service.')
+notify_opts = [
+ cfg.StrOpt('notify_on_state_change', default=None,
+ help='If set, send compute.instance.update notifications on instance '
+ 'state changes. Valid values are None for no notifications, '
+ '"vm_state" for notifications on VM state changes, or '
+ '"vm_and_task_state" for notifications on VM and task state '
+ 'changes.'),
+ cfg.BoolOpt('notify_on_any_change', default=False,
+ help='If set, send compute.instance.update notifications on instance '
+ 'state changes. Valid values are False for no notifications, '
+ 'True for notifications on any instance changes.'),
+ cfg.BoolOpt('notify_api_faults', default=False,
+ help='If set, send api.fault notifications on caught exceptions '
+ 'in the API service.'),
+]
CONF = cfg.CONF
-CONF.register_opt(notify_state_opt)
-CONF.register_opt(notify_any_opt)
-CONF.register_opt(notify_api_faults)
+CONF.register_opts(notify_opts)
def send_api_fault(url, status, exception):
@@ -227,10 +226,14 @@ def bandwidth_usage(instance_ref, audit_start,
nw_info = network.API().get_instance_nw_info(admin_context,
instance_ref)
except Exception:
- LOG.exception(_('Failed to get nw_info'), instance=instance_ref)
- if ignore_missing_network_data:
- return
- raise
+ try:
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_('Failed to get nw_info'),
+ instance=instance_ref)
+ except Exception:
+ if ignore_missing_network_data:
+ return
+ raise
macs = [vif['address'] for vif in nw_info]
uuids = [instance_ref["uuid"]]
diff --git a/nova/objectstore/s3server.py b/nova/objectstore/s3server.py
index 3ff5fa003..1c9f19a4e 100644
--- a/nova/objectstore/s3server.py
+++ b/nova/objectstore/s3server.py
@@ -2,7 +2,7 @@
#
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/context.py b/nova/openstack/common/context.py
index dd7dd04c3..709ce4d45 100644
--- a/nova/openstack/common/context.py
+++ b/nova/openstack/common/context.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/db/exception.py b/nova/openstack/common/db/exception.py
new file mode 100644
index 000000000..61ba1b3a9
--- /dev/null
+++ b/nova/openstack/common/db/exception.py
@@ -0,0 +1,45 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""DB related custom exceptions."""
+
+from nova.openstack.common.gettextutils import _
+
+
+class DBError(Exception):
+ """Wraps an implementation specific exception."""
+ def __init__(self, inner_exception=None):
+ self.inner_exception = inner_exception
+ super(DBError, self).__init__(str(inner_exception))
+
+
+class DBDuplicateEntry(DBError):
+ """Wraps an implementation specific exception."""
+ def __init__(self, columns=[], inner_exception=None):
+ self.columns = columns
+ super(DBDuplicateEntry, self).__init__(inner_exception)
+
+
+class DBDeadlock(DBError):
+ def __init__(self, inner_exception=None):
+ super(DBDeadlock, self).__init__(inner_exception)
+
+
+class DBInvalidUnicodeParameter(Exception):
+ message = _("Invalid Parameter: "
+ "Unicode is not supported by the current database.")
diff --git a/nova/openstack/common/db/sqlalchemy/session.py b/nova/openstack/common/db/sqlalchemy/session.py
index fb86d9ca5..cf6713581 100644
--- a/nova/openstack/common/db/sqlalchemy/session.py
+++ b/nova/openstack/common/db/sqlalchemy/session.py
@@ -246,12 +246,13 @@ import time
from eventlet import greenthread
from oslo.config import cfg
-from sqlalchemy.exc import DisconnectionError, OperationalError, IntegrityError
+from sqlalchemy import exc as sqla_exc
import sqlalchemy.interfaces
import sqlalchemy.orm
from sqlalchemy.pool import NullPool, StaticPool
from sqlalchemy.sql.expression import literal_column
+from nova.openstack.common.db import exception
from nova.openstack.common import log as logging
from nova.openstack.common.gettextutils import _
from nova.openstack.common import timeutils
@@ -327,25 +328,6 @@ def get_session(autocommit=True, expire_on_commit=False):
return session
-class DBError(Exception):
- """Wraps an implementation specific exception."""
- def __init__(self, inner_exception=None):
- self.inner_exception = inner_exception
- super(DBError, self).__init__(str(inner_exception))
-
-
-class DBDuplicateEntry(DBError):
- """Wraps an implementation specific exception."""
- def __init__(self, columns=[], inner_exception=None):
- self.columns = columns
- super(DBDuplicateEntry, self).__init__(inner_exception)
-
-
-class InvalidUnicodeParameter(Exception):
- message = _("Invalid Parameter: "
- "Unicode is not supported by the current database.")
-
-
# note(boris-42): In current versions of DB backends unique constraint
# violation messages follow the structure:
#
@@ -364,7 +346,7 @@ class InvalidUnicodeParameter(Exception):
# 'c1'")
# N columns - (IntegrityError) (1062, "Duplicate entry 'values joined
# with -' for key 'name_of_our_constraint'")
-_RE_DB = {
+_DUP_KEY_RE_DB = {
"sqlite": re.compile(r"^.*columns?([^)]+)(is|are)\s+not\s+unique$"),
"postgresql": re.compile(r"^.*duplicate\s+key.*\"([^\"]+)\"\s*\n.*$"),
"mysql": re.compile(r"^.*\(1062,.*'([^\']+)'\"\)$")
@@ -390,7 +372,7 @@ def raise_if_duplicate_entry_error(integrity_error, engine_name):
if engine_name not in ["mysql", "sqlite", "postgresql"]:
return
- m = _RE_DB[engine_name].match(integrity_error.message)
+ m = _DUP_KEY_RE_DB[engine_name].match(integrity_error.message)
if not m:
return
columns = m.group(1)
@@ -399,7 +381,32 @@ def raise_if_duplicate_entry_error(integrity_error, engine_name):
columns = columns.strip().split(", ")
else:
columns = get_columns_from_uniq_cons_or_name(columns)
- raise DBDuplicateEntry(columns, integrity_error)
+ raise exception.DBDuplicateEntry(columns, integrity_error)
+
+
+# NOTE(comstud): In current versions of DB backends, Deadlock violation
+# messages follow the structure:
+#
+# mysql:
+# (OperationalError) (1213, 'Deadlock found when trying to get lock; try '
+# 'restarting transaction') <query_str> <query_args>
+_DEADLOCK_RE_DB = {
+ "mysql": re.compile(r"^.*\(1213, 'Deadlock.*")
+}
+
+
+def raise_if_deadlock_error(operational_error, engine_name):
+ """
+ Raise DBDeadlock exception if OperationalError contains a Deadlock
+ condition.
+ """
+ re = _DEADLOCK_RE_DB.get(engine_name)
+ if re is None:
+ return
+ m = re.match(operational_error.message)
+ if not m:
+ return
+ raise exception.DBDeadlock(operational_error)
def wrap_db_error(f):
@@ -407,21 +414,26 @@ def wrap_db_error(f):
try:
return f(*args, **kwargs)
except UnicodeEncodeError:
- raise InvalidUnicodeParameter()
+ raise exception.DBInvalidUnicodeParameter()
# note(boris-42): We should catch unique constraint violation and
# wrap it by our own DBDuplicateEntry exception. Unique constraint
# violation is wrapped by IntegrityError.
- except IntegrityError, e:
+ except sqla_exc.OperationalError, e:
+ raise_if_deadlock_error(e, get_engine().name)
+ # NOTE(comstud): A lot of code is checking for OperationalError
+ # so let's not wrap it for now.
+ raise
+ except sqla_exc.IntegrityError, e:
# note(boris-42): SqlAlchemy doesn't unify errors from different
# DBs so we must do this. Also in some tables (for example
# instance_types) there are more than one unique constraint. This
# means we should get names of columns, which values violate
# unique constraint, from error message.
raise_if_duplicate_entry_error(e, get_engine().name)
- raise DBError(e)
+ raise exception.DBError(e)
except Exception, e:
LOG.exception(_('DB exception wrapped.'))
- raise DBError(e)
+ raise exception.DBError(e)
_wrap.func_name = f.func_name
return _wrap
@@ -471,7 +483,7 @@ def ping_listener(dbapi_conn, connection_rec, connection_proxy):
except dbapi_conn.OperationalError, ex:
if ex.args[0] in (2006, 2013, 2014, 2045, 2055):
LOG.warn(_('Got mysql server has gone away: %s'), ex)
- raise DisconnectionError("Database server went away")
+ raise sqla_exc.DisconnectionError("Database server went away")
else:
raise
@@ -532,7 +544,7 @@ def create_engine(sql_connection):
try:
engine.connect()
- except OperationalError, e:
+ except sqla_exc.OperationalError, e:
if not is_db_connection_error(e.args[0]):
raise
@@ -548,7 +560,7 @@ def create_engine(sql_connection):
try:
engine.connect()
break
- except OperationalError, e:
+ except sqla_exc.OperationalError, e:
if (remaining != 'infinite' and remaining == 0) or \
not is_db_connection_error(e.args[0]):
raise
diff --git a/nova/openstack/common/db/sqlalchemy/utils.py b/nova/openstack/common/db/sqlalchemy/utils.py
index ef8af57ce..6a9cb846f 100644
--- a/nova/openstack/common/db/sqlalchemy/utils.py
+++ b/nova/openstack/common/db/sqlalchemy/utils.py
@@ -2,7 +2,7 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# Copyright 2012 Justin Santa Barbara
# All Rights Reserved.
#
diff --git a/nova/openstack/common/eventlet_backdoor.py b/nova/openstack/common/eventlet_backdoor.py
index 8b81ebf8e..007676847 100644
--- a/nova/openstack/common/eventlet_backdoor.py
+++ b/nova/openstack/common/eventlet_backdoor.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 Openstack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
diff --git a/nova/openstack/common/excutils.py b/nova/openstack/common/excutils.py
index e507efced..bfd3fc0ed 100644
--- a/nova/openstack/common/excutils.py
+++ b/nova/openstack/common/excutils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2012, Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/fileutils.py b/nova/openstack/common/fileutils.py
index 4746ad498..cc52e7d44 100644
--- a/nova/openstack/common/fileutils.py
+++ b/nova/openstack/common/fileutils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/importutils.py b/nova/openstack/common/importutils.py
index 9dec764fb..8b5c00892 100644
--- a/nova/openstack/common/importutils.py
+++ b/nova/openstack/common/importutils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/jsonutils.py b/nova/openstack/common/jsonutils.py
index b06055117..3a2f27730 100644
--- a/nova/openstack/common/jsonutils.py
+++ b/nova/openstack/common/jsonutils.py
@@ -38,14 +38,10 @@ import functools
import inspect
import itertools
import json
-import logging
import xmlrpclib
-from nova.openstack.common.gettextutils import _
from nova.openstack.common import timeutils
-LOG = logging.getLogger(__name__)
-
def to_primitive(value, convert_instances=False, convert_datetime=True,
level=0, max_depth=3):
@@ -85,8 +81,6 @@ def to_primitive(value, convert_instances=False, convert_datetime=True,
return 'mock'
if level > max_depth:
- LOG.error(_('Max serialization depth exceeded on object: %d %s'),
- level, value)
return '?'
# The try block may not be necessary after the class check above,
diff --git a/nova/openstack/common/local.py b/nova/openstack/common/local.py
index 8bdc837a9..a9796bfe7 100644
--- a/nova/openstack/common/local.py
+++ b/nova/openstack/common/local.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/lockutils.py b/nova/openstack/common/lockutils.py
index 6ee376929..3270f0473 100644
--- a/nova/openstack/common/lockutils.py
+++ b/nova/openstack/common/lockutils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/log.py b/nova/openstack/common/log.py
index 796045657..dfad9919f 100644
--- a/nova/openstack/common/log.py
+++ b/nova/openstack/common/log.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
@@ -325,16 +325,11 @@ def _create_logging_excepthook(product_name):
def setup(product_name):
"""Setup logging."""
- sys.excepthook = _create_logging_excepthook(product_name)
-
if CONF.log_config:
- try:
- logging.config.fileConfig(CONF.log_config)
- except Exception:
- traceback.print_exc()
- raise
+ logging.config.fileConfig(CONF.log_config)
else:
_setup_logging_from_conf(product_name)
+ sys.excepthook = _create_logging_excepthook(product_name)
def set_defaults(logging_context_format_string):
diff --git a/nova/common/memorycache.py b/nova/openstack/common/memorycache.py
index c124784d5..9f876b80c 100644
--- a/nova/common/memorycache.py
+++ b/nova/openstack/common/memorycache.py
@@ -32,14 +32,19 @@ CONF = cfg.CONF
CONF.register_opts(memcache_opts)
-def get_client():
+def get_client(memcached_servers=None):
client_cls = Client
- if CONF.memcached_servers:
- import memcache
- client_cls = memcache.Client
+ if not memcached_servers:
+ memcached_servers = CONF.memcached_servers
+ if memcached_servers:
+ try:
+ import memcache
+ client_cls = memcache.Client
+ except ImportError:
+ pass
- return client_cls(CONF.memcached_servers, debug=0)
+ return client_cls(memcached_servers, debug=0)
class Client(object):
@@ -54,9 +59,10 @@ class Client(object):
this expunges expired keys during each get"""
+ now = timeutils.utcnow_ts()
for k in self.cache.keys():
(timeout, _value) = self.cache[k]
- if timeout and timeutils.utcnow_ts() >= timeout:
+ if timeout and now >= timeout:
del self.cache[k]
return self.cache.get(key, (0, None))[1]
diff --git a/nova/openstack/common/network_utils.py b/nova/openstack/common/network_utils.py
index 69f673216..65299b009 100644
--- a/nova/openstack/common/network_utils.py
+++ b/nova/openstack/common/network_utils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/notifier/__init__.py b/nova/openstack/common/notifier/__init__.py
index 482d54e4f..31285c4fc 100644
--- a/nova/openstack/common/notifier/__init__.py
+++ b/nova/openstack/common/notifier/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/notifier/api.py b/nova/openstack/common/notifier/api.py
index 70941e243..cb0a38b71 100644
--- a/nova/openstack/common/notifier/api.py
+++ b/nova/openstack/common/notifier/api.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/notifier/log_notifier.py b/nova/openstack/common/notifier/log_notifier.py
index 4fe4d74ea..51e488c94 100644
--- a/nova/openstack/common/notifier/log_notifier.py
+++ b/nova/openstack/common/notifier/log_notifier.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/notifier/no_op_notifier.py b/nova/openstack/common/notifier/no_op_notifier.py
index ee1ddbdca..d22d02072 100644
--- a/nova/openstack/common/notifier/no_op_notifier.py
+++ b/nova/openstack/common/notifier/no_op_notifier.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/notifier/rpc_notifier.py b/nova/openstack/common/notifier/rpc_notifier.py
index b348480c9..a119b2b7a 100644
--- a/nova/openstack/common/notifier/rpc_notifier.py
+++ b/nova/openstack/common/notifier/rpc_notifier.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/notifier/rpc_notifier2.py b/nova/openstack/common/notifier/rpc_notifier2.py
index f1158a2f9..d2ad74fb4 100644
--- a/nova/openstack/common/notifier/rpc_notifier2.py
+++ b/nova/openstack/common/notifier/rpc_notifier2.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/notifier/test_notifier.py b/nova/openstack/common/notifier/test_notifier.py
index 5e348803d..2e392f8b9 100644
--- a/nova/openstack/common/notifier/test_notifier.py
+++ b/nova/openstack/common/notifier/test_notifier.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/plugin/__init__.py b/nova/openstack/common/plugin/__init__.py
index 63c3905e2..bf3075ddd 100644
--- a/nova/openstack/common/plugin/__init__.py
+++ b/nova/openstack/common/plugin/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/plugin/callbackplugin.py b/nova/openstack/common/plugin/callbackplugin.py
index d19a1cf48..371819189 100644
--- a/nova/openstack/common/plugin/callbackplugin.py
+++ b/nova/openstack/common/plugin/callbackplugin.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/plugin/plugin.py b/nova/openstack/common/plugin/plugin.py
index 96be0af82..66feb000b 100644
--- a/nova/openstack/common/plugin/plugin.py
+++ b/nova/openstack/common/plugin/plugin.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/plugin/pluginmanager.py b/nova/openstack/common/plugin/pluginmanager.py
index 040b721a4..b789c2c7c 100644
--- a/nova/openstack/common/plugin/pluginmanager.py
+++ b/nova/openstack/common/plugin/pluginmanager.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/policy.py b/nova/openstack/common/policy.py
index 626a61aa5..8ed40477e 100644
--- a/nova/openstack/common/policy.py
+++ b/nova/openstack/common/policy.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/processutils.py b/nova/openstack/common/processutils.py
index 297f911c4..8ace63176 100644
--- a/nova/openstack/common/processutils.py
+++ b/nova/openstack/common/processutils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/rootwrap/__init__.py b/nova/openstack/common/rootwrap/__init__.py
index 671d3c173..f0f23d6a2 100644
--- a/nova/openstack/common/rootwrap/__init__.py
+++ b/nova/openstack/common/rootwrap/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/rootwrap/filters.py b/nova/openstack/common/rootwrap/filters.py
index 905bbabea..8e92d6bb4 100644
--- a/nova/openstack/common/rootwrap/filters.py
+++ b/nova/openstack/common/rootwrap/filters.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/rootwrap/wrapper.py b/nova/openstack/common/rootwrap/wrapper.py
index 4452177fe..7dc533e1e 100644
--- a/nova/openstack/common/rootwrap/wrapper.py
+++ b/nova/openstack/common/rootwrap/wrapper.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/rpc/impl_fake.py b/nova/openstack/common/rpc/impl_fake.py
index f43dbfe91..965d2640d 100644
--- a/nova/openstack/common/rpc/impl_fake.py
+++ b/nova/openstack/common/rpc/impl_fake.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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/openstack/common/rpc/impl_kombu.py b/nova/openstack/common/rpc/impl_kombu.py
index 180685cf3..0d83253f1 100644
--- a/nova/openstack/common/rpc/impl_kombu.py
+++ b/nova/openstack/common/rpc/impl_kombu.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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/openstack/common/rpc/impl_qpid.py b/nova/openstack/common/rpc/impl_qpid.py
index 5601ddb33..542256d0c 100644
--- a/nova/openstack/common/rpc/impl_qpid.py
+++ b/nova/openstack/common/rpc/impl_qpid.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
# Copyright 2011 - 2012, Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/openstack/common/setup.py b/nova/openstack/common/setup.py
index 35680b304..de008ab15 100644
--- a/nova/openstack/common/setup.py
+++ b/nova/openstack/common/setup.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
diff --git a/nova/openstack/common/version.py b/nova/openstack/common/version.py
index 57803b3d5..6bf41a75c 100644
--- a/nova/openstack/common/version.py
+++ b/nova/openstack/common/version.py
@@ -1,5 +1,5 @@
-# Copyright 2012 OpenStack LLC
+# Copyright 2012 OpenStack Foundation
# Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/policy.py b/nova/policy.py
index 6e500d926..68f449696 100644
--- a/nova/policy.py
+++ b/nova/policy.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/safe_utils.py b/nova/safe_utils.py
new file mode 100644
index 000000000..9c8fc2810
--- /dev/null
+++ b/nova/safe_utils.py
@@ -0,0 +1,55 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# Copyright 2011 Justin Santa Barbara
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Utilities and helper functions that won't produce circular imports."""
+
+import inspect
+
+
+def getcallargs(function, *args, **kwargs):
+ """This is a simplified inspect.getcallargs (2.7+).
+
+ It should be replaced when python >= 2.7 is standard.
+ """
+ keyed_args = {}
+ argnames, varargs, keywords, defaults = inspect.getargspec(function)
+
+ keyed_args.update(kwargs)
+
+ #NOTE(alaski) the implicit 'self' or 'cls' argument shows up in
+ # argnames but not in args or kwargs. Uses 'in' rather than '==' because
+ # some tests use 'self2'.
+ if 'self' in argnames[0] or 'cls' == argnames[0]:
+ # The function may not actually be a method or have im_self.
+ # Typically seen when it's stubbed with mox.
+ if inspect.ismethod(function) and hasattr(function, 'im_self'):
+ keyed_args[argnames[0]] = function.im_self
+ else:
+ keyed_args[argnames[0]] = None
+
+ remaining_argnames = filter(lambda x: x not in keyed_args, argnames)
+ keyed_args.update(dict(zip(remaining_argnames, args)))
+
+ if defaults:
+ num_defaults = len(defaults)
+ for argname, value in zip(argnames[-num_defaults:], defaults):
+ if argname not in keyed_args:
+ keyed_args[argname] = value
+
+ return keyed_args
diff --git a/nova/scheduler/__init__.py b/nova/scheduler/__init__.py
index 32e5d4d02..7dc4ffc35 100644
--- a/nova/scheduler/__init__.py
+++ b/nova/scheduler/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
#
# 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/scheduler/baremetal_host_manager.py b/nova/scheduler/baremetal_host_manager.py
index fdf482de7..226476714 100644
--- a/nova/scheduler/baremetal_host_manager.py
+++ b/nova/scheduler/baremetal_host_manager.py
@@ -1,5 +1,5 @@
# Copyright (c) 2012 NTT DOCOMO, INC.
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/chance.py b/nova/scheduler/chance.py
index c639aaf80..5bbc3ac3b 100644
--- a/nova/scheduler/chance.py
+++ b/nova/scheduler/chance.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
diff --git a/nova/scheduler/driver.py b/nova/scheduler/driver.py
index 96a3e5e98..3426c484c 100644
--- a/nova/scheduler/driver.py
+++ b/nova/scheduler/driver.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
@@ -256,9 +256,11 @@ class Scheduler(object):
# If dest is not specified, have scheduler pick one.
if dest is None:
+ instance_type = db.instance_type_get(
+ context, instance_ref['instance_type_id'])
image = self.image_service.show(context, instance_ref['image_ref'])
request_spec = {'instance_properties': instance_ref,
- 'instance_type': instance_ref['instance_type'],
+ 'instance_type': instance_type,
'instance_uuids': [instance_ref['uuid']],
'image': image}
filter_properties = {'ignore_hosts': ignore_hosts}
diff --git a/nova/scheduler/filter_scheduler.py b/nova/scheduler/filter_scheduler.py
index b886a04cc..b9768e11b 100644
--- a/nova/scheduler/filter_scheduler.py
+++ b/nova/scheduler/filter_scheduler.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/__init__.py b/nova/scheduler/filters/__init__.py
index 6e8e7ea7b..0bd069826 100644
--- a/nova/scheduler/filters/__init__.py
+++ b/nova/scheduler/filters/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/affinity_filter.py b/nova/scheduler/filters/affinity_filter.py
index a7e894320..bb7cb4aff 100644
--- a/nova/scheduler/filters/affinity_filter.py
+++ b/nova/scheduler/filters/affinity_filter.py
@@ -1,5 +1,5 @@
# Copyright 2012, Piston Cloud Computing, Inc.
-# Copyright 2012, OpenStack LLC.
+# Copyright 2012, OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/nova/scheduler/filters/aggregate_instance_extra_specs.py b/nova/scheduler/filters/aggregate_instance_extra_specs.py
index 3a3628f6a..6e1e47f68 100644
--- a/nova/scheduler/filters/aggregate_instance_extra_specs.py
+++ b/nova/scheduler/filters/aggregate_instance_extra_specs.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# Copyright (c) 2012 Cloudscaling
# All Rights Reserved.
#
diff --git a/nova/scheduler/filters/aggregate_multitenancy_isolation.py b/nova/scheduler/filters/aggregate_multitenancy_isolation.py
index 539da37d1..d9192af52 100644
--- a/nova/scheduler/filters/aggregate_multitenancy_isolation.py
+++ b/nova/scheduler/filters/aggregate_multitenancy_isolation.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2013 OpenStack, LLC.
+# Copyright (c) 2011-2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/all_hosts_filter.py b/nova/scheduler/filters/all_hosts_filter.py
index 4e01a624e..d6973f944 100644
--- a/nova/scheduler/filters/all_hosts_filter.py
+++ b/nova/scheduler/filters/all_hosts_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2012 OpenStack, LLC.
+# Copyright (c) 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/availability_zone_filter.py b/nova/scheduler/filters/availability_zone_filter.py
index f6c7472bf..fc578a7fb 100644
--- a/nova/scheduler/filters/availability_zone_filter.py
+++ b/nova/scheduler/filters/availability_zone_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2012 OpenStack, LLC.
+# Copyright (c) 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/compute_capabilities_filter.py b/nova/scheduler/filters/compute_capabilities_filter.py
index acbfa4702..e559c18a8 100644
--- a/nova/scheduler/filters/compute_capabilities_filter.py
+++ b/nova/scheduler/filters/compute_capabilities_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/compute_filter.py b/nova/scheduler/filters/compute_filter.py
index f571955d9..f6c643c1c 100644
--- a/nova/scheduler/filters/compute_filter.py
+++ b/nova/scheduler/filters/compute_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/core_filter.py b/nova/scheduler/filters/core_filter.py
index a07a1b39a..4eb6ebcf1 100644
--- a/nova/scheduler/filters/core_filter.py
+++ b/nova/scheduler/filters/core_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# Copyright (c) 2012 Justin Santa Barbara
#
# All Rights Reserved.
diff --git a/nova/scheduler/filters/disk_filter.py b/nova/scheduler/filters/disk_filter.py
index 812b9b212..517d43510 100644
--- a/nova/scheduler/filters/disk_filter.py
+++ b/nova/scheduler/filters/disk_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/extra_specs_ops.py b/nova/scheduler/filters/extra_specs_ops.py
index c77cd7b60..22fb219df 100644
--- a/nova/scheduler/filters/extra_specs_ops.py
+++ b/nova/scheduler/filters/extra_specs_ops.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/image_props_filter.py b/nova/scheduler/filters/image_props_filter.py
index a545ce9ff..185d2f4e4 100644
--- a/nova/scheduler/filters/image_props_filter.py
+++ b/nova/scheduler/filters/image_props_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2012 OpenStack, LLC
+# Copyright (c) 2011-2012 OpenStack Foundation
# Copyright (c) 2012 Canonical Ltd
# Copyright (c) 2012 SUSE LINUX Products GmbH
# All Rights Reserved.
diff --git a/nova/scheduler/filters/io_ops_filter.py b/nova/scheduler/filters/io_ops_filter.py
index a60be57e2..7d3337c1a 100644
--- a/nova/scheduler/filters/io_ops_filter.py
+++ b/nova/scheduler/filters/io_ops_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/isolated_hosts_filter.py b/nova/scheduler/filters/isolated_hosts_filter.py
index 89beb0ed0..c8849bcca 100644
--- a/nova/scheduler/filters/isolated_hosts_filter.py
+++ b/nova/scheduler/filters/isolated_hosts_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2012 OpenStack, LLC.
+# Copyright (c) 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/json_filter.py b/nova/scheduler/filters/json_filter.py
index f77d6dad3..7387cb363 100644
--- a/nova/scheduler/filters/json_filter.py
+++ b/nova/scheduler/filters/json_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/num_instances_filter.py b/nova/scheduler/filters/num_instances_filter.py
index f65fccbf6..06b5b5b73 100644
--- a/nova/scheduler/filters/num_instances_filter.py
+++ b/nova/scheduler/filters/num_instances_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/ram_filter.py b/nova/scheduler/filters/ram_filter.py
index 3345bf386..fdf189735 100644
--- a/nova/scheduler/filters/ram_filter.py
+++ b/nova/scheduler/filters/ram_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# Copyright (c) 2012 Cloudscaling
# All Rights Reserved.
#
diff --git a/nova/scheduler/filters/retry_filter.py b/nova/scheduler/filters/retry_filter.py
index 4d6ed50ee..d49ad1c36 100644
--- a/nova/scheduler/filters/retry_filter.py
+++ b/nova/scheduler/filters/retry_filter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/filters/trusted_filter.py b/nova/scheduler/filters/trusted_filter.py
index a7bb850bf..411ae93bd 100644
--- a/nova/scheduler/filters/trusted_filter.py
+++ b/nova/scheduler/filters/trusted_filter.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 Intel, Inc.
-# Copyright (c) 2011-2012 OpenStack, LLC.
+# Copyright (c) 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/host_manager.py b/nova/scheduler/host_manager.py
index c004b2947..d12f15f38 100644
--- a/nova/scheduler/host_manager.py
+++ b/nova/scheduler/host_manager.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py
index a9b774a4d..11798ca04 100644
--- a/nova/scheduler/manager.py
+++ b/nova/scheduler/manager.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
diff --git a/nova/scheduler/multi.py b/nova/scheduler/multi.py
index ec45ad618..2077fce5b 100644
--- a/nova/scheduler/multi.py
+++ b/nova/scheduler/multi.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
diff --git a/nova/scheduler/scheduler_options.py b/nova/scheduler/scheduler_options.py
index 1753c897b..f7aa91155 100644
--- a/nova/scheduler/scheduler_options.py
+++ b/nova/scheduler/scheduler_options.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -28,6 +28,7 @@ import os
from oslo.config import cfg
+from nova.openstack.common import excutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
@@ -66,9 +67,9 @@ class SchedulerOptions(object):
try:
return os.path.getmtime(filename)
except os.error, e:
- LOG.exception(_("Could not stat scheduler options file "
- "%(filename)s: '%(e)s'"), locals())
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.exception(_("Could not stat scheduler options file "
+ "%(filename)s: '%(e)s'"), locals())
def _load_file(self, handle):
"""Decode the JSON file. Broken out for testing."""
diff --git a/nova/scheduler/weights/__init__.py b/nova/scheduler/weights/__init__.py
index f96ec929a..1a8a15c43 100644
--- a/nova/scheduler/weights/__init__.py
+++ b/nova/scheduler/weights/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/weights/least_cost.py b/nova/scheduler/weights/least_cost.py
index 0e617ff42..d3e04f47e 100644
--- a/nova/scheduler/weights/least_cost.py
+++ b/nova/scheduler/weights/least_cost.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2012 OpenStack, LLC.
+# Copyright (c) 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/scheduler/weights/ram.py b/nova/scheduler/weights/ram.py
index 3fc15fbdf..b8478c7bd 100644
--- a/nova/scheduler/weights/ram.py
+++ b/nova/scheduler/weights/ram.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/servicegroup/__init__.py b/nova/servicegroup/__init__.py
index a804c62fa..02a808a14 100644
--- a/nova/servicegroup/__init__.py
+++ b/nova/servicegroup/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (c) IBM 2012 Pavel Kravchenco <kpavel at il dot ibm dot com>
+# Copyright 2012 IBM Corp.
# Copyright (c) AT&T Labs Inc. 2012 Yun Mao <yunmao@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/nova/servicegroup/api.py b/nova/servicegroup/api.py
index 2701329a0..902d4b640 100644
--- a/nova/servicegroup/api.py
+++ b/nova/servicegroup/api.py
@@ -1,5 +1,4 @@
-# Copyright (c) IBM 2012 Pavel Kravchenco <kpavel at il dot ibm dot com>
-# Alexey Roytman <roytman at il dot ibm dot com>
+# Copyright 2012 IBM Corp.
# Copyright (c) AT&T Labs Inc. 2012 Yun Mao <yunmao@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/nova/servicegroup/drivers/db.py b/nova/servicegroup/drivers/db.py
index 994015b34..aa29596db 100644
--- a/nova/servicegroup/drivers/db.py
+++ b/nova/servicegroup/drivers/db.py
@@ -1,5 +1,4 @@
-# Copyright (c) IBM 2012 Pavel Kravchenco <kpavel at il dot ibm dot com>
-# Alexey Roytman <roytman at il dot ibm dot com>
+# Copyright 2012 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/nova/servicegroup/drivers/mc.py b/nova/servicegroup/drivers/mc.py
index 2857185d9..0801138ff 100644
--- a/nova/servicegroup/drivers/mc.py
+++ b/nova/servicegroup/drivers/mc.py
@@ -2,8 +2,7 @@
# Copyright (c) 2013 Akira Yoshiyama <akirayoshiyama at gmail dot com>
#
# This is derived from nova/servicegroup/drivers/db.py.
-# Copyright (c) IBM 2012 Pavel Kravchenco <kpavel at il dot ibm dot com>
-# Alexey Roytman <roytman at il dot ibm dot com>
+# Copyright 2012 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -20,10 +19,10 @@
from oslo.config import cfg
-from nova.common import memorycache
from nova import conductor
from nova import context
from nova.openstack.common import log as logging
+from nova.openstack.common import memorycache
from nova.openstack.common import timeutils
from nova.servicegroup import api
from nova import utils
@@ -31,7 +30,7 @@ from nova import utils
CONF = cfg.CONF
CONF.import_opt('service_down_time', 'nova.service')
-CONF.import_opt('memcached_servers', 'nova.common.memorycache')
+CONF.import_opt('memcached_servers', 'nova.openstack.common.memorycache')
LOG = logging.getLogger(__name__)
diff --git a/nova/servicegroup/drivers/zk.py b/nova/servicegroup/drivers/zk.py
index 92b49f274..4326ef444 100644
--- a/nova/servicegroup/drivers/zk.py
+++ b/nova/servicegroup/drivers/zk.py
@@ -1,7 +1,5 @@
# Copyright (c) AT&T 2012-2013 Yun Mao <yunmao@gmail.com>
-#
-# Copyright (c) IBM 2012 Pavel Kravchenco <kpavel at il dot ibm dot com>
-# Alexey Roytman <roytman at il dot ibm dot com>
+# Copyright 2012 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,16 +17,17 @@
import os
import eventlet
-import evzookeeper
-from evzookeeper import membership
from oslo.config import cfg
-import zookeeper
from nova import exception
+from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.servicegroup import api
from nova import utils
+evzookeeper = importutils.try_import('evzookeeper')
+membership = importutils.try_import('evzookeeper.membersip')
+zookeeper = importutils.try_import('zookeeper')
zk_driver_opts = [
cfg.StrOpt('address',
@@ -58,16 +57,18 @@ class ZooKeeperDriver(api.ServiceGroupDriver):
def __init__(self, *args, **kwargs):
"""Create the zk session object."""
+ if not all([evzookeeper, membership, zookeeper]):
+ raise ImportError('zookeeper module not found')
null = open(os.devnull, "w")
- self._session = evzookeeper.ZKSession(CONF.zk.address,
+ self._session = evzookeeper.ZKSession(CONF.zookeeper.address,
recv_timeout=
- CONF.zk.recv_timeout,
+ CONF.zookeeper.recv_timeout,
zklog_fd=null)
self._memberships = {}
self._monitors = {}
# Make sure the prefix exists
try:
- self._session.create(CONF.zk.sg_prefix, "",
+ self._session.create(CONF.zookeeper.sg_prefix, "",
acl=[evzookeeper.ZOO_OPEN_ACL_UNSAFE])
except zookeeper.NodeExistsException:
pass
@@ -82,7 +83,7 @@ class ZooKeeperDriver(api.ServiceGroupDriver):
member = self._memberships.get((group, member_id), None)
if member is None:
# the first time to join. Generate a new object
- path = "%s/%s" % (CONF.zk.sg_prefix, group)
+ path = "%s/%s" % (CONF.zookeeper.sg_prefix, group)
try:
member = membership.Membership(self._session, path, member_id)
except RuntimeError:
@@ -90,7 +91,7 @@ class ZooKeeperDriver(api.ServiceGroupDriver):
"another node exists with the same name, or "
"this node just restarted. We will try "
"again in a short while to make sure."))
- eventlet.sleep(CONF.zk.sg_retry_interval)
+ eventlet.sleep(CONF.zookeeper.sg_retry_interval)
member = membership.Membership(self._session, path, member_id)
self._memberships[(group, member_id)] = member
return FakeLoopingCall(self, member_id, group)
@@ -120,7 +121,7 @@ class ZooKeeperDriver(api.ServiceGroupDriver):
"""
monitor = self._monitors.get(group_id, None)
if monitor is None:
- path = "%s/%s" % (CONF.zk.sg_prefix, group_id)
+ path = "%s/%s" % (CONF.zookeeper.sg_prefix, group_id)
monitor = membership.MembershipMonitor(self._session, path)
self._monitors[group_id] = monitor
# Note(maoy): When initialized for the first time, it takes a
diff --git a/nova/tests/api/__init__.py b/nova/tests/api/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/api/__init__.py
+++ b/nova/tests/api/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/ec2/__init__.py b/nova/tests/api/ec2/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/api/ec2/__init__.py
+++ b/nova/tests/api/ec2/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py
index 07780eb02..2ba8cfc60 100644
--- a/nova/tests/api/ec2/test_cloud.py
+++ b/nova/tests/api/ec2/test_cloud.py
@@ -41,9 +41,12 @@ from nova import db
from nova import exception
from nova.image import s3
from nova.network import api as network_api
+from nova.network import quantumv2
from nova.openstack.common import log as logging
from nova.openstack.common import rpc
from nova import test
+from nova.tests.api.openstack.compute.contrib import (
+ test_quantum_security_groups as test_quantum)
from nova.tests import fake_network
from nova.tests.image import fake
from nova.tests import matchers
@@ -1904,34 +1907,15 @@ class CloudTestCase(test.TestCase):
self.stubs.Set(fake._FakeImageService, 'show', fake_show)
def fake_block_device_mapping_get_all_by_instance(context, inst_id):
- class BDM(object):
- def __init__(self):
- self.no_device = None
- self.values = dict(id=1,
- snapshot_id=snapshots[0],
- volume_id=volumes[0],
- virtual_name=None,
- volume_size=1,
- device_name='sda1',
- delete_on_termination=False,
- connection_info='{"foo":"bar"}')
-
- def __getattr__(self, name):
- """Properly delegate dotted lookups."""
- if name in self.__dict__['values']:
- return self.values.get(name)
- try:
- return self.__dict__[name]
- except KeyError:
- raise AttributeError
-
- def __getitem__(self, key):
- return self.values.get(key)
-
- def iteritems(self):
- return self.values.iteritems()
-
- return [BDM()]
+ return [dict(id=1,
+ snapshot_id=snapshots[0],
+ volume_id=volumes[0],
+ virtual_name=None,
+ volume_size=1,
+ device_name='sda1',
+ delete_on_termination=False,
+ no_device=None,
+ connection_info='{"foo":"bar"}')]
self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
fake_block_device_mapping_get_all_by_instance)
@@ -1995,32 +1979,13 @@ class CloudTestCase(test.TestCase):
ec2_instance_id = self._run_instance(**kwargs)
def fake_block_device_mapping_get_all_by_instance(context, inst_id):
- class BDM(object):
- def __init__(self):
- self.no_device = None
- self.values = dict(snapshot_id=snapshots[0],
- volume_id=volumes[0],
- virtual_name=None,
- volume_size=1,
- device_name='vda',
- delete_on_termination=False)
-
- def __getattr__(self, name):
- """Properly delegate dotted lookups."""
- if name in self.__dict__['values']:
- return self.values.get(name)
- try:
- return self.__dict__[name]
- except KeyError:
- raise AttributeError
-
- def __getitem__(self, key):
- return self.values.get(key)
-
- def iteritems(self):
- return self.values.iteritems()
-
- return [BDM()]
+ return [dict(snapshot_id=snapshots[0],
+ volume_id=volumes[0],
+ virtual_name=None,
+ volume_size=1,
+ device_name='vda',
+ delete_on_termination=False,
+ no_device=None)]
self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
fake_block_device_mapping_get_all_by_instance)
@@ -2226,3 +2191,66 @@ class CloudTestCase(test.TestCase):
test_dia_iisb('stop', image_id='ami-4')
test_dia_iisb('stop', image_id='ami-5')
test_dia_iisb('stop', image_id='ami-6')
+
+
+class CloudTestCaseQuantumProxy(test.TestCase):
+ def setUp(self):
+ cfg.CONF.set_override('security_group_api', 'quantum')
+ self.cloud = cloud.CloudController()
+ self.original_client = quantumv2.get_client
+ quantumv2.get_client = test_quantum.get_client
+ self.user_id = 'fake'
+ self.project_id = 'fake'
+ self.context = context.RequestContext(self.user_id,
+ self.project_id,
+ is_admin=True)
+ super(CloudTestCaseQuantumProxy, self).setUp()
+
+ def tearDown(self):
+ quantumv2.get_client = self.original_client
+ test_quantum.get_client()._reset()
+ super(CloudTestCaseQuantumProxy, self).tearDown()
+
+ def test_describe_security_groups(self):
+ # Makes sure describe_security_groups works and filters results.
+ group_name = 'test'
+ description = 'test'
+ self.cloud.create_security_group(self.context, group_name,
+ description)
+ result = self.cloud.describe_security_groups(self.context)
+ # NOTE(vish): should have the default group as well
+ self.assertEqual(len(result['securityGroupInfo']), 2)
+ result = self.cloud.describe_security_groups(self.context,
+ group_name=[group_name])
+ self.assertEqual(len(result['securityGroupInfo']), 1)
+ self.assertEqual(result['securityGroupInfo'][0]['groupName'],
+ group_name)
+ self.cloud.delete_security_group(self.context, group_name)
+
+ def test_describe_security_groups_by_id(self):
+ group_name = 'test'
+ description = 'test'
+ self.cloud.create_security_group(self.context, group_name,
+ description)
+ quantum = test_quantum.get_client()
+ # Get id from quantum since cloud.create_security_group
+ # does not expose it.
+ search_opts = {'name': group_name}
+ groups = quantum.list_security_groups(
+ **search_opts)['security_groups']
+ result = self.cloud.describe_security_groups(self.context,
+ group_id=[groups[0]['id']])
+ self.assertEqual(len(result['securityGroupInfo']), 1)
+ self.assertEqual(
+ result['securityGroupInfo'][0]['groupName'],
+ group_name)
+ self.cloud.delete_security_group(self.context, group_name)
+
+ def test_create_delete_security_group(self):
+ descript = 'test description'
+ create = self.cloud.create_security_group
+ result = create(self.context, 'testgrp', descript)
+ group_descript = result['securityGroupSet'][0]['groupDescription']
+ self.assertEqual(descript, group_descript)
+ delete = self.cloud.delete_security_group
+ self.assertTrue(delete(self.context, 'testgrp'))
diff --git a/nova/tests/api/openstack/__init__.py b/nova/tests/api/openstack/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/api/openstack/__init__.py
+++ b/nova/tests/api/openstack/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/common.py b/nova/tests/api/openstack/common.py
index 1e4adf574..468bc5626 100644
--- a/nova/tests/api/openstack/common.py
+++ b/nova/tests/api/openstack/common.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/__init__.py b/nova/tests/api/openstack/compute/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/api/openstack/compute/__init__.py
+++ b/nova/tests/api/openstack/compute/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/__init__.py b/nova/tests/api/openstack/compute/contrib/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/api/openstack/compute/contrib/__init__.py
+++ b/nova/tests/api/openstack/compute/contrib/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_admin_actions.py b/nova/tests/api/openstack/compute/contrib/test_admin_actions.py
index 600d25889..bb3cbf086 100644
--- a/nova/tests/api/openstack/compute/contrib/test_admin_actions.py
+++ b/nova/tests/api/openstack/compute/contrib/test_admin_actions.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/api/openstack/compute/contrib/test_admin_actions_with_cells.py b/nova/tests/api/openstack/compute/contrib/test_admin_actions_with_cells.py
index 4e577e1f5..1e88d8047 100644
--- a/nova/tests/api/openstack/compute/contrib/test_admin_actions_with_cells.py
+++ b/nova/tests/api/openstack/compute/contrib/test_admin_actions_with_cells.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 Openstack, LLC.
+# Copyright (c) 2012 Openstack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_agents.py b/nova/tests/api/openstack/compute/contrib/test_agents.py
index 60659b3c6..0250b9ac5 100644
--- a/nova/tests/api/openstack/compute/contrib/test_agents.py
+++ b/nova/tests/api/openstack/compute/contrib/test_agents.py
@@ -1,5 +1,4 @@
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
@@ -99,9 +98,6 @@ class AgentsTest(test.TestCase):
self.context = context.get_admin_context()
self.controller = agents.AgentController()
- def tearDown(self):
- super(AgentsTest, self).tearDown()
-
def test_agents_create(self):
req = FakeRequest()
body = {'agent': {'hypervisor': 'kvm',
diff --git a/nova/tests/api/openstack/compute/contrib/test_availability_zone.py b/nova/tests/api/openstack/compute/contrib/test_availability_zone.py
index fb9a36ba9..cd4c616d7 100644
--- a/nova/tests/api/openstack/compute/contrib/test_availability_zone.py
+++ b/nova/tests/api/openstack/compute/contrib/test_availability_zone.py
@@ -1,5 +1,4 @@
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
diff --git a/nova/tests/api/openstack/compute/contrib/test_cells.py b/nova/tests/api/openstack/compute/contrib/test_cells.py
index 82d469524..89ce4cd5a 100644
--- a/nova/tests/api/openstack/compute/contrib/test_cells.py
+++ b/nova/tests/api/openstack/compute/contrib/test_cells.py
@@ -1,4 +1,4 @@
-# Copyright 2011-2012 OpenStack LLC.
+# Copyright 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_certificates.py b/nova/tests/api/openstack/compute/contrib/test_certificates.py
index 9c9625e8e..df5a7e9a1 100644
--- a/nova/tests/api/openstack/compute/contrib/test_certificates.py
+++ b/nova/tests/api/openstack/compute/contrib/test_certificates.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_cloudpipe.py b/nova/tests/api/openstack/compute/contrib/test_cloudpipe.py
index 40b4e6d93..83dca7a95 100644
--- a/nova/tests/api/openstack/compute/contrib/test_cloudpipe.py
+++ b/nova/tests/api/openstack/compute/contrib/test_cloudpipe.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_cloudpipe_update.py b/nova/tests/api/openstack/compute/contrib/test_cloudpipe_update.py
index 8068776de..d0f54edcb 100644
--- a/nova/tests/api/openstack/compute/contrib/test_cloudpipe_update.py
+++ b/nova/tests/api/openstack/compute/contrib/test_cloudpipe_update.py
@@ -1,5 +1,4 @@
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
diff --git a/nova/tests/api/openstack/compute/contrib/test_config_drive.py b/nova/tests/api/openstack/compute/contrib/test_config_drive.py
index e9d23f664..235b9373b 100644
--- a/nova/tests/api/openstack/compute/contrib/test_config_drive.py
+++ b/nova/tests/api/openstack/compute/contrib/test_config_drive.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_consoles.py b/nova/tests/api/openstack/compute/contrib/test_consoles.py
index cf044dfcd..505f0c1fe 100644
--- a/nova/tests/api/openstack/compute/contrib/test_consoles.py
+++ b/nova/tests/api/openstack/compute/contrib/test_consoles.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_coverage_ext.py b/nova/tests/api/openstack/compute/contrib/test_coverage_ext.py
index 66a8a8f82..6d66f8d74 100644
--- a/nova/tests/api/openstack/compute/contrib/test_coverage_ext.py
+++ b/nova/tests/api/openstack/compute/contrib/test_coverage_ext.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
@@ -34,12 +34,27 @@ def fake_check_coverage(self):
return False
-def fake_xml_report(self, outfile):
- return
+class FakeCoverage(object):
+ def __init__(self, data_file=None):
+ self.started = False
+ return super(FakeCoverage, self).__init__()
+ def save(self):
+ pass
-def fake_report(self, file):
- return
+ def start(self):
+ self.started = True
+
+ def stop(self):
+ if not self.started:
+ raise AssertionError
+ self.started = False
+
+ def report(self, file):
+ pass
+
+ def xml_report(self, outfile):
+ pass
class CoverageExtensionTest(test.TestCase):
@@ -48,8 +63,7 @@ class CoverageExtensionTest(test.TestCase):
super(CoverageExtensionTest, self).setUp()
self.stubs.Set(telnetlib.Telnet, 'write', fake_telnet)
self.stubs.Set(telnetlib.Telnet, 'expect', fake_telnet)
- self.stubs.Set(coverage.coverage, 'report', fake_report)
- self.stubs.Set(coverage.coverage, 'xml_report', fake_xml_report)
+ self.stubs.Set(coverage, 'coverage', FakeCoverage)
self.admin_context = context.RequestContext('fakeadmin_0',
'fake',
is_admin=True)
diff --git a/nova/tests/api/openstack/compute/contrib/test_createserverext.py b/nova/tests/api/openstack/compute/contrib/test_createserverext.py
index 9ec866172..7ee05516f 100644
--- a/nova/tests/api/openstack/compute/contrib/test_createserverext.py
+++ b/nova/tests/api/openstack/compute/contrib/test_createserverext.py
@@ -1,6 +1,6 @@
# vim: tabstop=5 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_deferred_delete.py b/nova/tests/api/openstack/compute/contrib/test_deferred_delete.py
index eba4154e2..4fd44bcd7 100644
--- a/nova/tests/api/openstack/compute/contrib/test_deferred_delete.py
+++ b/nova/tests/api/openstack/compute/contrib/test_deferred_delete.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_disk_config.py b/nova/tests/api/openstack/compute/contrib/test_disk_config.py
index 9434ba821..278be0580 100644
--- a/nova/tests/api/openstack/compute/contrib/test_disk_config.py
+++ b/nova/tests/api/openstack/compute/contrib/test_disk_config.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_evacuate.py b/nova/tests/api/openstack/compute/contrib/test_evacuate.py
index 9411b5663..fad89db02 100644
--- a/nova/tests/api/openstack/compute/contrib/test_evacuate.py
+++ b/nova/tests/api/openstack/compute/contrib/test_evacuate.py
@@ -1,4 +1,4 @@
-# Copyright 2013 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation
#
# 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/tests/api/openstack/compute/contrib/test_extended_availability_zone.py b/nova/tests/api/openstack/compute/contrib/test_extended_availability_zone.py
index d847e54f9..814c0fff4 100644
--- a/nova/tests/api/openstack/compute/contrib/test_extended_availability_zone.py
+++ b/nova/tests/api/openstack/compute/contrib/test_extended_availability_zone.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py b/nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py
index 63e1b6126..ff5ab7ac5 100644
--- a/nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py
+++ b/nova/tests/api/openstack/compute/contrib/test_extended_server_attributes.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_extended_status.py b/nova/tests/api/openstack/compute/contrib/test_extended_status.py
index e368c5986..f219b97bd 100644
--- a/nova/tests/api/openstack/compute/contrib/test_extended_status.py
+++ b/nova/tests/api/openstack/compute/contrib/test_extended_status.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_fixed_ips.py b/nova/tests/api/openstack/compute/contrib/test_fixed_ips.py
index 6b6fb8286..818bc3dff 100644
--- a/nova/tests/api/openstack/compute/contrib/test_fixed_ips.py
+++ b/nova/tests/api/openstack/compute/contrib/test_fixed_ips.py
@@ -1,5 +1,4 @@
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
@@ -107,9 +106,6 @@ class FixedIpTest(test.TestCase):
self.context = context.get_admin_context()
self.controller = fixed_ips.FixedIPController()
- def tearDown(self):
- super(FixedIpTest, self).tearDown()
-
def test_fixed_ips_get(self):
req = fakes.HTTPRequest.blank('/v2/fake/os-fixed-ips/192.168.1.1')
res_dict = self.controller.show(req, '192.168.1.1')
diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_access.py b/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
index 1475edc0a..fc5543409 100644
--- a/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
+++ b/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py b/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py
index 9b815489e..1c5703381 100644
--- a/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py
+++ b/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_floating_ip_bulk.py b/nova/tests/api/openstack/compute/contrib/test_floating_ip_bulk.py
index a36bb32cf..5521eddb1 100644
--- a/nova/tests/api/openstack/compute/contrib/test_floating_ip_bulk.py
+++ b/nova/tests/api/openstack/compute/contrib/test_floating_ip_bulk.py
@@ -1,5 +1,4 @@
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
@@ -33,9 +32,6 @@ class FloatingIPBulk(test.TestCase):
self.context = context.get_admin_context()
self.controller = floating_ips_bulk.FloatingIPBulkController()
- def tearDown(self):
- super(FloatingIPBulk, self).tearDown()
-
def _setup_floating_ips(self, ip_range):
body = {'floating_ips_bulk_create': {'ip_range': ip_range}}
req = fakes.HTTPRequest.blank('/v2/fake/os-floating-ips-bulk')
diff --git a/nova/tests/api/openstack/compute/contrib/test_floating_ips.py b/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
index 864ab7a9f..00759a7ef 100644
--- a/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
+++ b/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
@@ -364,8 +364,9 @@ class FloatingIpTest(test.TestCase):
body = dict(removeFloatingIp=dict(address='10.10.10.10'))
req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
- rsp = self.manager._remove_floating_ip(req, 'test_inst', body)
- self.assertTrue(rsp.status_int == 404)
+ self.assertRaises(webob.exc.HTTPUnprocessableEntity,
+ self.manager._remove_floating_ip,
+ req, 'test_inst', body)
def test_floating_ip_associate_non_existent_ip(self):
def fake_network_api_associate(self, context, instance,
@@ -414,8 +415,9 @@ class FloatingIpTest(test.TestCase):
body = dict(removeFloatingIp=dict(address='10.10.10.10'))
req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
- rsp = self.manager._remove_floating_ip(req, wrong_uuid, body)
- self.assertTrue(rsp.status_int == 404)
+ self.assertRaises(webob.exc.HTTPUnprocessableEntity,
+ self.manager._remove_floating_ip,
+ req, wrong_uuid, body)
def test_floating_ip_disassociate_wrong_instance_id(self):
def get_instance_by_floating_ip_addr(self, context, address):
@@ -428,8 +430,9 @@ class FloatingIpTest(test.TestCase):
body = dict(removeFloatingIp=dict(address='10.10.10.10'))
req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
- rsp = self.manager._remove_floating_ip(req, 'test_inst', body)
- self.assertTrue(rsp.status_int == 404)
+ self.assertRaises(webob.exc.HTTPUnprocessableEntity,
+ self.manager._remove_floating_ip,
+ req, 'test_inst', body)
def test_floating_ip_disassociate_auto_assigned(self):
def fake_get_floating_ip_addr_auto_assigned(self, context, address):
diff --git a/nova/tests/api/openstack/compute/contrib/test_fping.py b/nova/tests/api/openstack/compute/contrib/test_fping.py
index 1a1e3214e..cdeb0a280 100644
--- a/nova/tests/api/openstack/compute/contrib/test_fping.py
+++ b/nova/tests/api/openstack/compute/contrib/test_fping.py
@@ -1,5 +1,5 @@
# Copyright 2011 Grid Dynamics
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_hide_server_addresses.py b/nova/tests/api/openstack/compute/contrib/test_hide_server_addresses.py
index 804decdff..f77869947 100644
--- a/nova/tests/api/openstack/compute/contrib/test_hide_server_addresses.py
+++ b/nova/tests/api/openstack/compute/contrib/test_hide_server_addresses.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_hosts.py b/nova/tests/api/openstack/compute/contrib/test_hosts.py
index e103b5b19..85f93a9d5 100644
--- a/nova/tests/api/openstack/compute/contrib/test_hosts.py
+++ b/nova/tests/api/openstack/compute/contrib/test_hosts.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC.
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_hypervisors.py b/nova/tests/api/openstack/compute/contrib/test_hypervisors.py
index f93c64487..e323dce6a 100644
--- a/nova/tests/api/openstack/compute/contrib/test_hypervisors.py
+++ b/nova/tests/api/openstack/compute/contrib/test_hypervisors.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_instance_usage_audit_log.py b/nova/tests/api/openstack/compute/contrib/test_instance_usage_audit_log.py
index 920fd86d5..2b2fd1131 100644
--- a/nova/tests/api/openstack/compute/contrib/test_instance_usage_audit_log.py
+++ b/nova/tests/api/openstack/compute/contrib/test_instance_usage_audit_log.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_keypairs.py b/nova/tests/api/openstack/compute/contrib/test_keypairs.py
index 06454b123..025845637 100644
--- a/nova/tests/api/openstack/compute/contrib/test_keypairs.py
+++ b/nova/tests/api/openstack/compute/contrib/test_keypairs.py
@@ -236,6 +236,11 @@ class KeypairsTest(test.TestCase):
res = req.get_response(self.app)
self.assertEqual(res.status_int, 202)
+ def test_keypair_get_keypair_not_found(self):
+ req = webob.Request.blank('/v2/fake/os-keypairs/DOESNOTEXIST')
+ res = req.get_response(self.app)
+ self.assertEqual(res.status_int, 404)
+
def test_keypair_delete_not_found(self):
def db_key_pair_get_not_found(context, user_id, name):
diff --git a/nova/tests/api/openstack/compute/contrib/test_multinic_xs.py b/nova/tests/api/openstack/compute/contrib/test_multinic_xs.py
index bf9eebc6b..dc3c21d99 100644
--- a/nova/tests/api/openstack/compute/contrib/test_multinic_xs.py
+++ b/nova/tests/api/openstack/compute/contrib/test_multinic_xs.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_networks.py b/nova/tests/api/openstack/compute/contrib/test_networks.py
index fef60f20b..8238f9248 100644
--- a/nova/tests/api/openstack/compute/contrib/test_networks.py
+++ b/nova/tests/api/openstack/compute/contrib/test_networks.py
@@ -1,5 +1,5 @@
# Copyright 2011 Grid Dynamics
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
index e32fadbb8..a413babdf 100644
--- a/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
+++ b/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
@@ -237,6 +237,7 @@ class TestQuantumSecurityGroupRulesTestCase(TestQuantumSecurityGroupsTestCase):
id2 = '22222222-2222-2222-2222-222222222222'
sg_template2 = test_security_groups.security_group_template(
security_group_rules=[], id=id2)
+ self.controller_sg = security_groups.SecurityGroupController()
quantum = get_client()
quantum._fake_security_groups[id1] = sg_template1
quantum._fake_security_groups[id2] = sg_template2
@@ -252,12 +253,26 @@ class TestQuantumSecurityGroupRules(
TestQuantumSecurityGroupRulesTestCase):
def test_create_add_existing_rules_by_cidr(self):
- # Enforced by quantum
- pass
+ sg = test_security_groups.security_group_template()
+ req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups')
+ self.controller_sg.create(req, {'security_group': sg})
+ rule = test_security_groups.security_group_rule_template(
+ cidr='15.0.0.0/8', parent_group_id=self.sg2['id'])
+ req = fakes.HTTPRequest.blank('/v2/fake/os-security-group-rules')
+ self.controller.create(req, {'security_group_rule': rule})
+ self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
+ req, {'security_group_rule': rule})
def test_create_add_existing_rules_by_group_id(self):
- # Enforced by quantum
- pass
+ sg = test_security_groups.security_group_template()
+ req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups')
+ self.controller_sg.create(req, {'security_group': sg})
+ rule = test_security_groups.security_group_rule_template(
+ group=self.sg1['id'], parent_group_id=self.sg2['id'])
+ req = fakes.HTTPRequest.blank('/v2/fake/os-security-group-rules')
+ self.controller.create(req, {'security_group_rule': rule})
+ self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
+ req, {'security_group_rule': rule})
def test_delete(self):
rule = test_security_groups.security_group_rule_template(
@@ -517,8 +532,8 @@ class MockClient(object):
# does not handle bulk case so just picks rule[0]
r = body.get('security_group_rules')[0]
fields = ['direction', 'protocol', 'port_range_min', 'port_range_max',
- 'ethertype', 'source_ip_prefix', 'tenant_id',
- 'security_group_id', 'source_group_id']
+ 'ethertype', 'remote_ip_prefix', 'tenant_id',
+ 'security_group_id', 'remote_group_id']
ret = {}
for field in fields:
ret[field] = r.get(field)
@@ -528,11 +543,15 @@ class MockClient(object):
def show_security_group(self, security_group, **_params):
try:
- return {'security_group':
- self._fake_security_groups[security_group]}
+ sg = self._fake_security_groups[security_group]
except KeyError:
msg = 'Security Group %s not found' % security_group
raise q_exc.QuantumClientException(message=msg, status_code=404)
+ for security_group_rule in self._fake_security_group_rules.values():
+ if security_group_rule['security_group_id'] == sg['id']:
+ sg['security_group_rules'].append(security_group_rule)
+
+ return {'security_group': sg}
def show_security_group_rule(self, security_group_rule, **_params):
try:
@@ -569,10 +588,21 @@ class MockClient(object):
def list_security_groups(self, **_params):
ret = []
for security_group in self._fake_security_groups.values():
- if _params.get('name'):
- if security_group.get('name') == _params['name']:
- ret.append(security_group)
- else:
+ names = _params.get('name')
+ if names:
+ if not isinstance(names, list):
+ names = [names]
+ for name in names:
+ if security_group.get('name') == name:
+ ret.append(security_group)
+ ids = _params.get('id')
+ if ids:
+ if not isinstance(ids, list):
+ ids = [ids]
+ for id in ids:
+ if security_group.get('id') == id:
+ ret.append(security_group)
+ elif not (names or ids):
ret.append(security_group)
return {'security_groups': ret}
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 0c1378a67..7b0b62180 100644
--- a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py
+++ b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py
index 6636824fd..0616c4628 100644
--- a/nova/tests/api/openstack/compute/contrib/test_quotas.py
+++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_rescue.py b/nova/tests/api/openstack/compute/contrib/test_rescue.py
index 359eafb2a..0d2e9e5c8 100644
--- a/nova/tests/api/openstack/compute/contrib/test_rescue.py
+++ b/nova/tests/api/openstack/compute/contrib/test_rescue.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/api/openstack/compute/contrib/test_scheduler_hints.py b/nova/tests/api/openstack/compute/contrib/test_scheduler_hints.py
index 732abaad5..9b91ef2c5 100644
--- a/nova/tests/api/openstack/compute/contrib/test_scheduler_hints.py
+++ b/nova/tests/api/openstack/compute/contrib/test_scheduler_hints.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
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 5058f17ac..4919d461f 100644
--- a/nova/tests/api/openstack/compute/contrib/test_security_groups.py
+++ b/nova/tests/api/openstack/compute/contrib/test_security_groups.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
# Copyright 2012 Justin Santa Barbara
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_services.py b/nova/tests/api/openstack/compute/contrib/test_services.py
index aba1b92c1..d4bf62d19 100644
--- a/nova/tests/api/openstack/compute/contrib/test_services.py
+++ b/nova/tests/api/openstack/compute/contrib/test_services.py
@@ -1,5 +1,4 @@
-# Copyright 2012 IBM
-# All Rights Reserved.
+# Copyright 2012 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
@@ -122,9 +121,6 @@ class ServicesTest(test.TestCase):
self.context = context.get_admin_context()
self.controller = services.ServiceController()
- def tearDown(self):
- super(ServicesTest, self).tearDown()
-
def test_services_list(self):
req = FakeRequest()
res_dict = self.controller.index(req)
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 ef4aacae8..4c59e5aa9 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
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/contrib/test_used_limits.py b/nova/tests/api/openstack/compute/contrib/test_used_limits.py
index ce2322bfe..ebe3e852d 100644
--- a/nova/tests/api/openstack/compute/contrib/test_used_limits.py
+++ b/nova/tests/api/openstack/compute/contrib/test_used_limits.py
@@ -1,6 +1,6 @@
# vim: tabstop=5 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/extensions/__init__.py b/nova/tests/api/openstack/compute/extensions/__init__.py
index 848908a95..4ac574e58 100644
--- a/nova/tests/api/openstack/compute/extensions/__init__.py
+++ b/nova/tests/api/openstack/compute/extensions/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/api/openstack/compute/extensions/foxinsocks.py b/nova/tests/api/openstack/compute/extensions/foxinsocks.py
index fdc612047..3b232f327 100644
--- a/nova/tests/api/openstack/compute/extensions/foxinsocks.py
+++ b/nova/tests/api/openstack/compute/extensions/foxinsocks.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_api.py b/nova/tests/api/openstack/compute/test_api.py
index 782f1a344..9061fd397 100644
--- a/nova/tests/api/openstack/compute/test_api.py
+++ b/nova/tests/api/openstack/compute/test_api.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_auth.py b/nova/tests/api/openstack/compute/test_auth.py
index 21ef2a162..0aca45573 100644
--- a/nova/tests/api/openstack/compute/test_auth.py
+++ b/nova/tests/api/openstack/compute/test_auth.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_consoles.py b/nova/tests/api/openstack/compute/test_consoles.py
index 8f0a02e30..134fb0639 100644
--- a/nova/tests/api/openstack/compute/test_consoles.py
+++ b/nova/tests/api/openstack/compute/test_consoles.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# Copyright 2011 Piston Cloud Computing, Inc.
# All Rights Reserved.
#
diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py
index 68e5e1b99..dcc2c9b3d 100644
--- a/nova/tests/api/openstack/compute/test_extensions.py
+++ b/nova/tests/api/openstack/compute/test_extensions.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_flavors.py b/nova/tests/api/openstack/compute/test_flavors.py
index 947a2e294..3a11c92fe 100644
--- a/nova/tests/api/openstack/compute/test_flavors.py
+++ b/nova/tests/api/openstack/compute/test_flavors.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_image_metadata.py b/nova/tests/api/openstack/compute/test_image_metadata.py
index 29165b548..1330bc202 100644
--- a/nova/tests/api/openstack/compute/test_image_metadata.py
+++ b/nova/tests/api/openstack/compute/test_image_metadata.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_images.py b/nova/tests/api/openstack/compute/test_images.py
index 09e727da3..db0ad51f7 100644
--- a/nova/tests/api/openstack/compute/test_images.py
+++ b/nova/tests/api/openstack/compute/test_images.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_limits.py b/nova/tests/api/openstack/compute/test_limits.py
index e3fff380d..70c37e745 100644
--- a/nova/tests/api/openstack/compute/test_limits.py
+++ b/nova/tests/api/openstack/compute/test_limits.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_server_actions.py b/nova/tests/api/openstack/compute/test_server_actions.py
index 101458bf3..62a688962 100644
--- a/nova/tests/api/openstack/compute/test_server_actions.py
+++ b/nova/tests/api/openstack/compute/test_server_actions.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -784,32 +784,13 @@ class ServerActionsControllerTest(test.TestCase):
image_service.create(None, original_image)
def fake_block_device_mapping_get_all_by_instance(context, inst_id):
- class BDM(object):
- def __init__(self):
- self.no_device = None
- self.values = dict(volume_id=_fake_id('a'),
- virtual_name=None,
- volume_size=1,
- device_name='vda',
- snapshot_id=1,
- delete_on_termination=False)
-
- def __getattr__(self, name):
- """Properly delegate dotted lookups."""
- if name in self.__dict__['values']:
- return self.values.get(name)
- try:
- return self.__dict__[name]
- except KeyError:
- raise AttributeError
-
- def __getitem__(self, key):
- return self.values.get(key)
-
- def iteritems(self):
- return self.values.iteritems()
-
- return [BDM()]
+ return [dict(volume_id=_fake_id('a'),
+ virtual_name=None,
+ volume_size=1,
+ device_name='vda',
+ snapshot_id=1,
+ delete_on_termination=False,
+ no_device=None)]
self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
fake_block_device_mapping_get_all_by_instance)
diff --git a/nova/tests/api/openstack/compute/test_server_metadata.py b/nova/tests/api/openstack/compute/test_server_metadata.py
index 3ba895953..fa25ad4a3 100644
--- a/nova/tests/api/openstack/compute/test_server_metadata.py
+++ b/nova/tests/api/openstack/compute/test_server_metadata.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py
index 228d81f45..638ef79b0 100644
--- a/nova/tests/api/openstack/compute/test_servers.py
+++ b/nova/tests/api/openstack/compute/test_servers.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# Copyright 2011 Piston Cloud Computing, Inc.
# All Rights Reserved.
#
@@ -71,19 +71,10 @@ def fake_gen_uuid():
return FAKE_UUID
-def return_servers_by_reservation(context, reservation_id=""):
- return [fakes.stub_instance(i + 1,
- reservation_id=reservation_id) for i in xrange(5)]
-
-
def return_servers_empty(context, *args, **kwargs):
return []
-def return_servers_by_reservation_empty(context, reservation_id=""):
- return []
-
-
def return_security_group(context, instance_id, security_group_id):
pass
@@ -539,9 +530,6 @@ class ServersControllerTest(test.TestCase):
self.assertEqual(0, num_servers)
def test_get_server_list_with_reservation_id(self):
- self.stubs.Set(db, 'instance_get_all_by_reservation',
- return_servers_by_reservation)
-
req = fakes.HTTPRequest.blank('/v2/fake/servers?reservation_id=foo')
res_dict = self.controller.index(req)
@@ -551,9 +539,6 @@ class ServersControllerTest(test.TestCase):
i += 1
def test_get_server_list_with_reservation_id_empty(self):
- self.stubs.Set(db, 'instance_get_all_by_reservation',
- return_servers_by_reservation_empty)
-
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?'
'reservation_id=foo')
res_dict = self.controller.detail(req)
@@ -564,9 +549,6 @@ class ServersControllerTest(test.TestCase):
i += 1
def test_get_server_list_with_reservation_id_details(self):
- self.stubs.Set(db, 'instance_get_all_by_reservation',
- return_servers_by_reservation)
-
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?'
'reservation_id=foo')
res_dict = self.controller.detail(req)
@@ -2060,6 +2042,52 @@ class ServersControllerCreateTest(test.TestCase):
self.assertRaises(webob.exc.HTTPBadRequest,
self._test_create_extra, params, no_image=True)
+ def test_create_multiple_instance_with_non_integer_max_count(self):
+ self.ext_mgr.extensions = {'os-multiple-create': 'fake'}
+ image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
+ flavor_ref = 'http://localhost/123/flavors/3'
+ body = {
+ 'server': {
+ 'max_count': 2.5,
+ 'name': 'server_test',
+ 'imageRef': image_href,
+ 'flavorRef': flavor_ref,
+ 'metadata': {'hello': 'world',
+ 'open': 'stack'},
+ 'personality': []
+ }
+ }
+
+ req = fakes.HTTPRequest.blank('/v2/fake/servers')
+ req.method = 'POST'
+ req.body = jsonutils.dumps(body)
+ req.headers["content-type"] = "application/json"
+ self.assertRaises(webob.exc.HTTPBadRequest,
+ self.controller.create, req, body)
+
+ def test_create_multiple_instance_with_non_integer_min_count(self):
+ self.ext_mgr.extensions = {'os-multiple-create': 'fake'}
+ image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
+ flavor_ref = 'http://localhost/123/flavors/3'
+ body = {
+ 'server': {
+ 'min_count': 2.5,
+ 'name': 'server_test',
+ 'imageRef': image_href,
+ 'flavorRef': flavor_ref,
+ 'metadata': {'hello': 'world',
+ 'open': 'stack'},
+ 'personality': []
+ }
+ }
+
+ req = fakes.HTTPRequest.blank('/v2/fake/servers')
+ req.method = 'POST'
+ req.body = jsonutils.dumps(body)
+ req.headers["content-type"] = "application/json"
+ self.assertRaises(webob.exc.HTTPBadRequest,
+ self.controller.create, req, body)
+
def test_create_instance_image_ref_is_bookmark(self):
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
image_href = 'http://localhost/fake/images/%s' % image_uuid
@@ -2120,15 +2148,27 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance_with_security_group_enabled(self):
self.ext_mgr.extensions = {'os-security-groups': 'fake'}
group = 'foo'
- params = {'security_groups': [{'name': group}]}
old_create = compute_api.API.create
+ def sec_group_get(ctx, proj, name):
+ if name == group:
+ return True
+ else:
+ raise exception.SecurityGroupNotFoundForProject(
+ project_id=proj, security_group_id=name)
+
def create(*args, **kwargs):
self.assertEqual(kwargs['security_group'], [group])
return old_create(*args, **kwargs)
+ self.stubs.Set(db, 'security_group_get_by_name', sec_group_get)
+ # negative test
+ self.assertRaises(webob.exc.HTTPBadRequest,
+ self._test_create_extra,
+ {'security_groups': [{'name': 'bogus'}]})
+ # positive test - extra assert in create path
self.stubs.Set(compute_api.API, 'create', create)
- self._test_create_extra(params)
+ self._test_create_extra({'security_groups': [{'name': group}]})
def test_create_instance_with_security_group_disabled(self):
group = 'foo'
diff --git a/nova/tests/api/openstack/compute/test_urlmap.py b/nova/tests/api/openstack/compute/test_urlmap.py
index 6367a8e5e..8cb98944c 100644
--- a/nova/tests/api/openstack/compute/test_urlmap.py
+++ b/nova/tests/api/openstack/compute/test_urlmap.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/compute/test_versions.py b/nova/tests/api/openstack/compute/test_versions.py
index bd2e9fa7b..973fd0105 100644
--- a/nova/tests/api/openstack/compute/test_versions.py
+++ b/nova/tests/api/openstack/compute/test_versions.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py
index c906dae7f..1bc7b313e 100644
--- a/nova/tests/api/openstack/fakes.py
+++ b/nova/tests/api/openstack/fakes.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -587,7 +587,7 @@ def stub_snapshot(id, **kwargs):
'volume_id': 12,
'status': 'available',
'volume_size': 100,
- 'created_at': None,
+ 'created_at': timeutils.utcnow(),
'display_name': 'Default name',
'display_description': 'Default description',
'project_id': 'fake'
diff --git a/nova/tests/api/openstack/test_common.py b/nova/tests/api/openstack/test_common.py
index 68a5f0bf4..227044572 100644
--- a/nova/tests/api/openstack/test_common.py
+++ b/nova/tests/api/openstack/test_common.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/test_faults.py b/nova/tests/api/openstack/test_faults.py
index a413f9c4d..1bdb9f8c6 100644
--- a/nova/tests/api/openstack/test_faults.py
+++ b/nova/tests/api/openstack/test_faults.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/openstack/test_xmlutil.py b/nova/tests/api/openstack/test_xmlutil.py
index 83382cb58..bd7f24233 100644
--- a/nova/tests/api/openstack/test_xmlutil.py
+++ b/nova/tests/api/openstack/test_xmlutil.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/api/test_auth.py b/nova/tests/api/test_auth.py
index 083e6c0e9..ed69474c8 100644
--- a/nova/tests/api/test_auth.py
+++ b/nova/tests/api/test_auth.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
#
# 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/tests/api/test_sizelimit.py b/nova/tests/api/test_sizelimit.py
index 9e7a33d29..f5735f287 100644
--- a/nova/tests/api/test_sizelimit.py
+++ b/nova/tests/api/test_sizelimit.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
#
# 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/tests/api/test_validator.py b/nova/tests/api/test_validator.py
index 132e67e95..93a7deb66 100644
--- a/nova/tests/api/test_validator.py
+++ b/nova/tests/api/test_validator.py
@@ -73,14 +73,6 @@ class ValidatorTestCase(test.TestCase):
self.assertFalse(validator.validate_ec2_id(1234))
self.assertTrue(validator.validate_ec2_id('i-284f3a41'))
- def test_validate_ipv4(self):
- self.assertTrue(validator.validate_ipv4('4.2.2.4'))
- self.assertFalse(validator.validate_ipv4('foobar'))
- self.assertFalse(
- validator.validate_ipv4('2001:5a8:4:68e0:e6ce:8fff:fe27:d116'))
- self.assertFalse(validator.validate_ipv4(123))
- self.assertFalse(validator.validate_ipv4(''))
-
def test_validate_url_path(self):
self.assertTrue(validator.validate_url_path('/path/to/file'))
self.assertFalse(validator.validate_url_path('path/to/file'))
diff --git a/nova/tests/api/test_wsgi.py b/nova/tests/api/test_wsgi.py
index 6504e664d..210bf6cf6 100644
--- a/nova/tests/api/test_wsgi.py
+++ b/nova/tests/api/test_wsgi.py
@@ -2,7 +2,7 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/baremetal/db/test_bm_interface.py b/nova/tests/baremetal/db/test_bm_interface.py
index 32beb1ce0..e870ec5e0 100644
--- a/nova/tests/baremetal/db/test_bm_interface.py
+++ b/nova/tests/baremetal/db/test_bm_interface.py
@@ -18,7 +18,7 @@ Bare-metal DB testcase for BareMetalInterface
"""
from nova import exception
-from nova.openstack.common.db.sqlalchemy import session as db_session
+from nova.openstack.common.db import exception as db_exc
from nova.tests.baremetal.db import base
from nova.virt.baremetal import db
@@ -28,7 +28,7 @@ class BareMetalInterfaceTestCase(base.BMDBTestCase):
def test_unique_address(self):
pif1_id = db.bm_interface_create(self.context, 1, '11:11:11:11:11:11',
'0x1', 1)
- self.assertRaises(db_session.DBError,
+ self.assertRaises(db_exc.DBError,
db.bm_interface_create,
self.context, 2, '11:11:11:11:11:11', '0x2', 2)
# succeed after delete pif1
diff --git a/nova/tests/baremetal/db/test_bm_pxe_ip.py b/nova/tests/baremetal/db/test_bm_pxe_ip.py
index 9820f3af0..fe8ba5b3e 100644
--- a/nova/tests/baremetal/db/test_bm_pxe_ip.py
+++ b/nova/tests/baremetal/db/test_bm_pxe_ip.py
@@ -18,7 +18,7 @@ Bare-metal DB testcase for BareMetalPxeIp
"""
from nova import exception
-from nova.openstack.common.db.sqlalchemy import session as db_session
+from nova.openstack.common.db import exception as db_exc
from nova.tests.baremetal.db import base
from nova.tests.baremetal.db import utils
from nova.virt.baremetal import db
@@ -51,14 +51,14 @@ class BareMetalPxeIpTestCase(base.BMDBTestCase):
# address duplicates
i = utils.new_bm_pxe_ip(address='10.1.1.1',
server_address='10.1.1.201')
- self.assertRaises(db_session.DBError,
+ self.assertRaises(db_exc.DBError,
db.bm_pxe_ip_create_direct,
self.context, i)
# server_address duplicates
i = utils.new_bm_pxe_ip(address='10.1.1.3',
server_address='10.1.1.101')
- self.assertRaises(db_session.DBError,
+ self.assertRaises(db_exc.DBError,
db.bm_pxe_ip_create_direct,
self.context, i)
diff --git a/nova/tests/baremetal/test_nova_baremetal_deploy_helper.py b/nova/tests/baremetal/test_nova_baremetal_deploy_helper.py
index b78aa5e8b..7ec7fd0fd 100644
--- a/nova/tests/baremetal/test_nova_baremetal_deploy_helper.py
+++ b/nova/tests/baremetal/test_nova_baremetal_deploy_helper.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 NTT DOCOMO, INC.
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
# Copyright 2011 Ilya Alekseyev
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/baremetal/test_nova_baremetal_manage.py b/nova/tests/baremetal/test_nova_baremetal_manage.py
index c4fdaac6b..74e084113 100644
--- a/nova/tests/baremetal/test_nova_baremetal_manage.py
+++ b/nova/tests/baremetal/test_nova_baremetal_manage.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 NTT DOCOMO, INC.
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
# Copyright 2011 Ilya Alekseyev
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/baremetal/test_pxe.py b/nova/tests/baremetal/test_pxe.py
index d9e41bc67..dffecf9cd 100644
--- a/nova/tests/baremetal/test_pxe.py
+++ b/nova/tests/baremetal/test_pxe.py
@@ -27,7 +27,7 @@ from oslo.config import cfg
from testtools import matchers
from nova import exception
-from nova.openstack.common.db.sqlalchemy import session as db_session
+from nova.openstack.common.db import exception as db_exc
from nova.tests.baremetal.db import base as bm_db_base
from nova.tests.baremetal.db import utils as bm_db_utils
from nova.tests.image import fake as fake_image
@@ -37,6 +37,7 @@ from nova.virt.baremetal import db
from nova.virt.baremetal import pxe
from nova.virt.baremetal import utils as bm_utils
from nova.virt.disk import api as disk_api
+from nova.virt import fake as fake_virt
CONF = cfg.CONF
@@ -61,7 +62,7 @@ class BareMetalPXETestCase(bm_db_base.BMDBTestCase):
super(BareMetalPXETestCase, self).setUp()
self.flags(**COMMON_FLAGS)
self.flags(**BAREMETAL_FLAGS)
- self.driver = pxe.PXE()
+ self.driver = pxe.PXE(fake_virt.FakeVirtAPI())
fake_image.stub_out_image_service(self.stubs)
self.addCleanup(fake_image.FakeImageService_reset)
@@ -201,8 +202,8 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase):
def test_get_instance_deploy_ids(self):
self.instance['extra_specs'] = {
- 'deploy_kernel_id': 'aaaa',
- 'deploy_ramdisk_id': 'bbbb',
+ 'baremetal:deploy_kernel_id': 'aaaa',
+ 'baremetal:deploy_ramdisk_id': 'bbbb',
}
self.flags(deploy_kernel="fail", group='baremetal')
self.flags(deploy_ramdisk="fail", group='baremetal')
@@ -239,20 +240,21 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase):
self.assertEqual(sizes[1], 1)
def test_get_tftp_image_info(self):
+ instance_type = utils.get_test_instance_type()
# Raises an exception when options are neither specified
# on the instance nor in configuration file
CONF.baremetal.deploy_kernel = None
CONF.baremetal.deploy_ramdisk = None
self.assertRaises(exception.NovaException,
pxe.get_tftp_image_info,
- self.instance)
+ self.instance, instance_type)
# Test that other non-true values also raise an exception
CONF.baremetal.deploy_kernel = ""
CONF.baremetal.deploy_ramdisk = ""
self.assertRaises(exception.NovaException,
pxe.get_tftp_image_info,
- self.instance)
+ self.instance, instance_type)
# Even if the instance includes kernel_id and ramdisk_id,
# we still need deploy_kernel_id and deploy_ramdisk_id.
@@ -262,7 +264,7 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase):
self.instance['ramdisk_id'] = 'bbbb'
self.assertRaises(exception.NovaException,
pxe.get_tftp_image_info,
- self.instance)
+ self.instance, instance_type)
# If an instance doesn't specify deploy_kernel_id or deploy_ramdisk_id,
# but defaults are set in the config file, we should use those.
@@ -272,7 +274,7 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase):
CONF.baremetal.deploy_kernel = 'cccc'
CONF.baremetal.deploy_ramdisk = 'dddd'
base = os.path.join(CONF.baremetal.tftp_root, self.instance['uuid'])
- res = pxe.get_tftp_image_info(self.instance)
+ res = pxe.get_tftp_image_info(self.instance, instance_type)
expected = {
'kernel': ['aaaa', os.path.join(base, 'kernel')],
'ramdisk': ['bbbb', os.path.join(base, 'ramdisk')],
@@ -287,24 +289,24 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase):
# Note that it is passed on the 'instance' object, despite being
# inherited from the instance_types_extra_specs table.
extra_specs = {
- 'deploy_kernel_id': 'eeee',
- 'deploy_ramdisk_id': 'ffff',
+ 'baremetal:deploy_kernel_id': 'eeee',
+ 'baremetal:deploy_ramdisk_id': 'ffff',
}
- self.instance['extra_specs'] = extra_specs
- res = pxe.get_tftp_image_info(self.instance)
+ instance_type['extra_specs'] = extra_specs
+ res = pxe.get_tftp_image_info(self.instance, instance_type)
self.assertEqual(res['deploy_kernel'][0], 'eeee')
self.assertEqual(res['deploy_ramdisk'][0], 'ffff')
# However, if invalid values are passed on the image extra_specs,
# this should still raise an exception.
extra_specs = {
- 'deploy_kernel_id': '',
- 'deploy_ramdisk_id': '',
+ 'baremetal:deploy_kernel_id': '',
+ 'baremetal:deploy_ramdisk_id': '',
}
- self.instance['extra_specs'] = extra_specs
+ instance_type['extra_specs'] = extra_specs
self.assertRaises(exception.NovaException,
pxe.get_tftp_image_info,
- self.instance)
+ self.instance, instance_type)
class PXEPrivateMethodsTestCase(BareMetalPXETestCase):
@@ -320,12 +322,13 @@ class PXEPrivateMethodsTestCase(BareMetalPXETestCase):
def test_cache_tftp_images(self):
self.instance['kernel_id'] = 'aaaa'
self.instance['ramdisk_id'] = 'bbbb'
+ instance_type = utils.get_test_instance_type()
extra_specs = {
- 'deploy_kernel_id': 'cccc',
- 'deploy_ramdisk_id': 'dddd',
+ 'baremetal:deploy_kernel_id': 'cccc',
+ 'baremetal:deploy_ramdisk_id': 'dddd',
}
- self.instance['extra_specs'] = extra_specs
- image_info = pxe.get_tftp_image_info(self.instance)
+ instance_type['extra_specs'] = extra_specs
+ image_info = pxe.get_tftp_image_info(self.instance, instance_type)
self.mox.StubOutWithMock(os, 'makedirs')
self.mox.StubOutWithMock(os.path, 'exists')
@@ -390,12 +393,15 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase):
def test_cache_images(self):
self._create_node()
+ self.mox.StubOutWithMock(self.driver.virtapi, 'instance_type_get')
self.mox.StubOutWithMock(pxe, "get_tftp_image_info")
self.mox.StubOutWithMock(self.driver, "_cache_tftp_images")
self.mox.StubOutWithMock(self.driver, "_cache_image")
self.mox.StubOutWithMock(self.driver, "_inject_into_image")
- pxe.get_tftp_image_info(self.instance).AndReturn([])
+ self.driver.virtapi.instance_type_get(
+ self.context, self.instance['instance_type_id']).AndReturn({})
+ pxe.get_tftp_image_info(self.instance, {}).AndReturn([])
self.driver._cache_tftp_images(self.context, self.instance, [])
self.driver._cache_image(self.context, self.instance, [])
self.driver._inject_into_image(self.context, self.node, self.instance,
@@ -440,6 +446,7 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase):
pxe_path = pxe.get_pxe_config_file_path(self.instance)
image_path = pxe.get_image_file_path(self.instance)
+ self.mox.StubOutWithMock(self.driver.virtapi, 'instance_type_get')
self.mox.StubOutWithMock(pxe, 'get_tftp_image_info')
self.mox.StubOutWithMock(pxe, 'get_partition_sizes')
self.mox.StubOutWithMock(bm_utils, 'random_alnum')
@@ -447,7 +454,9 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase):
self.mox.StubOutWithMock(bm_utils, 'write_to_file')
self.mox.StubOutWithMock(bm_utils, 'create_link_without_raise')
- pxe.get_tftp_image_info(self.instance).AndReturn(image_info)
+ self.driver.virtapi.instance_type_get(
+ self.context, self.instance['instance_type_id']).AndReturn({})
+ pxe.get_tftp_image_info(self.instance, {}).AndReturn(image_info)
pxe.get_partition_sizes(self.instance).AndReturn((0, 0))
bm_utils.random_alnum(32).AndReturn('alnum')
pxe.build_pxe_config(
@@ -466,18 +475,24 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase):
def test_activate_and_deactivate_bootloader(self):
self._create_node()
- extra_specs = {
- 'deploy_kernel_id': 'eeee',
- 'deploy_ramdisk_id': 'ffff',
+ instance_type = {
+ 'extra_specs': {
+ 'baremetal:deploy_kernel_id': 'eeee',
+ 'baremetal:deploy_ramdisk_id': 'ffff',
+ }
}
- self.instance['extra_specs'] = extra_specs
self.instance['uuid'] = 'fake-uuid'
+ self.mox.StubOutWithMock(self.driver.virtapi, 'instance_type_get')
self.mox.StubOutWithMock(bm_utils, 'write_to_file')
self.mox.StubOutWithMock(bm_utils, 'create_link_without_raise')
self.mox.StubOutWithMock(bm_utils, 'unlink_without_raise')
self.mox.StubOutWithMock(bm_utils, 'rmtree_without_raise')
+ self.driver.virtapi.instance_type_get(
+ self.context, self.instance['instance_type_id']).AndReturn(
+ instance_type)
+
# create the config file
bm_utils.write_to_file(mox.StrContains('fake-uuid'),
mox.StrContains(CONF.baremetal.tftp_root))
@@ -525,11 +540,14 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase):
self.mox.StubOutWithMock(pxe, 'get_tftp_image_info')
self.mox.StubOutWithMock(self.driver, '_collect_mac_addresses')
- pxe.get_tftp_image_info(self.instance).\
+ extra_specs = dict(extra_specs={
+ 'baremetal:deploy_ramdisk_id': 'ignore',
+ 'baremetal:deploy_kernel_id': 'ignore'})
+ pxe.get_tftp_image_info(self.instance, extra_specs).\
AndRaise(exception.NovaException)
bm_utils.unlink_without_raise(pxe_path)
self.driver._collect_mac_addresses(self.context, self.node).\
- AndRaise(db_session.DBError)
+ AndRaise(db_exc.DBError)
bm_utils.rmtree_without_raise(
os.path.join(CONF.baremetal.tftp_root, 'fake-uuid'))
self.mox.ReplayAll()
diff --git a/nova/tests/baremetal/test_virtual_power_driver.py b/nova/tests/baremetal/test_virtual_power_driver.py
index 5a38ed87b..4b140f66a 100644
--- a/nova/tests/baremetal/test_virtual_power_driver.py
+++ b/nova/tests/baremetal/test_virtual_power_driver.py
@@ -49,6 +49,7 @@ BAREMETAL_FLAGS = dict(
virtual_power_type='vbox',
virtual_power_host_user=None,
virtual_power_host_pass=None,
+ virtual_power_host_key=None,
group='baremetal',
)
@@ -128,7 +129,7 @@ class VPDClassMethodsTestCase(BareMetalVPDTestCase):
self.flags(virtual_power_host_user='user', group="baremetal")
self.flags(virtual_power_host_pass='password', group="baremetal")
- def test_get_conn_success(self):
+ def test_get_conn_success_pass(self):
self._create_node()
self._create_pm()
self._conn = self.pm._get_conn()
@@ -139,6 +140,24 @@ class VPDClassMethodsTestCase(BareMetalVPDTestCase):
self.assertEqual(self.pm.connection_data.host, '127.0.0.1')
self.assertEqual(self.pm.connection_data.username, 'user')
self.assertEqual(self.pm.connection_data.password, 'password')
+ self.assertEqual(self.pm.connection_data.keyfile, None)
+ self.mox.VerifyAll()
+
+ def test_get_conn_success_key(self):
+ self.flags(virtual_power_host_pass='', group="baremetal")
+ self.flags(virtual_power_host_key='/id_rsa_file.txt',
+ group="baremetal")
+ self._create_node()
+ self._create_pm()
+ self._conn = self.pm._get_conn()
+ self.mox.StubOutWithMock(connection, 'ssh_connect')
+ connection.ssh_connect(mox.IsA(self._conn)).AndReturn(True)
+ self.mox.ReplayAll()
+ self.pm._set_connection()
+ self.assertEqual(self.pm.connection_data.host, '127.0.0.1')
+ self.assertEqual(self.pm.connection_data.username, 'user')
+ self.assertEqual(self.pm.connection_data.password, '')
+ self.assertEqual(self.pm.connection_data.keyfile, '/id_rsa_file.txt')
self.mox.VerifyAll()
def test_get_full_node_list(self):
diff --git a/nova/tests/cert/__init__.py b/nova/tests/cert/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/cert/__init__.py
+++ b/nova/tests/cert/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/compute/__init__.py b/nova/tests/compute/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/compute/__init__.py
+++ b/nova/tests/compute/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/compute/fake_resource_tracker.py b/nova/tests/compute/fake_resource_tracker.py
index ab24bc7b9..2cd69b2c3 100644
--- a/nova/tests/compute/fake_resource_tracker.py
+++ b/nova/tests/compute/fake_resource_tracker.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/compute/test_claims.py b/nova/tests/compute/test_claims.py
index d908c0089..42de11c09 100644
--- a/nova/tests/compute/test_claims.py
+++ b/nova/tests/compute/test_claims.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index 5ad333c9e..e247b41c9 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -605,6 +605,18 @@ class ComputeTestCase(BaseTestCase):
fake_network.unset_stub_network_methods(self.stubs)
instance = jsonutils.to_primitive(self._create_fake_instance())
+ orig_update = self.compute._instance_update
+
+ # Make sure the access_ip_* updates happen in the same DB
+ # update as the set to ACTIVE.
+ def _instance_update(ctxt, instance_uuid, **kwargs):
+ if kwargs.get('vm_state', None) == vm_states.ACTIVE:
+ self.assertEqual(kwargs['access_ip_v4'], '192.168.1.100')
+ self.assertEqual(kwargs['access_ip_v6'], '2001:db8:0:1::1')
+ return orig_update(ctxt, instance_uuid, **kwargs)
+
+ self.stubs.Set(self.compute, '_instance_update', _instance_update)
+
try:
self.compute.run_instance(self.context, instance=instance,
is_first_time=True)
@@ -850,6 +862,29 @@ class ComputeTestCase(BaseTestCase):
self.assert_(instance['launched_at'] < terminate)
self.assert_(instance['deleted_at'] > terminate)
+ def test_run_terminate_deallocate_net_failure_sets_error_state(self):
+ instance = jsonutils.to_primitive(self._create_fake_instance())
+
+ self.compute.run_instance(self.context, instance=instance)
+
+ instances = db.instance_get_all(self.context)
+ LOG.info(_("Running instances: %s"), instances)
+ self.assertEqual(len(instances), 1)
+
+ def _fake_deallocate_network(*args, **kwargs):
+ raise Exception()
+
+ self.stubs.Set(self.compute, '_deallocate_network',
+ _fake_deallocate_network)
+
+ try:
+ self.compute.terminate_instance(self.context, instance=instance)
+ except Exception:
+ pass
+
+ instance = db.instance_get_by_uuid(self.context, instance['uuid'])
+ self.assertEqual(instance['vm_state'], vm_states.ERROR)
+
def test_stop(self):
# Ensure instance can be stopped.
instance = jsonutils.to_primitive(self._create_fake_instance())
@@ -1062,7 +1097,7 @@ class ComputeTestCase(BaseTestCase):
self.compute.terminate_instance(self.context,
instance=jsonutils.to_primitive(instance))
- def _test_reboot(self, soft, legacy_nwinfo_driver):
+ def _test_reboot(self, soft, legacy_nwinfo_driver, test_delete=False):
# This is a true unit test, so we don't need the network stubs.
fake_network.unset_stub_network_methods(self.stubs)
@@ -1141,13 +1176,24 @@ class ComputeTestCase(BaseTestCase):
# Power state should be updated again
self.compute._get_power_state(econtext,
updated_instance1).AndReturn(fake_power_state2)
- self.compute._instance_update(econtext, updated_instance1['uuid'],
- power_state=fake_power_state2,
- task_state=None,
- vm_state=vm_states.ACTIVE).AndReturn(updated_instance2)
- self.compute._notify_about_instance_usage(econtext,
- updated_instance2,
- 'reboot.end')
+ if test_delete:
+ self.compute._instance_update(econtext, updated_instance1['uuid'],
+ power_state=fake_power_state2,
+ task_state=None,
+ vm_state=vm_states.ACTIVE).AndRaise(
+ exception.InstanceNotFound(
+ instance_id=updated_instance1['uuid']))
+ self.compute._notify_about_instance_usage(econtext,
+ updated_instance1,
+ 'reboot.end')
+ else:
+ self.compute._instance_update(econtext, updated_instance1['uuid'],
+ power_state=fake_power_state2,
+ task_state=None,
+ vm_state=vm_states.ACTIVE).AndReturn(updated_instance2)
+ self.compute._notify_about_instance_usage(econtext,
+ updated_instance2,
+ 'reboot.end')
self.mox.ReplayAll()
self.compute.reboot_instance(self.context, instance=instance,
@@ -1158,9 +1204,15 @@ class ComputeTestCase(BaseTestCase):
def test_reboot_soft(self):
self._test_reboot(True, False)
+ def test_reboot_soft_and_delete(self):
+ self._test_reboot(True, False, True)
+
def test_reboot_hard(self):
self._test_reboot(False, False)
+ def test_reboot_hard_and_delete(self):
+ self._test_reboot(False, False, True)
+
def test_reboot_soft_legacy_nwinfo_driver(self):
self._test_reboot(True, True)
@@ -3109,16 +3161,12 @@ class ComputeTestCase(BaseTestCase):
self.compute.host = instance['host']
- self.mox.StubOutWithMock(self.compute.driver, 'list_instances')
- self.compute.driver.list_instances().AndReturn([instance['name']])
+ self.mox.StubOutWithMock(self.compute, '_get_instances_on_driver')
+ self.compute._get_instances_on_driver(admin_context).AndReturn(
+ [instance])
self.flags(running_deleted_instance_timeout=3600,
running_deleted_instance_action='reap')
- self.mox.StubOutWithMock(self.compute.conductor_api,
- "instance_get_all_by_host")
- self.compute.conductor_api.instance_get_all_by_host(
- admin_context, self.compute.host).AndReturn([instance])
-
bdms = []
self.mox.StubOutWithMock(self.compute, "_shutdown_instance")
@@ -3135,32 +3183,28 @@ class ComputeTestCase(BaseTestCase):
self.compute._cleanup_running_deleted_instances(admin_context)
def test_running_deleted_instances(self):
- self.mox.StubOutWithMock(self.compute.driver, 'list_instances')
- self.compute.driver.list_instances().AndReturn(['herp', 'derp'])
+ admin_context = context.get_admin_context()
+
self.compute.host = 'host'
instance1 = {}
- instance1['name'] = 'herp'
instance1['deleted'] = True
instance1['deleted_at'] = "sometimeago"
instance2 = {}
- instance2['name'] = 'derp'
instance2['deleted'] = False
instance2['deleted_at'] = None
+ self.mox.StubOutWithMock(self.compute, '_get_instances_on_driver')
+ self.compute._get_instances_on_driver(admin_context).AndReturn(
+ [instance1, instance2])
+
self.mox.StubOutWithMock(timeutils, 'is_older_than')
timeutils.is_older_than('sometimeago',
CONF.running_deleted_instance_timeout).AndReturn(True)
- self.mox.StubOutWithMock(self.compute.conductor_api,
- "instance_get_all_by_host")
- self.compute.conductor_api.instance_get_all_by_host('context',
- 'host').AndReturn(
- [instance1,
- instance2])
self.mox.ReplayAll()
- val = self.compute._running_deleted_instances('context')
+ val = self.compute._running_deleted_instances(admin_context)
self.assertEqual(val, [instance1])
def test_get_instance_nw_info(self):
@@ -3607,6 +3651,7 @@ class ComputeTestCase(BaseTestCase):
'info_cache': None,
'power_state': power_state.RUNNING,
'vm_state': vm_states.ACTIVE,
+ 'task_state': None,
}
self.flags(resume_guests_state_on_host_boot=True)
self.mox.StubOutWithMock(self.compute, '_get_power_state')
@@ -3630,6 +3675,38 @@ class ComputeTestCase(BaseTestCase):
self.mox.ReplayAll()
self.compute._init_instance('fake-context', instance)
+ def test_init_instance_reverts_crashed_migrations(self):
+ instance = {
+ 'uuid': 'foo',
+ 'vm_state': vm_states.ERROR,
+ 'task_state': task_states.RESIZE_MIGRATING,
+ 'power_state': power_state.SHUTDOWN,
+ }
+ fixed = dict(instance, task_state=None)
+ self.mox.StubOutWithMock(compute_utils, 'get_nw_info_for_instance')
+ self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
+ self.mox.StubOutWithMock(self.compute.driver,
+ 'finish_revert_migration')
+ self.mox.StubOutWithMock(self.compute,
+ '_get_instance_volume_block_device_info')
+ self.mox.StubOutWithMock(self.compute.driver, 'get_info')
+ self.mox.StubOutWithMock(self.compute, '_instance_update')
+
+ compute_utils.get_nw_info_for_instance(instance).AndReturn(
+ network_model.NetworkInfo())
+ self.compute.driver.plug_vifs(instance, [])
+ self.compute._get_instance_volume_block_device_info(
+ self.context, instance).AndReturn([])
+ self.compute.driver.finish_revert_migration(instance, [], [])
+ self.compute._instance_update(self.context, instance['uuid'],
+ task_state=None).AndReturn(fixed)
+ self.compute.driver.get_info(fixed).AndReturn(
+ {'state': power_state.SHUTDOWN})
+
+ self.mox.ReplayAll()
+
+ self.compute._init_instance(self.context, instance)
+
def test_get_instances_on_driver(self):
fake_context = context.get_admin_context()
@@ -3641,14 +3718,14 @@ class ComputeTestCase(BaseTestCase):
self.mox.StubOutWithMock(self.compute.driver,
'list_instance_uuids')
self.mox.StubOutWithMock(self.compute.conductor_api,
- 'instance_get_by_uuid')
+ 'instance_get_all_by_filters')
self.compute.driver.list_instance_uuids().AndReturn(
[inst['uuid'] for inst in driver_instances])
- for x in xrange(len(driver_instances)):
- self.compute.conductor_api.instance_get_by_uuid(fake_context,
- driver_instances[x]['uuid']).AndReturn(
- driver_instances[x])
+ self.compute.conductor_api.instance_get_all_by_filters(
+ fake_context, {'uuid': [inst['uuid'] for
+ inst in driver_instances]}).AndReturn(
+ driver_instances)
self.mox.ReplayAll()
@@ -3658,6 +3735,7 @@ class ComputeTestCase(BaseTestCase):
def test_get_instances_on_driver_fallback(self):
# Test getting instances when driver doesn't support
# 'list_instance_uuids'
+ self.compute.host = 'host'
fake_context = context.get_admin_context()
all_instances = []
@@ -3673,14 +3751,14 @@ class ComputeTestCase(BaseTestCase):
self.mox.StubOutWithMock(self.compute.driver,
'list_instances')
self.mox.StubOutWithMock(self.compute.conductor_api,
- 'instance_get_all')
+ 'instance_get_all_by_host')
self.compute.driver.list_instance_uuids().AndRaise(
NotImplementedError())
self.compute.driver.list_instances().AndReturn(
[inst['name'] for inst in driver_instances])
- self.compute.conductor_api.instance_get_all(
- fake_context).AndReturn(all_instances)
+ self.compute.conductor_api.instance_get_all_by_host(
+ fake_context, self.compute.host).AndReturn(all_instances)
self.mox.ReplayAll()
@@ -3707,6 +3785,30 @@ class ComputeTestCase(BaseTestCase):
self.mox.ReplayAll()
self.compute._instance_usage_audit(self.context)
+ def test_add_remove_fixed_ip_updates_instance_updated_at(self):
+ def _noop(*args, **kwargs):
+ pass
+
+ self.stubs.Set(self.compute.network_api,
+ 'add_fixed_ip_to_instance', _noop)
+ self.stubs.Set(self.compute.network_api,
+ 'remove_fixed_ip_from_instance', _noop)
+
+ instance = self._create_fake_instance()
+ updated_at_1 = instance['updated_at']
+
+ self.compute.add_fixed_ip_to_instance(self.context, 'fake', instance)
+ instance = db.instance_get_by_uuid(self.context, instance['uuid'])
+ updated_at_2 = instance['updated_at']
+
+ self.compute.remove_fixed_ip_from_instance(self.context, 'fake',
+ instance)
+ instance = db.instance_get_by_uuid(self.context, instance['uuid'])
+ updated_at_3 = instance['updated_at']
+
+ updated_ats = (updated_at_1, updated_at_2, updated_at_3)
+ self.assertEqual(len(updated_ats), len(set(updated_ats)))
+
class ComputeAPITestCase(BaseTestCase):
@@ -4557,6 +4659,30 @@ class ComputeAPITestCase(BaseTestCase):
inst_ref,
reboot_type)
+ def test_soft_reboot_of_rescued_instance(self):
+ # Ensure instance can't be rebooted while in rescued state.
+ instance = jsonutils.to_primitive(self._create_fake_instance())
+ self.compute.run_instance(self.context, instance=instance)
+
+ inst_ref = db.instance_get_by_uuid(self.context, instance['uuid'])
+
+ db.instance_update(self.context, instance['uuid'],
+ {"vm_state": vm_states.RESCUED})
+
+ inst_ref = db.instance_get_by_uuid(self.context, inst_ref['uuid'])
+
+ self.assertRaises(exception.InstanceInvalidState,
+ self.compute_api.reboot,
+ self.context,
+ inst_ref,
+ 'SOFT')
+
+ self.assertRaises(exception.InstanceInvalidState,
+ self.compute_api.reboot,
+ self.context,
+ inst_ref,
+ 'HARD')
+
def test_hostname_create(self):
# Ensure instance hostname is set during creation.
inst_type = instance_types.get_instance_type_by_name('m1.tiny')
@@ -4663,8 +4789,8 @@ class ComputeAPITestCase(BaseTestCase):
def test_snapshot_minram_mindisk_VHD(self):
"""Ensure a snapshots min_ram and min_disk are correct.
- A snapshot of a non-shrinkable VHD should have min_ram
- and min_disk set to that of the original instances flavor.
+ A snapshot of a non-shrinkable VHD should have min_disk
+ set to that of the original instances flavor.
"""
self.fake_image.update(disk_format='vhd',
@@ -4678,7 +4804,7 @@ class ComputeAPITestCase(BaseTestCase):
self.assertEqual(image['name'], 'snap1')
instance_type = instance['instance_type']
- self.assertEqual(image['min_ram'], instance_type['memory_mb'])
+ self.assertEqual(image['min_ram'], self.fake_image['min_ram'])
self.assertEqual(image['min_disk'], instance_type['root_gb'])
properties = image['properties']
self.assertTrue('backup_type' not in properties)
@@ -5073,7 +5199,6 @@ class ComputeAPITestCase(BaseTestCase):
instance = self._create_fake_instance(dict(host='host2'))
instance = db.instance_get_by_uuid(self.context, instance['uuid'])
instance = jsonutils.to_primitive(instance)
- instance['instance_type']['extra_specs'] = []
orig_instance_type = instance['instance_type']
self.compute.run_instance(self.context, instance=instance)
# We need to set the host to something 'known'. Unfortunately,
@@ -6348,8 +6473,14 @@ class ComputeAPITestCase(BaseTestCase):
def fake_service_is_up(*args, **kwargs):
return False
+ def fake_rebuild_instance(*args, **kwargs):
+ db.instance_update(self.context, instance_uuid,
+ {'host': kwargs['host']})
+
self.stubs.Set(self.compute_api.servicegroup_api, 'service_is_up',
fake_service_is_up)
+ self.stubs.Set(self.compute_api.compute_rpcapi, 'rebuild_instance',
+ fake_rebuild_instance)
self.compute_api.evacuate(self.context.elevated(),
instance,
host='fake_dest_host',
@@ -6358,6 +6489,7 @@ class ComputeAPITestCase(BaseTestCase):
instance = db.instance_get_by_uuid(self.context, instance_uuid)
self.assertEqual(instance['task_state'], task_states.REBUILDING)
+ self.assertEqual(instance['host'], 'fake_dest_host')
db.instance_destroy(self.context, instance['uuid'])
@@ -7225,6 +7357,41 @@ class ComputeRescheduleOrReraiseTestCase(BaseTestCase):
self.compute._reschedule_or_reraise(self.context, self.instance,
exc_info, None, None, None, False, None, {})
+ def test_no_reschedule_on_delete_during_spawn(self):
+ # instance should not be rescheduled if instance is deleted
+ # during the build
+ self.mox.StubOutWithMock(self.compute, '_spawn')
+ self.mox.StubOutWithMock(self.compute, '_reschedule_or_reraise')
+
+ exc = exception.UnexpectedTaskStateError(expected=task_states.SPAWNING,
+ actual=task_states.DELETING)
+ self.compute._spawn(mox.IgnoreArg(), self.instance, mox.IgnoreArg(),
+ mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(),
+ mox.IgnoreArg(), set_access_ip=False).AndRaise(exc)
+
+ self.mox.ReplayAll()
+ # test succeeds if mocked method '_reschedule_or_reraise' is not
+ # called.
+ self.compute._run_instance(self.context, None, {}, None, None, None,
+ False, None, self.instance)
+
+ def test_no_reschedule_on_unexpected_task_state(self):
+ # instance shouldn't be rescheduled if unexpected task state arises.
+ # the exception should get reraised.
+ self.mox.StubOutWithMock(self.compute, '_spawn')
+ self.mox.StubOutWithMock(self.compute, '_reschedule_or_reraise')
+
+ exc = exception.UnexpectedTaskStateError(expected=task_states.SPAWNING,
+ actual=task_states.SCHEDULING)
+ self.compute._spawn(mox.IgnoreArg(), self.instance, mox.IgnoreArg(),
+ mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(),
+ mox.IgnoreArg(), set_access_ip=False).AndRaise(exc)
+
+ self.mox.ReplayAll()
+ self.assertRaises(exception.UnexpectedTaskStateError,
+ self.compute._run_instance, self.context, None, {}, None, None,
+ None, False, None, self.instance)
+
class ComputeRescheduleResizeOrReraiseTestCase(BaseTestCase):
"""Test logic and exception handling around rescheduling prep resize
diff --git a/nova/tests/compute/test_compute_utils.py b/nova/tests/compute/test_compute_utils.py
index 0f96e657d..884aac628 100644
--- a/nova/tests/compute/test_compute_utils.py
+++ b/nova/tests/compute/test_compute_utils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/compute/test_host_api.py b/nova/tests/compute/test_host_api.py
index 772ae1eb1..3b5a9b871 100644
--- a/nova/tests/compute/test_host_api.py
+++ b/nova/tests/compute/test_host_api.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/compute/test_multiple_nodes.py b/nova/tests/compute/test_multiple_nodes.py
index 1a967c5e4..8bf3781c7 100644
--- a/nova/tests/compute/test_multiple_nodes.py
+++ b/nova/tests/compute/test_multiple_nodes.py
@@ -19,7 +19,6 @@
from oslo.config import cfg
from nova import context
-from nova import exception
from nova.openstack.common import importutils
from nova import test
from nova.virt import fake
@@ -72,8 +71,8 @@ class FakeDriverMultiNodeTestCase(BaseTestCase):
res_b = self.driver.get_available_resource('bbb')
self.assertEqual(res_b['hypervisor_hostname'], 'bbb')
- self.assertRaises(exception.NovaException,
- self.driver.get_available_resource, 'xxx')
+ res_x = self.driver.get_available_resource('xxx')
+ self.assertEqual(res_x, {})
class MultiNodeComputeTestCase(BaseTestCase):
@@ -101,3 +100,22 @@ class MultiNodeComputeTestCase(BaseTestCase):
self.compute.update_available_resource(ctx)
self.assertEqual(sorted(self.compute._resource_tracker_dict.keys()),
['A', 'B', 'C'])
+
+ def test_compute_manager_removes_deleted_node(self):
+ ctx = context.get_admin_context()
+ fake.set_nodes(['A', 'B'])
+ self.compute.update_available_resource(ctx)
+
+ rt_A = self.compute._resource_tracker_dict['A']
+ rt_B = self.compute._resource_tracker_dict['B']
+ self.mox.StubOutWithMock(rt_A, 'update_available_resource')
+ self.mox.StubOutWithMock(rt_B, 'update_available_resource')
+ rt_A.update_available_resource(ctx)
+ rt_B.update_available_resource(ctx, delete=True)
+ self.mox.ReplayAll()
+
+ fake.set_nodes(['A'])
+ self.compute.update_available_resource(ctx)
+ self.mox.VerifyAll()
+ self.assertEqual(sorted(self.compute._resource_tracker_dict.keys()),
+ ['A'])
diff --git a/nova/tests/compute/test_resource_tracker.py b/nova/tests/compute/test_resource_tracker.py
index 84dbc69fc..860ea9fab 100644
--- a/nova/tests/compute/test_resource_tracker.py
+++ b/nova/tests/compute/test_resource_tracker.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -347,6 +347,9 @@ class BaseTrackerTestCase(BaseTestCase):
# database models and a compatible compute driver:
super(BaseTrackerTestCase, self).setUp()
+ self.updated = False
+ self.deleted = False
+
self.tracker = self._tracker()
self._migrations = {}
@@ -354,6 +357,8 @@ class BaseTrackerTestCase(BaseTestCase):
self._fake_service_get_by_compute_host)
self.stubs.Set(db, 'compute_node_update',
self._fake_compute_node_update)
+ self.stubs.Set(db, 'compute_node_delete',
+ self._fake_compute_node_delete)
self.stubs.Set(db, 'migration_update',
self._fake_migration_update)
self.stubs.Set(db, 'migration_get_in_progress_by_host_and_node',
@@ -375,6 +380,11 @@ class BaseTrackerTestCase(BaseTestCase):
self.compute.update(values)
return self.compute
+ def _fake_compute_node_delete(self, ctx, compute_node_id):
+ self.deleted = True
+ self.compute.update({'deleted': 1})
+ return self.compute
+
def _fake_migration_get_in_progress_by_host_and_node(self, ctxt, host,
node):
status = ['confirmed', 'reverted']
@@ -867,10 +877,6 @@ class ResizeClaimTestCase(BaseTrackerTestCase):
class OrphanTestCase(BaseTrackerTestCase):
-
- def setUp(self):
- super(OrphanTestCase, self).setUp()
-
def _driver(self):
class OrphanVirtDriver(FakeVirtDriver):
def get_per_instance_usage(self):
@@ -892,3 +898,18 @@ class OrphanTestCase(BaseTrackerTestCase):
orphans = self.tracker._find_orphaned_instances()
self.assertEqual(2, len(orphans))
+
+
+class DeletedNodeTestCase(BaseTrackerTestCase):
+
+ def test_remove_deleted_node(self):
+ self.assertFalse(self.tracker.disabled)
+ self.assertTrue(self.updated)
+
+ def _get_available_resource(nodename):
+ return {}
+ self.tracker.driver.get_available_resource = _get_available_resource
+
+ self.tracker.update_available_resource(self.context, delete=True)
+ self.assertEqual(self.deleted, True)
+ self.assertEqual(self.compute['deleted'], 1)
diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py
index 1257f67e1..6c40a95e2 100644
--- a/nova/tests/compute/test_rpcapi.py
+++ b/nova/tests/compute/test_rpcapi.py
@@ -162,9 +162,6 @@ class ComputeRpcAPITestCase(test.TestCase):
self._test_compute_api('get_diagnostics', 'call',
instance=self.fake_instance)
- def test_get_host_uptime(self):
- self._test_compute_api('get_host_uptime', 'call')
-
def test_get_vnc_console(self):
self._test_compute_api('get_vnc_console', 'call',
instance=self.fake_instance, console_type='type')
diff --git a/nova/tests/compute/test_stats.py b/nova/tests/compute/test_stats.py
index a798670c7..03fe4b359 100644
--- a/nova/tests/compute/test_stats.py
+++ b/nova/tests/compute/test_stats.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/compute/test_virtapi.py b/nova/tests/compute/test_virtapi.py
index 568bf456d..e3887d033 100644
--- a/nova/tests/compute/test_virtapi.py
+++ b/nova/tests/compute/test_virtapi.py
@@ -77,6 +77,10 @@ class VirtAPIBaseTest(test.TestCase, test.APICoverage):
self.assertExpected('agent_build_get_by_triple',
'fake-hv', 'gnu/hurd', 'fake-arch')
+ def test_instance_type_get(self):
+ self.assertExpected('instance_type_get',
+ 'fake-instance-type')
+
class FakeVirtAPITest(VirtAPIBaseTest):
diff --git a/nova/tests/conductor/test_conductor.py b/nova/tests/conductor/test_conductor.py
index 32e685623..72c04e427 100644
--- a/nova/tests/conductor/test_conductor.py
+++ b/nova/tests/conductor/test_conductor.py
@@ -429,6 +429,14 @@ class _BaseTestCase(object):
'fake-values', False)
self.assertEqual(result, 'fake-result')
+ def test_compute_node_delete(self):
+ node = {'id': 'fake-id'}
+ self.mox.StubOutWithMock(db, 'compute_node_delete')
+ db.compute_node_delete(self.context, node['id']).AndReturn(None)
+ self.mox.ReplayAll()
+ result = self.conductor.compute_node_delete(self.context, node)
+ self.assertEqual(result, None)
+
def test_instance_fault_create(self):
self.mox.StubOutWithMock(db, 'instance_fault_create')
db.instance_fault_create(self.context, 'fake-values').AndReturn(
diff --git a/nova/tests/console/__init__.py b/nova/tests/console/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/console/__init__.py
+++ b/nova/tests/console/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/console/test_console.py b/nova/tests/console/test_console.py
index 0f95f3d95..54bcb32ca 100644
--- a/nova/tests/console/test_console.py
+++ b/nova/tests/console/test_console.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
diff --git a/nova/tests/consoleauth/__init__.py b/nova/tests/consoleauth/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/consoleauth/__init__.py
+++ b/nova/tests/consoleauth/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/consoleauth/test_consoleauth.py b/nova/tests/consoleauth/test_consoleauth.py
index 54e3d2261..9b9b0c92a 100644
--- a/nova/tests/consoleauth/test_consoleauth.py
+++ b/nova/tests/consoleauth/test_consoleauth.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py
index d77e189df..455751809 100644
--- a/nova/tests/db/fakes.py
+++ b/nova/tests/db/fakes.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
-# Copyright 2010 OpenStack, LLC
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -331,51 +331,56 @@ def stub_out_db_instance_api(stubs, injected=True):
INSTANCE_TYPES = {
'm1.tiny': dict(id=2,
+ name='m1.tiny',
memory_mb=512,
vcpus=1,
vcpu_weight=None,
root_gb=0,
ephemeral_gb=10,
flavorid=1,
- rxtx_cap=1,
+ rxtx_factor=1.0,
swap=0),
'm1.small': dict(id=5,
+ name='m1.small',
memory_mb=2048,
vcpus=1,
vcpu_weight=None,
root_gb=20,
ephemeral_gb=0,
flavorid=2,
- rxtx_cap=2,
+ rxtx_factor=1.0,
swap=1024),
'm1.medium':
dict(id=1,
+ name='m1.medium',
memory_mb=4096,
vcpus=2,
vcpu_weight=None,
root_gb=40,
ephemeral_gb=40,
flavorid=3,
- rxtx_cap=3,
+ rxtx_factor=1.0,
swap=0),
'm1.large': dict(id=3,
+ name='m1.large',
memory_mb=8192,
vcpus=4,
vcpu_weight=None,
root_gb=80,
ephemeral_gb=80,
flavorid=4,
- rxtx_cap=4,
+ rxtx_factor=1.0,
swap=0),
'm1.xlarge':
dict(id=4,
+ name='m1.xlarge',
memory_mb=16384,
vcpus=8,
vcpu_weight=None,
root_gb=160,
ephemeral_gb=160,
flavorid=5,
- rxtx_cap=5,
+ rxtx_factor=1.0,
swap=0)}
flat_network_fields = {'id': 'fake_flat',
diff --git a/nova/tests/fake_hosts.py b/nova/tests/fake_hosts.py
index e6831d124..618566c0b 100644
--- a/nova/tests/fake_hosts.py
+++ b/nova/tests/fake_hosts.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/fake_instance_actions.py b/nova/tests/fake_instance_actions.py
index f34d9b213..e12ae827f 100644
--- a/nova/tests/fake_instance_actions.py
+++ b/nova/tests/fake_instance_actions.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2013 OpenStack LLC
+# Copyright 2013 OpenStack Foundation
#
# 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/tests/fake_libvirt_utils.py b/nova/tests/fake_libvirt_utils.py
index 31b1af231..ba00a7091 100644
--- a/nova/tests/fake_libvirt_utils.py
+++ b/nova/tests/fake_libvirt_utils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack LLC
+# Copyright (c) 2011 OpenStack Foundation
#
# 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/tests/fake_loadables/__init__.py b/nova/tests/fake_loadables/__init__.py
index 824243347..a74c55d21 100644
--- a/nova/tests/fake_loadables/__init__.py
+++ b/nova/tests/fake_loadables/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC. # All Rights Reserved.
+# Copyright 2012 OpenStack Foundation # All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
diff --git a/nova/tests/fake_loadables/fake_loadable1.py b/nova/tests/fake_loadables/fake_loadable1.py
index 58f9704b3..cc02fe717 100644
--- a/nova/tests/fake_loadables/fake_loadable1.py
+++ b/nova/tests/fake_loadables/fake_loadable1.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC. # All Rights Reserved.
+# Copyright 2012 OpenStack Foundation # All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
diff --git a/nova/tests/fake_loadables/fake_loadable2.py b/nova/tests/fake_loadables/fake_loadable2.py
index 3e365effc..e72b58200 100644
--- a/nova/tests/fake_loadables/fake_loadable2.py
+++ b/nova/tests/fake_loadables/fake_loadable2.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC. # All Rights Reserved.
+# Copyright 2012 OpenStack Foundation # All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
diff --git a/nova/tests/fake_network_cache_model.py b/nova/tests/fake_network_cache_model.py
index 32ace8bdc..3aa3bf586 100644
--- a/nova/tests/fake_network_cache_model.py
+++ b/nova/tests/fake_network_cache_model.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/fake_policy.py b/nova/tests/fake_policy.py
index 7f9fffddc..94380058d 100644
--- a/nova/tests/fake_policy.py
+++ b/nova/tests/fake_policy.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
#
# 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/tests/fakelibvirt.py b/nova/tests/fakelibvirt.py
index 69a4e677e..05dce0c76 100644
--- a/nova/tests/fakelibvirt.py
+++ b/nova/tests/fakelibvirt.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2010 OpenStack LLC
+# Copyright 2010 OpenStack Foundation
#
# 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
@@ -16,6 +16,7 @@
from lxml import etree
+import time
import uuid
# Allow passing None to the various connect methods
diff --git a/nova/tests/hyperv/db_fakes.py b/nova/tests/hyperv/db_fakes.py
index 7169edf8d..5152bd035 100644
--- a/nova/tests/hyperv/db_fakes.py
+++ b/nova/tests/hyperv/db_fakes.py
@@ -41,7 +41,7 @@ def get_fake_instance_data(name, project_id, user_id):
{'name': 'm1.tiny',
'memory_mb': 512,
'vcpus': 1,
- 'root_gb': 0,
+ 'root_gb': 1024,
'flavorid': 1,
'rxtx_factor': 1}
}
@@ -69,8 +69,6 @@ def get_fake_volume_info_data(target_portal, volume_id):
'target_portal': target_portal,
'target_lun': 1,
'auth_method': 'CHAP',
- 'auth_method': 'fake',
- 'auth_method': 'fake',
}
}
@@ -121,6 +119,9 @@ def stub_out_db_instance_api(stubs):
def __getitem__(self, key):
return self.get(key)
+ def __setitem__(self, key, value):
+ self.values[key] = value
+
def __str__(self):
return str(self.values)
diff --git a/nova/tests/image/__init__.py b/nova/tests/image/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/image/__init__.py
+++ b/nova/tests/image/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/image/fake.py b/nova/tests/image/fake.py
index 06f2f5147..d2d80ab35 100644
--- a/nova/tests/image/fake.py
+++ b/nova/tests/image/fake.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 Justin Santa Barbara
-# Copyright 2012 OpenStack LLC
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/image/test_fake.py b/nova/tests/image/test_fake.py
index c63bb5389..266d03fc6 100644
--- a/nova/tests/image/test_fake.py
+++ b/nova/tests/image/test_fake.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
# Author: Soren Hansen
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py
index a7ed4c409..2eca4b969 100644
--- a/nova/tests/image/test_glance.py
+++ b/nova/tests/image/test_glance.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-req.json.tpl b/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-req.json.tpl
new file mode 100644
index 000000000..3d360a57b
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-req.json.tpl
@@ -0,0 +1,6 @@
+{
+ "volumeAttachment": {
+ "volumeId": "%(volume_id)s",
+ "device": "%(device)s"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-req.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-req.xml.tpl
new file mode 100644
index 000000000..ffb20ad1e
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-req.xml.tpl
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<volumeAttachment volumeId="%(volume_id)s" device="%(device)s" />
diff --git a/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-resp.json.tpl
new file mode 100644
index 000000000..4730b3c19
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-resp.json.tpl
@@ -0,0 +1,8 @@
+{
+ "volumeAttachment": {
+ "device": "%(device)s",
+ "id": "%(volume_id)s",
+ "serverId": "%(uuid)s",
+ "volumeId": "%(volume_id)s"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-resp.xml.tpl
new file mode 100644
index 000000000..efad2fd02
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/attach-volume-to-server-resp.xml.tpl
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumeAttachment device="%(device)s" serverId="%(uuid)s" id="%(volume_id)s" volumeId="%(volume_id)s"/>
diff --git a/nova/tests/integrated/api_samples/os-volumes/list-volume-attachments-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/list-volume-attachments-resp.json.tpl
new file mode 100644
index 000000000..6c1da07ef
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/list-volume-attachments-resp.json.tpl
@@ -0,0 +1,16 @@
+{
+ "volumeAttachments": [
+ {
+ "device": "/dev/sdd",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "%(uuid)s",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ },
+ {
+ "device": "/dev/sdc",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f804",
+ "serverId": "%(uuid)s",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f804"
+ }
+ ]
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/list-volume-attachments-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/list-volume-attachments-resp.xml.tpl
new file mode 100644
index 000000000..351646d81
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/list-volume-attachments-resp.xml.tpl
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumeAttachments>
+ <volumeAttachment device="/dev/sdd" serverId="%(uuid)s" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/>
+ <volumeAttachment device="/dev/sdc" serverId="%(uuid)s" id="a26887c6-c47b-4654-abb5-dfadf7d3f804" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f804"/>
+</volumeAttachments>
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-detail-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-detail-resp.json.tpl
new file mode 100644
index 000000000..eeca4489e
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-detail-resp.json.tpl
@@ -0,0 +1,24 @@
+{
+ "volumes": [
+ {
+ "attachments": [
+ {
+ "device": "/",
+ "id": "%(uuid)s",
+ "serverId": "%(uuid)s",
+ "volumeId": "%(uuid)s"
+ }
+ ],
+ "availabilityZone": "zone1:host1",
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "%(volume_desc)s",
+ "displayName": "%(volume_name)s",
+ "id": "%(uuid)s",
+ "metadata": {},
+ "size": 100,
+ "snapshotId": null,
+ "status": "in-use",
+ "volumeType": "Backup"
+ }
+ ]
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-detail-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-detail-resp.xml.tpl
new file mode 100644
index 000000000..7410bed49
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-detail-resp.xml.tpl
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumes>
+ <volume status="in-use" displayDescription="%(volume_desc)s" availabilityZone="zone1:host1" displayName="%(volume_name)s" volumeType="Backup" snapshotId="None" id="%(uuid)s" createdAt="%(timestamp)s" size="100">
+ <attachments>
+ <attachment device="/" serverId="%(uuid)s" id="%(uuid)s" volumeId="%(uuid)s"/>
+ </attachments>
+ <metadata/>
+ </volume>
+</volumes>
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-get-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-get-resp.json.tpl
new file mode 100644
index 000000000..4343e6c0a
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-get-resp.json.tpl
@@ -0,0 +1,22 @@
+{
+ "volume": {
+ "attachments": [
+ {
+ "device": "/",
+ "id": "%(uuid)s",
+ "serverId": "%(uuid)s",
+ "volumeId": "%(uuid)s"
+ }
+ ],
+ "availabilityZone": "zone1:host1",
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "%(volume_desc)s",
+ "displayName": "%(volume_name)s",
+ "id": "%(uuid)s",
+ "metadata": {},
+ "size": 100,
+ "snapshotId": null,
+ "status": "in-use",
+ "volumeType": "Backup"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-get-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-get-resp.xml.tpl
new file mode 100644
index 000000000..6503138f0
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-get-resp.xml.tpl
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volume status="in-use" displayDescription="%(volume_desc)s" availabilityZone="zone1:host1" displayName="%(volume_name)s" volumeType="Backup" snapshotId="None" id="%(uuid)s" createdAt="%(timestamp)s" size="100">
+ <attachments>
+ <attachment device="/" serverId="%(uuid)s" id="%(uuid)s" volumeId="%(uuid)s"/>
+ </attachments>
+ <metadata/>
+</volume>
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-index-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-index-resp.json.tpl
new file mode 100644
index 000000000..eeca4489e
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-index-resp.json.tpl
@@ -0,0 +1,24 @@
+{
+ "volumes": [
+ {
+ "attachments": [
+ {
+ "device": "/",
+ "id": "%(uuid)s",
+ "serverId": "%(uuid)s",
+ "volumeId": "%(uuid)s"
+ }
+ ],
+ "availabilityZone": "zone1:host1",
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "%(volume_desc)s",
+ "displayName": "%(volume_name)s",
+ "id": "%(uuid)s",
+ "metadata": {},
+ "size": 100,
+ "snapshotId": null,
+ "status": "in-use",
+ "volumeType": "Backup"
+ }
+ ]
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-index-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-index-resp.xml.tpl
new file mode 100644
index 000000000..7410bed49
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-index-resp.xml.tpl
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumes>
+ <volume status="in-use" displayDescription="%(volume_desc)s" availabilityZone="zone1:host1" displayName="%(volume_name)s" volumeType="Backup" snapshotId="None" id="%(uuid)s" createdAt="%(timestamp)s" size="100">
+ <attachments>
+ <attachment device="/" serverId="%(uuid)s" id="%(uuid)s" volumeId="%(uuid)s"/>
+ </attachments>
+ <metadata/>
+ </volume>
+</volumes>
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-req.json.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-req.json.tpl
new file mode 100644
index 000000000..db7fbff4d
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-req.json.tpl
@@ -0,0 +1,9 @@
+{
+ "volume":
+ {
+ "availability_zone": "zone1:host1",
+ "display_name": "%(volume_name)s",
+ "display_description": "%(volume_desc)s",
+ "size": 100
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-req.xml.tpl
new file mode 100644
index 000000000..bb115cc61
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-req.xml.tpl
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+ <volume displayDescription="%(volume_desc)s" availabilityZone="zone1:host1" displayName="%(volume_name)s" size="100"/>
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-resp.json.tpl
new file mode 100644
index 000000000..f1a3d3ca3
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-resp.json.tpl
@@ -0,0 +1,21 @@
+{
+ "volume": {
+ "status": "in-use",
+ "displayDescription": "%(volume_desc)s",
+ "availabilityZone": "zone1:host1",
+ "displayName": "%(volume_name)s",
+ "attachments": [
+ { "device": "/",
+ "serverId": "%(uuid)s",
+ "id": "%(uuid)s",
+ "volumeId": "%(uuid)s"
+ }
+ ],
+ "volumeType": "Backup",
+ "snapshotId": null,
+ "metadata": {},
+ "id": "%(uuid)s",
+ "createdAt": "%(timestamp)s",
+ "size": 100
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-resp.xml.tpl
new file mode 100644
index 000000000..6503138f0
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/os-volumes-post-resp.xml.tpl
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volume status="in-use" displayDescription="%(volume_desc)s" availabilityZone="zone1:host1" displayName="%(volume_name)s" volumeType="Backup" snapshotId="None" id="%(uuid)s" createdAt="%(timestamp)s" size="100">
+ <attachments>
+ <attachment device="/" serverId="%(uuid)s" id="%(uuid)s" volumeId="%(uuid)s"/>
+ </attachments>
+ <metadata/>
+</volume>
diff --git a/nova/tests/integrated/api_samples/os-volumes/server-post-req.json.tpl b/nova/tests/integrated/api_samples/os-volumes/server-post-req.json.tpl
new file mode 100644
index 000000000..d3916d1aa
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/server-post-req.json.tpl
@@ -0,0 +1,16 @@
+{
+ "server" : {
+ "name" : "new-server-test",
+ "imageRef" : "%(host)s/openstack/images/%(image_id)s",
+ "flavorRef" : "%(host)s/openstack/flavors/1",
+ "metadata" : {
+ "My Server Name" : "Apache1"
+ },
+ "personality" : [
+ {
+ "path" : "/etc/banner.txt",
+ "contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
+ }
+ ]
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/server-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/server-post-req.xml.tpl
new file mode 100644
index 000000000..f92614984
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/server-post-req.xml.tpl
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<server xmlns="http://docs.openstack.org/compute/api/v1.1" imageRef="%(host)s/openstack/images/%(image_id)s" flavorRef="%(host)s/openstack/flavors/1" name="new-server-test">
+ <metadata>
+ <meta key="My Server Name">Apache1</meta>
+ </metadata>
+ <personality>
+ <file path="/etc/banner.txt">
+ ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp
+ dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k
+ IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs
+ c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g
+ QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo
+ ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv
+ dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy
+ c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6
+ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==
+ </file>
+ </personality>
+</server>
diff --git a/nova/tests/integrated/api_samples/os-volumes/server-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/server-post-resp.json.tpl
new file mode 100644
index 000000000..d5f030c87
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/server-post-resp.json.tpl
@@ -0,0 +1,16 @@
+{
+ "server": {
+ "adminPass": "%(password)s",
+ "id": "%(id)s",
+ "links": [
+ {
+ "href": "%(host)s/v2/openstack/servers/%(uuid)s",
+ "rel": "self"
+ },
+ {
+ "href": "%(host)s/openstack/servers/%(uuid)s",
+ "rel": "bookmark"
+ }
+ ]
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/server-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/server-post-resp.xml.tpl
new file mode 100644
index 000000000..3bb13e69b
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/server-post-resp.xml.tpl
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<server xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="%(id)s" adminPass="%(password)s">
+ <metadata/>
+ <atom:link href="%(host)s/v2/openstack/servers/%(uuid)s" rel="self"/>
+ <atom:link href="%(host)s/openstack/servers/%(uuid)s" rel="bookmark"/>
+</server>
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshot-create-req.json.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshot-create-req.json.tpl
new file mode 100644
index 000000000..a8d47ea03
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshot-create-req.json.tpl
@@ -0,0 +1,8 @@
+{
+ "snapshot": {
+ "display_name": "%(snapshot_name)s",
+ "display_description": "%(description)s",
+ "volume_id": "%(volume_id)s",
+ "force": false
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshot-create-req.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshot-create-req.xml.tpl
new file mode 100644
index 000000000..a5b670bc2
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshot-create-req.xml.tpl
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <snapshot>
+ <display_name>%(snapshot_name)s</display_name>
+ <display_description>%(description)s</display_description>
+ <volume_id>%(volume_id)s</volume_id>
+ <force>false</force>
+ </snapshot>
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshot-create-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshot-create-resp.json.tpl
new file mode 100644
index 000000000..73cd02d9d
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshot-create-resp.json.tpl
@@ -0,0 +1,32 @@
+{
+ "snapshot": {
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "%(description)s",
+ "displayName": "%(snapshot_name)s",
+ "id": 100,
+ "size": 100,
+ "status": "available",
+ "volumeId": {
+ "attach_status": "attached",
+ "availability_zone": "fakeaz",
+ "created_at": "%(timestamp)s",
+ "display_description": "displaydesc",
+ "display_name": "displayname",
+ "host": "fakehost",
+ "id": "%(uuid)s",
+ "instance_uuid": "fakeuuid",
+ "mountpoint": "/",
+ "name": "vol name",
+ "project_id": "fakeproject",
+ "size": 1,
+ "snapshot_id": null,
+ "status": "fakestatus",
+ "user_id": "fakeuser",
+ "volume_metadata": [],
+ "volume_type": {
+ "name": "vol_type_name"
+ },
+ "volume_type_id": "fakevoltype"
+ }
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshot-create-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshot-create-resp.xml.tpl
new file mode 100644
index 000000000..aa713311f
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshot-create-resp.xml.tpl
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<snapshot status="available" displayDescription="%(description)s" displayName="%(snapshot_name)s" volumeId="{'instance_uuid': 'fakeuuid', 'status': 'fakestatus', 'user_id': 'fakeuser', 'name': 'vol name', 'display_name': 'displayname', 'availability_zone': 'fakeaz', 'created_at': datetime.datetime(1999, 1, 1, 1, 1, 1), 'attach_status': 'attached', 'display_description': 'displaydesc', 'host': 'fakehost', 'volume_type_id': 'fakevoltype', 'volume_metadata': [], 'volume_type': {'name': 'vol_type_name'}, 'snapshot_id': None, 'mountpoint': '/', 'project_id': 'fakeproject', 'id': u'521752a6-acf6-4b2d-bc7a-119f9148cd8c', 'size': 1}" id="100" createdAt="%(timestamp)s" size="100"/>
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshots-detail-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshots-detail-resp.json.tpl
new file mode 100644
index 000000000..f6b4a3abf
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshots-detail-resp.json.tpl
@@ -0,0 +1,31 @@
+{
+ "snapshots": [
+ {
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 100,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ },
+ {
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 101,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ },
+ {
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "Default description",
+ "displayName": "Default name",
+ "id": 102,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ }
+ ]
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshots-detail-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshots-detail-resp.xml.tpl
new file mode 100644
index 000000000..dbfe32526
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshots-detail-resp.xml.tpl
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<snapshots>
+ <snapshot status="available" displayDescription="%(text)s" displayName="%(text)s" volumeId="12" id="100" createdAt="%(timestamp)s" size="100"/>
+ <snapshot status="available" displayDescription="%(text)s" displayName="%(text)s" volumeId="12" id="101" createdAt="%(timestamp)s" size="100"/>
+ <snapshot status="available" displayDescription="%(text)s" displayName="%(text)s" volumeId="12" id="102" createdAt="%(timestamp)s" size="100"/>
+</snapshots>
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshots-list-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshots-list-resp.json.tpl
new file mode 100644
index 000000000..5cfbd7283
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshots-list-resp.json.tpl
@@ -0,0 +1,31 @@
+{
+ "snapshots": [
+ {
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "%(text)s",
+ "displayName": "%(text)s",
+ "id": 100,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ },
+ {
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "%(text)s",
+ "displayName": "%(text)s",
+ "id": 101,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ },
+ {
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "%(text)s",
+ "displayName": "%(text)s",
+ "id": 102,
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ }
+ ]
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshots-list-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshots-list-resp.xml.tpl
new file mode 100644
index 000000000..dbfe32526
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshots-list-resp.xml.tpl
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<snapshots>
+ <snapshot status="available" displayDescription="%(text)s" displayName="%(text)s" volumeId="12" id="100" createdAt="%(timestamp)s" size="100"/>
+ <snapshot status="available" displayDescription="%(text)s" displayName="%(text)s" volumeId="12" id="101" createdAt="%(timestamp)s" size="100"/>
+ <snapshot status="available" displayDescription="%(text)s" displayName="%(text)s" volumeId="12" id="102" createdAt="%(timestamp)s" size="100"/>
+</snapshots>
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshots-show-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshots-show-resp.json.tpl
new file mode 100644
index 000000000..0690ed8b6
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshots-show-resp.json.tpl
@@ -0,0 +1,11 @@
+{
+ "snapshot": {
+ "createdAt": "%(timestamp)s",
+ "displayDescription": "%(description)s",
+ "displayName": "%(snapshot_name)s",
+ "id": "100",
+ "size": 100,
+ "status": "available",
+ "volumeId": 12
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/snapshots-show-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/snapshots-show-resp.xml.tpl
new file mode 100644
index 000000000..3525851cf
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/snapshots-show-resp.xml.tpl
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<snapshot status="available" displayDescription="%(description)s" displayName="%(snapshot_name)s" volumeId="12" id="100" createdAt="%(timestamp)s" size="100"/>
diff --git a/nova/tests/integrated/api_samples/os-volumes/volume-attachment-detail-resp.json.tpl b/nova/tests/integrated/api_samples/os-volumes/volume-attachment-detail-resp.json.tpl
new file mode 100644
index 000000000..86099eeb8
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/volume-attachment-detail-resp.json.tpl
@@ -0,0 +1,8 @@
+{
+ "volumeAttachment": {
+ "device": "/dev/sdd",
+ "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
+ "serverId": "%(uuid)s",
+ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-volumes/volume-attachment-detail-resp.xml.tpl b/nova/tests/integrated/api_samples/os-volumes/volume-attachment-detail-resp.xml.tpl
new file mode 100644
index 000000000..45fd19979
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-volumes/volume-attachment-detail-resp.xml.tpl
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<volumeAttachment device="/dev/sdd" serverId="%(uuid)s" id="a26887c6-c47b-4654-abb5-dfadf7d3f803" volumeId="a26887c6-c47b-4654-abb5-dfadf7d3f803"/>
diff --git a/nova/tests/integrated/test_api_samples.py b/nova/tests/integrated/test_api_samples.py
index d48ef5091..9fe2c6566 100644
--- a/nova/tests/integrated/test_api_samples.py
+++ b/nova/tests/integrated/test_api_samples.py
@@ -33,6 +33,7 @@ from nova.api.openstack.compute.contrib import fping
# Import extensions to pull in osapi_compute_extension CONF option used below.
from nova.cloudpipe import pipelib
from nova.compute import api as compute_api
+from nova.compute import manager as compute_manager
from nova import context
from nova import db
from nova.db.sqlalchemy import models
@@ -46,6 +47,7 @@ import nova.quota
from nova.scheduler import driver
from nova.servicegroup import api as service_group_api
from nova import test
+from nova.tests.api.openstack.compute.contrib import test_coverage_ext
from nova.tests.api.openstack.compute.contrib import test_fping
from nova.tests.api.openstack.compute.contrib import test_networks
from nova.tests.api.openstack.compute.contrib import test_services
@@ -57,6 +59,7 @@ from nova.tests.image import fake
from nova.tests.integrated import integrated_helpers
from nova.tests import utils as test_utils
from nova import utils
+from nova.volume import cinder
CONF = cfg.CONF
CONF.import_opt('allow_resize_to_same_host', 'nova.compute.api')
@@ -173,8 +176,18 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
ex_keys = sorted(expected.keys())
res_keys = sorted(result.keys())
if ex_keys != res_keys:
- raise NoMatch(_('Key mismatch:\n'
- '%(ex_keys)s\n%(res_keys)s') % locals())
+ ex_delta = []
+ res_delta = []
+ for key in ex_keys:
+ if key not in res_keys:
+ ex_delta.append(key)
+ for key in res_keys:
+ if key not in ex_keys:
+ res_delta.append(key)
+ raise NoMatch(_('Dictionary key mismatch:\n'
+ 'Extra key(s) in template:\n%(ex_delta)s\n'
+ 'Extra key(s) in response:\n%(res_delta)s\n')
+ % locals())
for key in ex_keys:
res = self._compare_result(subs, expected[key], result[key])
matched_value = res or matched_value
@@ -199,11 +212,11 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
error = []
if expected:
- error.append(_('Extra items in expected:'))
+ error.append(_('Extra list items in template:'))
error.extend([repr(o) for o in expected])
if extra:
- error.append(_('Extra items in result:'))
+ error.append(_('Extra list items in response:'))
error.extend([repr(o) for o in extra])
if error:
@@ -223,7 +236,8 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
match = re.match(expected, result)
if not match:
raise NoMatch(_('Values do not match:\n'
- '%(expected)s\n%(result)s') % locals())
+ 'Template: %(expected)s\nResponse: %(result)s')
+ % locals())
try:
matched_value = match.group('id')
except IndexError:
@@ -236,7 +250,8 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
result = result.strip()
if expected != result:
raise NoMatch(_('Values do not match:\n'
- '%(expected)s\n%(result)s') % locals())
+ 'Template: %(expected)s\nResponse: %(result)s')
+ % locals())
return matched_value
def _verify_something(self, subs, expected, data):
@@ -384,7 +399,6 @@ class ApiSamplesTrap(ApiSampleTestBase):
# removed) soon.
do_not_approve_additions = []
do_not_approve_additions.append('os-create-server-ext')
- do_not_approve_additions.append('os-volumes')
tests = self._get_extensions_tested()
extensions = self._get_extensions()
@@ -760,7 +774,7 @@ class CoverageExtJsonTests(ApiSampleTestBase):
self.stubs.Set(coverage_ext.CoverageController, '_check_coverage',
_fake_check_coverage)
- self.stubs.Set(coverage.coverage, 'xml_report', _fake_xml_report)
+ self.stubs.Set(coverage, 'coverage', test_coverage_ext.FakeCoverage)
def test_start_coverage(self):
# Start coverage data collection.
@@ -1591,9 +1605,6 @@ class CloudPipeUpdateJsonTest(ApiSampleTestBase):
'nova.api.openstack.compute.contrib.cloudpipe.Cloudpipe')
return f
- def setUp(self):
- super(CloudPipeUpdateJsonTest, self).setUp()
-
def test_cloud_pipe_update(self):
subs = {'vpn_ip': '192.168.1.1',
'vpn_port': 2000}
@@ -1868,9 +1879,6 @@ class CertificatesSamplesJsonTest(ApiSampleTestBase):
extension_name = ("nova.api.openstack.compute.contrib.certificates."
"Certificates")
- def setUp(self):
- super(CertificatesSamplesJsonTest, self).setUp()
-
def test_create_certificates(self):
response = self._do_post('os-certificates',
'certificate-create-req', {})
@@ -3593,3 +3601,277 @@ class AttachInterfacesSampleJsonTest(ServersSampleBase):
class AttachInterfacesSampleXmlTest(AttachInterfacesSampleJsonTest):
ctype = 'xml'
+
+
+class SnapshotsSampleJsonTests(ApiSampleTestBase):
+ extension_name = "nova.api.openstack.compute.contrib.volumes.Volumes"
+
+ create_subs = {
+ 'snapshot_name': 'snap-001',
+ 'description': 'Daily backup',
+ 'volume_id': '521752a6-acf6-4b2d-bc7a-119f9148cd8c'
+ }
+
+ def setUp(self):
+ super(SnapshotsSampleJsonTests, self).setUp()
+ self.stubs.Set(cinder.API, "get_all_snapshots",
+ fakes.stub_snapshot_get_all)
+ self.stubs.Set(cinder.API, "get_snapshot", fakes.stub_snapshot_get)
+
+ def _create_snapshot(self):
+ self.stubs.Set(cinder.API, "create_snapshot",
+ fakes.stub_snapshot_create)
+ self.stubs.Set(cinder.API, "get", fakes.stub_volume_get)
+
+ response = self._do_post("os-snapshots",
+ "snapshot-create-req",
+ self.create_subs)
+ return response
+
+ def test_snapshots_create(self):
+ response = self._create_snapshot()
+ self.assertEqual(response.status, 200)
+ self.create_subs.update(self._get_regexes())
+ return self._verify_response("snapshot-create-resp",
+ self.create_subs, response)
+
+ def test_snapshots_delete(self):
+ self.stubs.Set(cinder.API, "delete_snapshot",
+ fakes.stub_snapshot_delete)
+ self._create_snapshot()
+ response = self._do_delete('os-snapshots/100')
+ self.assertEqual(response.status, 202)
+ self.assertEqual(response.read(), '')
+
+ def test_snapshots_detail(self):
+ response = self._do_get('os-snapshots/detail')
+ self.assertEqual(response.status, 200)
+ subs = self._get_regexes()
+ return self._verify_response('snapshots-detail-resp',
+ subs, response)
+
+ def test_snapshots_list(self):
+ response = self._do_get('os-snapshots')
+ self.assertEqual(response.status, 200)
+ subs = self._get_regexes()
+ return self._verify_response('snapshots-list-resp',
+ subs, response)
+
+ def test_snapshots_show(self):
+ response = self._do_get('os-snapshots/100')
+ self.assertEqual(response.status, 200)
+ subs = {
+ 'snapshot_name': 'Default name',
+ 'description': 'Default description'
+ }
+ subs.update(self._get_regexes())
+ return self._verify_response('snapshots-show-resp',
+ subs, response)
+
+
+class SnapshotsSampleXmlTests(SnapshotsSampleJsonTests):
+ ctype = "xml"
+
+
+class VolumeAttachmentsSampleJsonTest(ServersSampleBase):
+ extension_name = ("nova.api.openstack.compute.contrib.volumes.Volumes")
+
+ def test_attach_volume_to_server(self):
+ device_name = '/dev/vdd'
+ self.stubs.Set(cinder.API, 'get', fakes.stub_volume_get)
+ self.stubs.Set(cinder.API, 'check_attach', lambda *a, **k: None)
+ self.stubs.Set(cinder.API, 'reserve_volume', lambda *a, **k: None)
+ self.stubs.Set(compute_manager.ComputeManager,
+ "reserve_block_device_name",
+ lambda *a, **k: device_name)
+
+ volume = fakes.stub_volume_get(None, context.get_admin_context(),
+ 'a26887c6-c47b-4654-abb5-dfadf7d3f803')
+ subs = {
+ 'volume_id': volume['id'],
+ 'device': device_name
+ }
+ server_id = self._post_server()
+ response = self._do_post('servers/%s/os-volume_attachments'
+ % server_id,
+ 'attach-volume-to-server-req', subs)
+
+ self.assertEqual(response.status, 200)
+ subs.update(self._get_regexes())
+ self._verify_response('attach-volume-to-server-resp',
+ subs, response)
+
+ def _stub_compute_api_get_instance_bdms(self, server_id):
+
+ def fake_compute_api_get_instance_bdms(self, context, instance):
+ bdms = [
+ {'volume_id': 'a26887c6-c47b-4654-abb5-dfadf7d3f803',
+ 'instance_uuid': server_id,
+ 'device_name': '/dev/sdd'},
+ {'volume_id': 'a26887c6-c47b-4654-abb5-dfadf7d3f804',
+ 'instance_uuid': server_id,
+ 'device_name': '/dev/sdc'}
+ ]
+ return bdms
+
+ self.stubs.Set(compute_api.API, "get_instance_bdms",
+ fake_compute_api_get_instance_bdms)
+
+ def _stub_compute_api_get(self):
+
+ def fake_compute_api_get(self, context, instance_id):
+ return {'uuid': instance_id}
+
+ self.stubs.Set(compute_api.API, 'get', fake_compute_api_get)
+
+ def test_list_volume_attachments(self):
+ server_id = self._post_server()
+
+ self._stub_compute_api_get_instance_bdms(server_id)
+
+ response = self._do_get('servers/%s/os-volume_attachments'
+ % server_id)
+ self.assertEqual(response.status, 200)
+ subs = self._get_regexes()
+ self._verify_response('list-volume-attachments-resp',
+ subs, response)
+
+ def test_volume_attachment_detail(self):
+ server_id = self._post_server()
+ attach_id = "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ self._stub_compute_api_get_instance_bdms(server_id)
+ self._stub_compute_api_get()
+ response = self._do_get('servers/%s/os-volume_attachments/%s'
+ % (server_id, attach_id))
+ self.assertEqual(response.status, 200)
+ subs = self._get_regexes()
+ self._verify_response('volume-attachment-detail-resp',
+ subs, response)
+
+ def test_volume_attachment_delete(self):
+ server_id = self._post_server()
+ attach_id = "a26887c6-c47b-4654-abb5-dfadf7d3f803"
+ self._stub_compute_api_get_instance_bdms(server_id)
+ self._stub_compute_api_get()
+ self.stubs.Set(compute_api.API, 'detach_volume', lambda *a, **k: None)
+ response = self._do_delete('servers/%s/os-volume_attachments/%s'
+ % (server_id, attach_id))
+ self.assertEqual(response.status, 202)
+ self.assertEqual(response.read(), '')
+
+
+class VolumeAttachmentsSampleXmlTest(VolumeAttachmentsSampleJsonTest):
+ ctype = 'xml'
+
+
+class VolumesSampleJsonTest(ServersSampleBase):
+ extension_name = ("nova.api.openstack.compute.contrib.volumes.Volumes")
+
+ def _get_volume_id(self):
+ return 'a26887c6-c47b-4654-abb5-dfadf7d3f803'
+
+ def _stub_volume(self, id, displayname="Volume Name",
+ displaydesc="Volume Description", size=100):
+ volume = {
+ 'id': id,
+ 'size': size,
+ 'availability_zone': 'zone1:host1',
+ 'instance_uuid': '3912f2b4-c5ba-4aec-9165-872876fe202e',
+ 'mountpoint': '/',
+ 'status': 'in-use',
+ 'attach_status': 'attached',
+ 'name': 'vol name',
+ 'display_name': displayname,
+ 'display_description': displaydesc,
+ 'created_at': "2008-12-01T11:01:55",
+ 'snapshot_id': None,
+ 'volume_type_id': 'fakevoltype',
+ 'volume_metadata': [],
+ 'volume_type': {'name': 'Backup'}
+ }
+ return volume
+
+ def _stub_volume_get(self, context, volume_id):
+ return self._stub_volume(volume_id)
+
+ def _stub_volume_delete(self, context, *args, **param):
+ pass
+
+ def _stub_volume_get_all(self, context, search_opts=None):
+ id = self._get_volume_id()
+ return [self._stub_volume(id)]
+
+ def _stub_volume_create(self, context, size, name, description, snapshot,
+ **param):
+ id = self._get_volume_id()
+ return self._stub_volume(id)
+
+ def setUp(self):
+ super(VolumesSampleJsonTest, self).setUp()
+ fakes.stub_out_networking(self.stubs)
+ fakes.stub_out_rate_limiting(self.stubs)
+
+ self.stubs.Set(cinder.API, "delete", self._stub_volume_delete)
+ self.stubs.Set(cinder.API, "get", self._stub_volume_get)
+ self.stubs.Set(cinder.API, "get_all", self._stub_volume_get_all)
+
+ def _post_volume(self):
+ subs_req = {
+ 'volume_name': "Volume Name",
+ 'volume_desc': "Volume Description",
+ }
+
+ self.stubs.Set(cinder.API, "create", self._stub_volume_create)
+ response = self._do_post('os-volumes', 'os-volumes-post-req',
+ subs_req)
+ self.assertEqual(response.status, 200)
+ subs = self._get_regexes()
+ subs.update(subs_req)
+ return self._verify_response('os-volumes-post-resp', subs, response)
+
+ def test_volumes_show(self):
+ subs = {
+ 'volume_name': "Volume Name",
+ 'volume_desc': "Volume Description",
+ }
+ vol_id = self._get_volume_id()
+ response = self._do_get('os-volumes/%s' % vol_id)
+ self.assertEqual(response.status, 200)
+ subs.update(self._get_regexes())
+ return self._verify_response('os-volumes-get-resp', subs, response)
+
+ def test_volumes_index(self):
+ subs = {
+ 'volume_name': "Volume Name",
+ 'volume_desc': "Volume Description",
+ }
+ response = self._do_get('os-volumes')
+ self.assertEqual(response.status, 200)
+ subs.update(self._get_regexes())
+ return self._verify_response('os-volumes-index-resp', subs, response)
+
+ def test_volumes_detail(self):
+ # For now, index and detail are the same.
+ # See the volumes api
+ subs = {
+ 'volume_name': "Volume Name",
+ 'volume_desc': "Volume Description",
+ }
+ response = self._do_get('os-volumes/detail')
+ self.assertEqual(response.status, 200)
+ subs.update(self._get_regexes())
+ return self._verify_response('os-volumes-detail-resp', subs, response)
+
+ def test_volumes_create(self):
+ return self._post_volume()
+
+ def test_volumes_delete(self):
+ self._post_volume()
+ vol_id = self._get_volume_id()
+ response = self._do_delete('os-volumes/%s' % vol_id)
+ self.assertEqual(response.status, 202)
+ self.assertEqual(response.read(), '')
+
+
+class VolumesSampleXmlTest(VolumesSampleJsonTest):
+ ctype = 'xml'
diff --git a/nova/tests/integrated/test_multiprocess_api.py b/nova/tests/integrated/test_multiprocess_api.py
index 91e37116d..c85a43a0c 100644
--- a/nova/tests/integrated/test_multiprocess_api.py
+++ b/nova/tests/integrated/test_multiprocess_api.py
@@ -1,5 +1,5 @@
# Copyright (c) 2012 Intel, LLC
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
#
# 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/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py
index 95c2da2a1..b45bd88f7 100644
--- a/nova/tests/integrated/test_servers.py
+++ b/nova/tests/integrated/test_servers.py
@@ -185,7 +185,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
def test_deferred_delete_restore(self):
# Creates, deletes and restores a server.
- self.flags(reclaim_instance_interval=1)
+ self.flags(reclaim_instance_interval=3600)
fake_network.set_stub_network_methods(self.stubs)
# Create server
@@ -218,7 +218,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
def test_deferred_delete_force(self):
# Creates, deletes and force deletes a server.
- self.flags(reclaim_instance_interval=1)
+ self.flags(reclaim_instance_interval=3600)
fake_network.set_stub_network_methods(self.stubs)
# Create server
diff --git a/nova/tests/monkey_patch_example/__init__.py b/nova/tests/monkey_patch_example/__init__.py
index 779dc72f3..8eaaf41a1 100644
--- a/nova/tests/monkey_patch_example/__init__.py
+++ b/nova/tests/monkey_patch_example/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/monkey_patch_example/example_a.py b/nova/tests/monkey_patch_example/example_a.py
index 21e79bcb0..ae852a406 100644
--- a/nova/tests/monkey_patch_example/example_a.py
+++ b/nova/tests/monkey_patch_example/example_a.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/monkey_patch_example/example_b.py b/nova/tests/monkey_patch_example/example_b.py
index 9d8f6d339..8a171834b 100644
--- a/nova/tests/monkey_patch_example/example_b.py
+++ b/nova/tests/monkey_patch_example/example_b.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/network/__init__.py b/nova/tests/network/__init__.py
index adc424847..34c7255d3 100644
--- a/nova/tests/network/__init__.py
+++ b/nova/tests/network/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/network/test_deprecated_api.py b/nova/tests/network/test_deprecated_api.py
new file mode 100644
index 000000000..48a7e4d6d
--- /dev/null
+++ b/nova/tests/network/test_deprecated_api.py
@@ -0,0 +1,80 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Openstack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Tests for the deprecated network API."""
+
+import inspect
+
+from nova.network import api
+from nova.network import api_deprecated
+from nova import test
+
+# NOTE(jkoelker) These tests require that decorators in the apis
+# "do the right thing" and set __name__ properly
+# they should all be using functools.wraps or similar
+# functionality.
+
+
+def isapimethod(obj):
+ if inspect.ismethod(obj) and not obj.__name__.startswith('_'):
+ return True
+ return False
+
+
+def discover_real_method(name, method):
+ if method.func_closure:
+ for closure in method.func_closure:
+ if closure.cell_contents.__name__ == name:
+ return closure.cell_contents
+ return method
+
+
+class DeprecatedApiTestCase(test.TestCase):
+ def setUp(self):
+ super(DeprecatedApiTestCase, self).setUp()
+ self.api = api.API()
+ self.api_deprecated = api_deprecated.API()
+
+ self.api_methods = inspect.getmembers(self.api, isapimethod)
+
+ def test_api_compat(self):
+ methods = [m[0] for m in self.api_methods]
+ deprecated_methods = [getattr(self.api_deprecated, n, None)
+ for n in methods]
+ missing = [m[0] for m in zip(methods, deprecated_methods)
+ if m[1] is None]
+
+ self.assertFalse(missing,
+ 'Deprecated api needs methods: %s' % missing)
+
+ def test_method_signatures(self):
+ for name, method in self.api_methods:
+ deprecated_method = getattr(self.api_deprecated, name, None)
+ self.assertIsNotNone(deprecated_method,
+ 'Deprecated api has no method %s' % name)
+
+ method = discover_real_method(name, method)
+ deprecated_method = discover_real_method(name,
+ deprecated_method)
+
+ api_argspec = inspect.getargspec(method)
+ deprecated_argspec = inspect.getargspec(deprecated_method)
+
+ # NOTE/TODO(jkoelker) Should probably handle the case where
+ # varargs/keywords are used.
+ self.assertEqual(api_argspec.args, deprecated_argspec.args,
+ "API method %s arguments differ" % name)
diff --git a/nova/tests/network/test_linux_net.py b/nova/tests/network/test_linux_net.py
index cba08d9ce..09b38f7a9 100644
--- a/nova/tests/network/test_linux_net.py
+++ b/nova/tests/network/test_linux_net.py
@@ -26,6 +26,7 @@ from nova import db
from nova.network import driver
from nova.network import linux_net
from nova.openstack.common import fileutils
+from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
from nova import test
@@ -496,7 +497,7 @@ class LinuxNetworkTestCase(test.TestCase):
dev = 'br100'
linux_net.restart_dhcp(self.context, dev, network_ref)
expected = ['env',
- 'CONFIG_FILE=%s' % CONF.dhcpbridge_flagfile,
+ 'CONFIG_FILE=%s' % jsonutils.dumps(CONF.dhcpbridge_flagfile),
'NETWORK_ID=fake',
'dnsmasq',
'--strict-order',
@@ -729,6 +730,19 @@ class LinuxNetworkTestCase(test.TestCase):
]
self._test_initialize_gateway(existing, expected)
+ def test_ensure_floating_no_duplicate_forwards(self):
+ ln = linux_net
+ self.stubs.Set(ln.iptables_manager, 'apply', lambda: None)
+ self.stubs.Set(ln, 'ensure_ebtables_rules', lambda *a, **kw: None)
+ net = {'bridge': 'br100', 'cidr': '10.0.0.0/24'}
+ ln.ensure_floating_forward('10.10.10.10', '10.0.0.1', 'eth0', net)
+ one_forward_rules = len(linux_net.iptables_manager.ipv4['nat'].rules)
+ ln.ensure_floating_forward('10.10.10.11', '10.0.0.10', 'eth0', net)
+ two_forward_rules = len(linux_net.iptables_manager.ipv4['nat'].rules)
+ ln.ensure_floating_forward('10.10.10.10', '10.0.0.3', 'eth0', net)
+ dup_forward_rules = len(linux_net.iptables_manager.ipv4['nat'].rules)
+ self.assertEqual(two_forward_rules, dup_forward_rules)
+
def test_apply_ran(self):
manager = linux_net.IptablesManager()
manager.iptables_apply_deferred = False
diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py
index ba997ac9d..92b8e1d91 100644
--- a/nova/tests/network/test_manager.py
+++ b/nova/tests/network/test_manager.py
@@ -29,7 +29,7 @@ from nova.network import floating_ips
from nova.network import linux_net
from nova.network import manager as network_manager
from nova.network import model as net_model
-from nova.openstack.common.db.sqlalchemy import session as db_session
+from nova.openstack.common.db import exception as db_exc
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common import rpc
@@ -2157,7 +2157,7 @@ class FloatingIPTestCase(test.TestCase):
# address column, so fake the collision-avoidance here
def fake_vif_save(vif):
if vif.address == crash_test_dummy_vif['address']:
- raise db_session.DBError("If you're smart, you'll retry!")
+ raise db_exc.DBError("If you're smart, you'll retry!")
self.stubs.Set(models.VirtualInterface, 'save', fake_vif_save)
# Attempt to add another and make sure that both MACs are consumed
diff --git a/nova/tests/network/test_network_info.py b/nova/tests/network/test_network_info.py
index d2ab6a746..021e6b5e6 100644
--- a/nova/tests/network/test_network_info.py
+++ b/nova/tests/network/test_network_info.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/network/test_quantumv2.py b/nova/tests/network/test_quantumv2.py
index e9e19ef45..167b418ad 100644
--- a/nova/tests/network/test_quantumv2.py
+++ b/nova/tests/network/test_quantumv2.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -227,6 +227,7 @@ class TestQuantumv2(test.TestCase):
'port_id': self.port_data2[1]['id'],
'fixed_ip_address': fixed_ip_address,
'router_id': 'router_id1'}
+ self._returned_nw_info = []
def tearDown(self):
self.addCleanup(CONF.reset)
@@ -457,13 +458,14 @@ class TestQuantumv2(test.TestCase):
api.get_instance_nw_info(mox.IgnoreArg(),
self.instance,
networks=nets,
- conductor_api=mox.IgnoreArg()).AndReturn(None)
+ conductor_api=mox.IgnoreArg()).AndReturn(
+ self._returned_nw_info)
self.mox.ReplayAll()
return api
def _allocate_for_instance(self, net_idx=1, **kwargs):
api = self._stub_allocate_for_instance(net_idx, **kwargs)
- api.allocate_for_instance(self.context, self.instance, **kwargs)
+ return api.allocate_for_instance(self.context, self.instance, **kwargs)
def test_allocate_for_instance_1(self):
# Allocate one port in one network env.
@@ -631,6 +633,29 @@ class TestQuantumv2(test.TestCase):
self.assertRaises(QUANTUM_CLIENT_EXCEPTION, api.allocate_for_instance,
self.context, self.instance)
+ def test_allocate_for_instance_no_port_or_network(self):
+ class BailOutEarly(Exception):
+ pass
+ api = quantumapi.API()
+ self.mox.StubOutWithMock(api, '_get_available_networks')
+ # Make sure we get an empty list and then bail out of the rest
+ # of the function
+ api._get_available_networks(self.context, self.instance['project_id'],
+ []).AndRaise(BailOutEarly)
+ self.mox.ReplayAll()
+ self.assertRaises(BailOutEarly,
+ api.allocate_for_instance,
+ self.context, self.instance,
+ requested_networks=[(None, None, None)])
+
+ def test_allocate_for_instance_second_time(self):
+ # Make sure that allocate_for_instance only returns ports that it
+ # allocated during _that_ run.
+ new_port = {'id': 'fake'}
+ self._returned_nw_info = self.port_data1 + [new_port]
+ nw_info = self._allocate_for_instance()
+ self.assertEqual(nw_info, [new_port])
+
def _deallocate_for_instance(self, number):
port_data = number == 1 and self.port_data1 or self.port_data2
self.moxed_client.list_ports(
diff --git a/nova/tests/scheduler/__init__.py b/nova/tests/scheduler/__init__.py
index 7e04e7c73..4c506c9fa 100644
--- a/nova/tests/scheduler/__init__.py
+++ b/nova/tests/scheduler/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/scheduler/fakes.py b/nova/tests/scheduler/fakes.py
index 652893662..4e4ab7c37 100644
--- a/nova/tests/scheduler/fakes.py
+++ b/nova/tests/scheduler/fakes.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/scheduler/test_chance_scheduler.py b/nova/tests/scheduler/test_chance_scheduler.py
index 0ee617044..d2de055b5 100644
--- a/nova/tests/scheduler/test_chance_scheduler.py
+++ b/nova/tests/scheduler/test_chance_scheduler.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/scheduler/test_filter_scheduler.py b/nova/tests/scheduler/test_filter_scheduler.py
index 849f63f5d..5256dc35f 100644
--- a/nova/tests/scheduler/test_filter_scheduler.py
+++ b/nova/tests/scheduler/test_filter_scheduler.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py
index 8fe998daa..c977871d5 100644
--- a/nova/tests/scheduler/test_host_filters.py
+++ b/nova/tests/scheduler/test_host_filters.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC. # All Rights Reserved.
+# Copyright 2011 OpenStack Foundation # All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
diff --git a/nova/tests/scheduler/test_host_manager.py b/nova/tests/scheduler/test_host_manager.py
index 088aa4da9..ddc9bd29a 100644
--- a/nova/tests/scheduler/test_host_manager.py
+++ b/nova/tests/scheduler/test_host_manager.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 OpenStack, LLC
+# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/scheduler/test_least_cost.py b/nova/tests/scheduler/test_least_cost.py
index d920b7255..8cee3b4d7 100644
--- a/nova/tests/scheduler/test_least_cost.py
+++ b/nova/tests/scheduler/test_least_cost.py
@@ -1,4 +1,4 @@
-# Copyright 2011-2012 OpenStack LLC.
+# Copyright 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/scheduler/test_multi_scheduler.py b/nova/tests/scheduler/test_multi_scheduler.py
index 17e3331ed..fb25ae9da 100644
--- a/nova/tests/scheduler/test_multi_scheduler.py
+++ b/nova/tests/scheduler/test_multi_scheduler.py
@@ -2,7 +2,7 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py
index 5d0228c62..4e95061a7 100644
--- a/nova/tests/scheduler/test_scheduler.py
+++ b/nova/tests/scheduler/test_scheduler.py
@@ -403,6 +403,7 @@ class SchedulerTestCase(test.TestCase):
'vm_state': '',
'task_state': '',
'instance_type': {'memory_mb': 1024},
+ 'instance_type_id': 1,
'image_ref': 'fake-image-ref'}
def test_live_migration_basic(self):
@@ -736,6 +737,7 @@ class SchedulerTestCase(test.TestCase):
def test_live_migration_dest_check_auto_set_host(self):
# Confirm dest is picked by scheduler if not set.
self.mox.StubOutWithMock(self.driver, 'select_hosts')
+ self.mox.StubOutWithMock(db, 'instance_type_get')
instance = self._live_migration_instance()
request_spec = {'instance_properties': instance,
@@ -747,6 +749,8 @@ class SchedulerTestCase(test.TestCase):
ignore_hosts = [instance['host']]
filter_properties = {'ignore_hosts': ignore_hosts}
+ db.instance_type_get(self.context, 1).AndReturn(
+ instance['instance_type'])
self.driver.select_hosts(self.context, request_spec,
filter_properties).AndReturn(['fake_host2'])
@@ -757,6 +761,7 @@ class SchedulerTestCase(test.TestCase):
def test_live_migration_auto_set_dest(self):
# Confirm scheduler picks target host if none given.
+ self.mox.StubOutWithMock(db, 'instance_type_get')
self.mox.StubOutWithMock(self.driver, '_live_migration_src_check')
self.mox.StubOutWithMock(self.driver, 'select_hosts')
self.mox.StubOutWithMock(self.driver, '_live_migration_common_check')
@@ -776,6 +781,9 @@ class SchedulerTestCase(test.TestCase):
self.driver._live_migration_src_check(self.context, instance)
+ db.instance_type_get(self.context, 1).MultipleTimes().AndReturn(
+ instance['instance_type'])
+
# First selected host raises exception.InvalidHypervisorType
self.driver.select_hosts(self.context, request_spec,
{'ignore_hosts': [instance['host']]}).AndReturn(['fake_host2'])
diff --git a/nova/tests/scheduler/test_scheduler_options.py b/nova/tests/scheduler/test_scheduler_options.py
index 17c1bb731..df54cde5f 100644
--- a/nova/tests/scheduler/test_scheduler_options.py
+++ b/nova/tests/scheduler/test_scheduler_options.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/scheduler/test_weights.py b/nova/tests/scheduler/test_weights.py
index 8699ed811..3ea6c945f 100644
--- a/nova/tests/scheduler/test_weights.py
+++ b/nova/tests/scheduler/test_weights.py
@@ -1,4 +1,4 @@
-# Copyright 2011-2012 OpenStack LLC.
+# Copyright 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/servicegroup/__init__.py b/nova/tests/servicegroup/__init__.py
index 4549abf92..efbc9063d 100644
--- a/nova/tests/servicegroup/__init__.py
+++ b/nova/tests/servicegroup/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC
+# Copyright 2012 OpenStack Foundation
#
# 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/tests/servicegroup/test_db_servicegroup.py b/nova/tests/servicegroup/test_db_servicegroup.py
index d14427439..a7ab3ff6f 100644
--- a/nova/tests/servicegroup/test_db_servicegroup.py
+++ b/nova/tests/servicegroup/test_db_servicegroup.py
@@ -1,4 +1,4 @@
-# Copyright (c) IBM 2012 Alexey Roytman <roytman at il dot ibm dot com>
+# Copyright 2012 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
diff --git a/nova/tests/servicegroup/test_mc_servicegroup.py b/nova/tests/servicegroup/test_mc_servicegroup.py
index 255184219..9d5601ff8 100644
--- a/nova/tests/servicegroup/test_mc_servicegroup.py
+++ b/nova/tests/servicegroup/test_mc_servicegroup.py
@@ -1,7 +1,7 @@
# Copyright (c) 2013 Akira Yoshiyama <akirayoshiyama at gmail dot com>
#
# This is derived from test_db_servicegroup.py.
-# Copyright (c) IBM 2012 Alexey Roytman <roytman at il dot ibm dot com>
+# Copyright 2012 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
diff --git a/nova/tests/servicegroup/test_zk_driver.py b/nova/tests/servicegroup/test_zk_driver.py
index 7330da66a..cdb919307 100644
--- a/nova/tests/servicegroup/test_zk_driver.py
+++ b/nova/tests/servicegroup/test_zk_driver.py
@@ -1,5 +1,5 @@
# Copyright (c) AT&T 2012-2013 Yun Mao <yunmao@gmail.com>
-# Copyright (c) IBM 2012 Alexey Roytman <roytman at il dot ibm dot com>.
+# Copyright 2012 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
@@ -38,7 +38,7 @@ class ZKServiceGroupTestCase(test.TestCase):
servicegroup.API._driver = None
try:
from nova.servicegroup.drivers import zk
- _unused = zk
+ _unused = zk.ZooKeeperDriver()
except ImportError:
self.skipTest("Unable to test due to lack of ZooKeeper")
self.flags(servicegroup_driver='zk')
diff --git a/nova/tests/test_cinder.py b/nova/tests/test_cinder.py
index 79b5ae66a..06eb467ab 100644
--- a/nova/tests/test_cinder.py
+++ b/nova/tests/test_cinder.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/test_context.py b/nova/tests/test_context.py
index 527534fd5..99b5c705c 100644
--- a/nova/tests/test_context.py
+++ b/nova/tests/test_context.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/test_crypto.py b/nova/tests/test_crypto.py
index cec3ca9c1..e328babfe 100644
--- a/nova/tests/test_crypto.py
+++ b/nova/tests/test_crypto.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
index 346e0b2b7..769ddaea2 100644
--- a/nova/tests/test_db_api.py
+++ b/nova/tests/test_db_api.py
@@ -451,41 +451,6 @@ class DbApiTestCase(test.TestCase):
self.assertEquals("building", old_ref["vm_state"])
self.assertEquals("needscoffee", new_ref["vm_state"])
- def test_instance_update_with_extra_specs(self):
- # Ensure _extra_specs are returned from _instance_update.
- ctxt = context.get_admin_context()
-
- # create a flavor
- inst_type_dict = dict(
- name="test_flavor",
- memory_mb=1,
- vcpus=1,
- root_gb=1,
- ephemeral_gb=1,
- flavorid=105)
- inst_type_ref = db.instance_type_create(ctxt, inst_type_dict)
-
- # add some extra spec to our flavor
- spec = {'test_spec': 'foo'}
- db.instance_type_extra_specs_update_or_create(
- ctxt,
- inst_type_ref['flavorid'],
- spec)
-
- # create instance, just populates db, doesn't pull extra_spec
- instance = db.instance_create(
- ctxt,
- {'instance_type_id': inst_type_ref['id']})
- self.assertNotIn('extra_specs', instance)
-
- # update instance, used when starting instance to set state, etc
- (old_ref, new_ref) = db.instance_update_and_get_original(
- ctxt,
- instance['uuid'],
- {})
- self.assertEquals(spec, old_ref['extra_specs'])
- self.assertEquals(spec, new_ref['extra_specs'])
-
def _test_instance_update_updates_metadata(self, metadata_type):
ctxt = context.get_admin_context()
@@ -734,7 +699,7 @@ class DbApiTestCase(test.TestCase):
self.assertEqual('schedule', events[0]['event'])
self.assertEqual(start_time, events[0]['start_time'])
- def test_instance_action_event_finish(self):
+ def test_instance_action_event_finish_success(self):
"""Finish an instance action event."""
ctxt = context.get_admin_context()
uuid = str(stdlib_uuid.uuid4())
@@ -758,15 +723,55 @@ class DbApiTestCase(test.TestCase):
event_finish_values = {'event': 'schedule',
'request_id': ctxt.request_id,
'instance_uuid': uuid,
- 'finish_time': finish_time}
+ 'finish_time': finish_time,
+ 'result': 'Success'}
+ db.action_event_finish(ctxt, event_finish_values)
+
+ # Retrieve the event to ensure it was successfully added
+ events = db.action_events_get(ctxt, action['id'])
+ action = db.action_get_by_request_id(ctxt, uuid, ctxt.request_id)
+ self.assertEqual(1, len(events))
+ self.assertEqual('schedule', events[0]['event'])
+ self.assertEqual(start_time, events[0]['start_time'])
+ self.assertEqual(finish_time, events[0]['finish_time'])
+ self.assertNotEqual(action['message'], 'Error')
+
+ def test_instance_action_event_finish_error(self):
+ """Finish an instance action event with an error."""
+ ctxt = context.get_admin_context()
+ uuid = str(stdlib_uuid.uuid4())
+
+ start_time = timeutils.utcnow()
+ action_values = {'action': 'run_instance',
+ 'instance_uuid': uuid,
+ 'request_id': ctxt.request_id,
+ 'user_id': ctxt.user_id,
+ 'project_id': ctxt.project_id,
+ 'start_time': start_time}
+ action = db.action_start(ctxt, action_values)
+
+ event_values = {'event': 'schedule',
+ 'request_id': ctxt.request_id,
+ 'instance_uuid': uuid,
+ 'start_time': start_time}
+ db.action_event_start(ctxt, event_values)
+
+ finish_time = timeutils.utcnow() + datetime.timedelta(seconds=5)
+ event_finish_values = {'event': 'schedule',
+ 'request_id': ctxt.request_id,
+ 'instance_uuid': uuid,
+ 'finish_time': finish_time,
+ 'result': 'Error'}
db.action_event_finish(ctxt, event_finish_values)
# Retrieve the event to ensure it was successfully added
events = db.action_events_get(ctxt, action['id'])
+ action = db.action_get_by_request_id(ctxt, uuid, ctxt.request_id)
self.assertEqual(1, len(events))
self.assertEqual('schedule', events[0]['event'])
self.assertEqual(start_time, events[0]['start_time'])
self.assertEqual(finish_time, events[0]['finish_time'])
+ self.assertEqual(action['message'], 'Error')
def test_instance_action_and_event_start_string_time(self):
"""Create an instance action and event with a string start_time."""
diff --git a/nova/tests/test_driver.py b/nova/tests/test_driver.py
index 2dee7725f..6fd8b00b1 100644
--- a/nova/tests/test_driver.py
+++ b/nova/tests/test_driver.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2013 Citrix Systems, Inc.
-# Copyright 2013 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation
#
# 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/tests/test_exception.py b/nova/tests/test_exception.py
index ad67cff26..6f5a9909e 100644
--- a/nova/tests/test_exception.py
+++ b/nova/tests/test_exception.py
@@ -133,3 +133,10 @@ class NovaExceptionTestCase(test.TestCase):
exc = FakeNovaException(code=404)
self.assertEquals(exc.kwargs['code'], 404)
+
+ def test_cleanse_dict(self):
+ kwargs = {'foo': 1, 'blah_pass': 2, 'zoo_password': 3, '_pass': 4}
+ self.assertEquals(exception._cleanse_dict(kwargs), {'foo': 1})
+
+ kwargs = {}
+ self.assertEquals(exception._cleanse_dict(kwargs), {})
diff --git a/nova/tests/test_fakelibvirt.py b/nova/tests/test_fakelibvirt.py
index 32c85a95a..ee2008544 100644
--- a/nova/tests/test_fakelibvirt.py
+++ b/nova/tests/test_fakelibvirt.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2010 OpenStack LLC
+# Copyright 2010 OpenStack Foundation
#
# 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/tests/test_filters.py b/nova/tests/test_filters.py
index 13fd122c8..d20836168 100644
--- a/nova/tests/test_filters.py
+++ b/nova/tests/test_filters.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC. # All Rights Reserved.
+# Copyright 2012 OpenStack Foundation # All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
diff --git a/nova/tests/test_hooks.py b/nova/tests/test_hooks.py
index 0b61d6924..1f4625294 100644
--- a/nova/tests/test_hooks.py
+++ b/nova/tests/test_hooks.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/test_hypervapi.py b/nova/tests/test_hypervapi.py
index 5912bb301..c6d75aea1 100644
--- a/nova/tests/test_hypervapi.py
+++ b/nova/tests/test_hypervapi.py
@@ -56,7 +56,7 @@ from nova.virt.hyperv import volumeutilsv2
from nova.virt import images
CONF = cfg.CONF
-CONF.import_opt('vswitch_name', 'nova.virt.hyperv.vif')
+CONF.import_opt('vswitch_name', 'nova.virt.hyperv.vif', 'hyperv')
class HyperVAPITestCase(test.TestCase):
@@ -86,9 +86,11 @@ class HyperVAPITestCase(test.TestCase):
self._setup_stubs()
self.flags(instances_path=r'C:\Hyper-V\test\instances',
- vswitch_name='external',
- network_api_class='nova.network.quantumv2.api.API',
- force_volumeutils_v1=True)
+ network_api_class='nova.network.quantumv2.api.API')
+
+ self.flags(vswitch_name='external',
+ force_volumeutils_v1=True,
+ group='hyperv')
self._conn = driver_hyperv.HyperVDriver(None)
@@ -154,6 +156,8 @@ class HyperVAPITestCase(test.TestCase):
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'merge_vhd')
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'get_vhd_parent_path')
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'get_vhd_info')
+ self._mox.StubOutWithMock(vhdutils.VHDUtils, 'resize_vhd')
+ self._mox.StubOutWithMock(vhdutils.VHDUtils, 'validate_vhd')
self._mox.StubOutWithMock(hostutils.HostUtils, 'get_cpus_info')
self._mox.StubOutWithMock(hostutils.HostUtils,
@@ -331,7 +335,7 @@ class HyperVAPITestCase(test.TestCase):
cdb.__exit__(None, None, None).AndReturn(None)
if not use_cdrom:
- utils.execute(CONF.qemu_img_cmd,
+ utils.execute(CONF.hyperv.qemu_img_cmd,
'convert',
'-f',
'raw',
@@ -351,7 +355,7 @@ class HyperVAPITestCase(test.TestCase):
def _test_spawn_config_drive(self, use_cdrom):
self.flags(force_config_drive=True)
- self.flags(config_drive_cdrom=use_cdrom)
+ self.flags(config_drive_cdrom=use_cdrom, group='hyperv')
self.flags(mkisofs_cmd='mkisofs.exe')
self._setup_spawn_config_drive_mocks(use_cdrom)
@@ -391,7 +395,7 @@ class HyperVAPITestCase(test.TestCase):
fake_vswitch_port = 'fake port'
m = networkutils.NetworkUtils.get_external_vswitch(
- CONF.vswitch_name)
+ CONF.hyperv.vswitch_name)
m.AndReturn(fake_vswitch_path)
m = networkutils.NetworkUtils.create_vswitch_port(
@@ -410,7 +414,7 @@ class HyperVAPITestCase(test.TestCase):
def setup_vif_mocks():
m = networkutils.NetworkUtils.get_external_vswitch(
- CONF.vswitch_name)
+ CONF.hyperv.vswitch_name)
m.AndRaise(vmutils.HyperVException(_('fake vswitch not found')))
self.assertRaises(vmutils.HyperVException, self._test_spawn_instance,
@@ -516,7 +520,7 @@ class HyperVAPITestCase(test.TestCase):
self._setup_destroy_mocks()
self._mox.ReplayAll()
- self._conn.destroy(self._instance_data)
+ self._conn.destroy(self._instance_data, None)
self._mox.VerifyAll()
def test_live_migration(self):
@@ -567,6 +571,8 @@ class HyperVAPITestCase(test.TestCase):
self.flags(use_cow_images=cow)
instance_data = self._get_instance_data()
+ instance = db.instance_create(self._context, instance_data)
+ instance['system_metadata'] = {}
network_info = fake_network.fake_get_instance_nw_info(self.stubs,
spectacular=True)
@@ -579,10 +585,14 @@ class HyperVAPITestCase(test.TestCase):
None)
m.AndReturn(False)
- vhdutils.VHDUtils.get_vhd_info(mox.Func(self._check_img_path))
+ m = vhdutils.VHDUtils.get_vhd_info(mox.Func(self._check_img_path))
+ m.AndReturn({'MaxInternalSize': 1024})
+
+ fake.PathUtils.copyfile(mox.IsA(str), mox.IsA(str))
+ vhdutils.VHDUtils.resize_vhd(mox.IsA(str), mox.IsA(object))
self._mox.ReplayAll()
- self._conn.pre_live_migration(self._context, instance_data,
+ self._conn.pre_live_migration(self._context, instance,
None, network_info)
self._mox.VerifyAll()
@@ -697,6 +707,7 @@ class HyperVAPITestCase(test.TestCase):
self._instance_data = self._get_instance_data()
instance = db.instance_create(self._context, self._instance_data)
+ instance['system_metadata'] = {}
image = db_fakes.get_fake_image_data(self._project_id, self._user_id)
@@ -763,12 +774,16 @@ class HyperVAPITestCase(test.TestCase):
m.AndReturn(boot_from_volume)
if not boot_from_volume:
- vhdutils.VHDUtils.get_vhd_info(mox.Func(self._check_img_path))
+ m = vhdutils.VHDUtils.get_vhd_info(mox.Func(self._check_img_path))
+ m.AndReturn({'MaxInternalSize': 1024})
if cow:
- vhdutils.VHDUtils.create_differencing_vhd(
- mox.IsA(str), mox.Func(self._check_img_path))
+ fake.PathUtils.copyfile(mox.IsA(str), mox.IsA(str))
+ vhdutils.VHDUtils.resize_vhd(mox.IsA(str), mox.IsA(object))
+ vhdutils.VHDUtils.create_differencing_vhd(mox.IsA(str),
+ mox.IsA(str))
else:
+ vhdutils.VHDUtils.resize_vhd(mox.IsA(str), mox.IsA(object))
fake.PathUtils.copyfile(mox.IsA(str), mox.IsA(str))
self._setup_create_instance_mocks(setup_vif_mocks_func,
@@ -1009,6 +1024,7 @@ class HyperVAPITestCase(test.TestCase):
def test_finish_migration(self):
self._instance_data = self._get_instance_data()
instance = db.instance_create(self._context, self._instance_data)
+ instance['system_metadata'] = {}
network_info = fake_network.fake_get_instance_nw_info(
self.stubs, spectacular=True)
@@ -1032,6 +1048,12 @@ class HyperVAPITestCase(test.TestCase):
vhdutils.VHDUtils.reconnect_parent_vhd(mox.IsA(str), mox.IsA(str))
+ m = vhdutils.VHDUtils.get_vhd_info(mox.IsA(str))
+ m.AndReturn({'MaxInternalSize': 1024})
+
+ m = fake.PathUtils.exists(mox.IsA(str))
+ m.AndReturn(True)
+
self._set_vm_name(instance['name'])
self._setup_create_instance_mocks(None, False)
diff --git a/nova/tests/test_iptables_network.py b/nova/tests/test_iptables_network.py
index 7e62d3a6e..e64dcf66b 100644
--- a/nova/tests/test_iptables_network.py
+++ b/nova/tests/test_iptables_network.py
@@ -68,19 +68,19 @@ class IptablesManagerTestCase(test.TestCase):
':OUTPUT ACCEPT [63491:4191863]',
':POSTROUTING ACCEPT [63112:4108641]',
':%s-OUTPUT - [0:0]' % (binary_name),
- ':%s-float-snat - [0:0]' % (binary_name),
':%s-snat - [0:0]' % (binary_name),
':%s-PREROUTING - [0:0]' % (binary_name),
+ ':%s-float-snat - [0:0]' % (binary_name),
':%s-POSTROUTING - [0:0]' % (binary_name),
':nova-postrouting-bottom - [0:0]',
'[0:0] -A PREROUTING -j %s-PREROUTING' % (binary_name),
'[0:0] -A OUTPUT -j %s-OUTPUT' % (binary_name),
'[0:0] -A POSTROUTING -j %s-POSTROUTING' % (binary_name),
- '[0:0] -A POSTROUTING -j nova-postrouting-bottom',
'[0:0] -A nova-postrouting-bottom '
- '-j %s-SNATTING' % (binary_name),
- '[0:0] -A %s-SNATTING '
- '-j %s-floating-ip-snat' % (binary_name, binary_name),
+ '-j %s-snat' % (binary_name),
+ '[0:0] -A %s-snat '
+ '-j %s-float-snat' % (binary_name, binary_name),
+ '[0:0] -A POSTROUTING -j nova-postrouting-bottom',
'COMMIT',
'# Completed on Fri Feb 18 15:17:05 2011']
@@ -103,6 +103,33 @@ class IptablesManagerTestCase(test.TestCase):
'-s 1.2.3.4/5 -j DROP' % self.binary_name
not in new_lines)
+ def test_remove_rules_regex(self):
+ current_lines = self.sample_nat
+ table = self.manager.ipv4['nat']
+ table.add_rule('float-snat', '-s 10.0.0.1 -j SNAT --to 10.10.10.10'
+ ' -d 10.0.0.1')
+ table.add_rule('float-snat', '-s 10.0.0.1 -j SNAT --to 10.10.10.10'
+ ' -o eth0')
+ table.add_rule('PREROUTING', '-d 10.10.10.10 -j DNAT --to 10.0.0.1')
+ table.add_rule('OUTPUT', '-d 10.10.10.10 -j DNAT --to 10.0.0.1')
+ table.add_rule('float-snat', '-s 10.0.0.10 -j SNAT --to 10.10.10.11'
+ ' -d 10.0.0.10')
+ table.add_rule('float-snat', '-s 10.0.0.10 -j SNAT --to 10.10.10.11'
+ ' -o eth0')
+ table.add_rule('PREROUTING', '-d 10.10.10.11 -j DNAT --to 10.0.0.10')
+ table.add_rule('OUTPUT', '-d 10.10.10.11 -j DNAT --to 10.0.0.10')
+ new_lines = self.manager._modify_rules(current_lines, table)
+ self.assertEqual(len(new_lines) - len(current_lines), 8)
+ regex = '.*\s+%s(/32|\s+|$)'
+ num_removed = table.remove_rules_regex(regex % '10.10.10.10')
+ self.assertEqual(num_removed, 4)
+ new_lines = self.manager._modify_rules(current_lines, table)
+ self.assertEqual(len(new_lines) - len(current_lines), 4)
+ num_removed = table.remove_rules_regex(regex % '10.10.10.11')
+ self.assertEqual(num_removed, 4)
+ new_lines = self.manager._modify_rules(current_lines, table)
+ self.assertEqual(new_lines, current_lines)
+
def test_nat_rules(self):
current_lines = self.sample_nat
new_lines = self.manager._modify_rules(current_lines,
diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py
index b16855eb4..df3d34c1f 100644
--- a/nova/tests/test_ipv6.py
+++ b/nova/tests/test_ipv6.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack LLC
+# Copyright (c) 2011 OpenStack Foundation
#
# 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/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index cad556851..2b405152e 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2010 OpenStack LLC
+# Copyright 2010 OpenStack Foundation
# Copyright 2012 University Of Minho
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -171,9 +171,6 @@ class CacheConcurrencyTestCase(test.TestCase):
'nova.virt.libvirt.imagebackend.libvirt_utils',
fake_libvirt_utils))
- def tearDown(self):
- super(CacheConcurrencyTestCase, self).tearDown()
-
def test_same_fname_concurrency(self):
# Ensures that the same fname cache runs at a sequentially.
uuid = uuidutils.generate_uuid()
@@ -3948,8 +3945,10 @@ class IptablesFirewallTestCase(test.TestCase):
ipv6 = self.fw.iptables.ipv6['filter'].rules
ipv4_network_rules = len(ipv4) - len(inst_ipv4) - ipv4_len
ipv6_network_rules = len(ipv6) - len(inst_ipv6) - ipv6_len
- self.assertEquals(ipv4_network_rules,
- ipv4_rules_per_addr * ipv4_addr_per_network * networks_count)
+ # Extra rules are for the DHCP request
+ rules = (ipv4_rules_per_addr * ipv4_addr_per_network *
+ networks_count) + 2
+ self.assertEquals(ipv4_network_rules, rules)
self.assertEquals(ipv6_network_rules,
ipv6_rules_per_addr * ipv6_addr_per_network * networks_count)
@@ -4840,6 +4839,53 @@ class LibvirtDriverTestCase(test.TestCase):
self.libvirtconnection.finish_revert_migration(ins_ref, None)
+ def _test_finish_revert_migration_after_crash(self, backup_made, new_made):
+ class FakeLoopingCall:
+ def start(self, *a, **k):
+ return self
+
+ def wait(self):
+ return None
+
+ self.mox.StubOutWithMock(libvirt_utils, 'get_instance_path')
+ self.mox.StubOutWithMock(os.path, 'exists')
+ self.mox.StubOutWithMock(shutil, 'rmtree')
+ self.mox.StubOutWithMock(utils, 'execute')
+
+ self.stubs.Set(blockinfo, 'get_disk_info', lambda *a: None)
+ self.stubs.Set(self.libvirtconnection, 'to_xml', lambda *a, **k: None)
+ self.stubs.Set(self.libvirtconnection, '_create_domain_and_network',
+ lambda *a: None)
+ self.stubs.Set(utils, 'FixedIntervalLoopingCall',
+ lambda *a, **k: FakeLoopingCall())
+
+ libvirt_utils.get_instance_path({}).AndReturn('/fake/foo')
+ os.path.exists('/fake/foo_resize').AndReturn(backup_made)
+ if backup_made:
+ os.path.exists('/fake/foo').AndReturn(new_made)
+ if new_made:
+ shutil.rmtree('/fake/foo')
+ utils.execute('mv', '/fake/foo_resize', '/fake/foo')
+
+ self.mox.ReplayAll()
+
+ self.libvirtconnection.finish_revert_migration({}, [])
+
+ def test_finish_revert_migration_after_crash(self):
+ self._test_finish_revert_migration_after_crash(True, True)
+
+ def test_finish_revert_migration_after_crash_before_new(self):
+ self._test_finish_revert_migration_after_crash(True, False)
+
+ def test_finish_revert_migration_after_crash_before_backup(self):
+ self._test_finish_revert_migration_after_crash(False, False)
+
+ def test_cleanup_failed_migration(self):
+ self.mox.StubOutWithMock(shutil, 'rmtree')
+ shutil.rmtree('/fake/inst')
+ self.mox.ReplayAll()
+ self.libvirtconnection._cleanup_failed_migration('/fake/inst')
+
def test_confirm_migration(self):
ins_ref = self._create_instance()
diff --git a/nova/tests/test_libvirt_blockinfo.py b/nova/tests/test_libvirt_blockinfo.py
index 5560e63fd..0165d77b6 100644
--- a/nova/tests/test_libvirt_blockinfo.py
+++ b/nova/tests/test_libvirt_blockinfo.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2010 OpenStack LLC
+# Copyright 2010 OpenStack Foundation
# Copyright 2012 University Of Minho
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -419,13 +419,13 @@ class LibvirtBlockInfoTest(test.TestCase):
device_type='cdrom')
self.assertEqual(bus, 'ide')
- image_meta = {'properties': {'disk_bus': 'scsi'}}
+ image_meta = {'properties': {'hw_disk_bus': 'scsi'}}
bus = blockinfo.get_disk_bus_for_device_type('kvm',
image_meta)
self.assertEqual(bus, 'scsi')
- image_meta = {'properties': {'disk_bus': 'usb',
- 'cdrom_bus': 'scsi'}}
+ image_meta = {'properties': {'hw_disk_bus': 'usb',
+ 'hw_cdrom_bus': 'scsi'}}
bus = blockinfo.get_disk_bus_for_device_type('kvm',
image_meta,
device_type='cdrom')
@@ -435,7 +435,7 @@ class LibvirtBlockInfoTest(test.TestCase):
image_meta)
self.assertEqual(bus, 'usb')
- image_meta = {'properties': {'disk_bus': 'xen'}}
+ image_meta = {'properties': {'hw_disk_bus': 'xen'}}
self.assertRaises(exception.UnsupportedHardware,
blockinfo.get_disk_bus_for_device_type,
'kvm',
diff --git a/nova/tests/test_libvirt_vif.py b/nova/tests/test_libvirt_vif.py
index 026e55e9c..6160105ce 100644
--- a/nova/tests/test_libvirt_vif.py
+++ b/nova/tests/test_libvirt_vif.py
@@ -277,7 +277,7 @@ class LibvirtVifTestCase(test.TestCase):
return fakelibvirt.Connection("qemu:///session",
False)
d = vif.LibvirtGenericVIFDriver(get_connection)
- image_meta = {'properties': {'vif_model': 'e1000'}}
+ image_meta = {'properties': {'hw_vif_model': 'e1000'}}
xml = self._get_instance_xml(d,
self.net_bridge,
self.mapping_bridge,
@@ -301,7 +301,7 @@ class LibvirtVifTestCase(test.TestCase):
return fakelibvirt.Connection("qemu:///session",
False)
d = vif.LibvirtGenericVIFDriver(get_connection)
- image_meta = {'properties': {'vif_model': 'acme'}}
+ image_meta = {'properties': {'hw_vif_model': 'acme'}}
self.assertRaises(exception.UnsupportedHardware,
self._get_instance_xml,
d,
diff --git a/nova/tests/test_libvirt_volume.py b/nova/tests/test_libvirt_volume.py
index 28d0c8088..1186ed268 100644
--- a/nova/tests/test_libvirt_volume.py
+++ b/nova/tests/test_libvirt_volume.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2010 OpenStack LLC
+# Copyright 2010 OpenStack Foundation
# Copyright 2012 University Of Minho
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/test_loadables.py b/nova/tests/test_loadables.py
index 6d16b9fa8..6b7a96a65 100644
--- a/nova/tests/test_loadables.py
+++ b/nova/tests/test_loadables.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC. # All Rights Reserved.
+# Copyright 2012 OpenStack Foundation # All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
diff --git a/nova/tests/test_migrations.py b/nova/tests/test_migrations.py
index 7c75a64ea..cf5c2f509 100644
--- a/nova/tests/test_migrations.py
+++ b/nova/tests/test_migrations.py
@@ -1,6 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack, LLC
+# Copyright 2010-2011 OpenStack Foundation
+# Copyright 2012-2013 IBM Corp.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -44,16 +45,19 @@ import collections
import commands
import ConfigParser
import datetime
-import netaddr
import os
-import sqlalchemy
-import sqlalchemy.exc
import urlparse
import uuid
from migrate.versioning import repository
+import netaddr
+import sqlalchemy
+from sqlalchemy.dialects import postgresql
+from sqlalchemy.dialects import sqlite
+import sqlalchemy.exc
import nova.db.sqlalchemy.migrate_repo
+from nova.openstack.common import lockutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
from nova import test
@@ -244,11 +248,36 @@ class BaseMigrationTestCase(test.TestCase):
self._reset_databases()
super(BaseMigrationTestCase, self).tearDown()
+ def execute_cmd(self, cmd=None):
+ status, output = commands.getstatusoutput(cmd)
+ LOG.debug(output)
+ self.assertEqual(0, status,
+ "Failed to run: %s\n%s" % (cmd, output))
+
+ @lockutils.synchronized('pgadmin', 'nova-', external=True)
+ def _reset_pg(self, conn_pieces):
+ (user, password, database, host) = \
+ get_pgsql_connection_info(conn_pieces)
+ os.environ['PGPASSWORD'] = password
+ os.environ['PGUSER'] = user
+ # note(boris-42): We must create and drop database, we can't
+ # drop database which we have connected to, so for such
+ # operations there is a special database template1.
+ sqlcmd = ("psql -w -U %(user)s -h %(host)s -c"
+ " '%(sql)s' -d template1")
+
+ sql = ("drop database if exists %(database)s;") % locals()
+ droptable = sqlcmd % locals()
+ self.execute_cmd(droptable)
+
+ sql = ("create database %(database)s;") % locals()
+ createtable = sqlcmd % locals()
+ self.execute_cmd(createtable)
+
+ os.unsetenv('PGPASSWORD')
+ os.unsetenv('PGUSER')
+
def _reset_databases(self):
- def execute_cmd(cmd=None):
- status, output = commands.getstatusoutput(cmd)
- LOG.debug(output)
- self.assertEqual(0, status)
for key, engine in self.engines.items():
conn_string = self.test_databases[key]
conn_pieces = urlparse.urlparse(conn_string)
@@ -271,29 +300,9 @@ class BaseMigrationTestCase(test.TestCase):
"create database %(database)s;") % locals()
cmd = ("mysql -u \"%(user)s\" %(password)s -h %(host)s "
"-e \"%(sql)s\"") % locals()
- execute_cmd(cmd)
+ self.execute_cmd(cmd)
elif conn_string.startswith('postgresql'):
- # note(krtaylor): File creation problems with tests in
- # venv using .pgpass authentication, changed to
- # PGPASSWORD environment variable which is no longer
- # planned to be deprecated
- (user, password, database, host) = \
- get_pgsql_connection_info(conn_pieces)
- os.environ['PGPASSWORD'] = password
- os.environ['PGUSER'] = user
- # note(boris-42): We must create and drop database, we can't
- # drop database which we have connected to, so for such
- # operations there is a special database template1.
- sqlcmd = ("psql -w -U %(user)s -h %(host)s -c"
- " '%(sql)s' -d template1")
- sql = ("drop database if exists %(database)s;") % locals()
- droptable = sqlcmd % locals()
- execute_cmd(droptable)
- sql = ("create database %(database)s;") % locals()
- createtable = sqlcmd % locals()
- execute_cmd(createtable)
- os.unsetenv('PGPASSWORD')
- os.unsetenv('PGUSER')
+ self._reset_pg(conn_pieces)
def _test_mysql_opportunistically(self):
# Test that table creation on mysql only builds InnoDB tables
@@ -363,36 +372,37 @@ class BaseMigrationTestCase(test.TestCase):
self.migration_api.db_version(engine,
self.REPOSITORY))
- self.migration_api.upgrade(engine,
- self.REPOSITORY,
- self.INIT_VERSION + 1)
-
LOG.debug('latest version is %s' % self.REPOSITORY.latest)
+ versions = range(self.INIT_VERSION + 1, self.REPOSITORY.latest + 1)
- for version in xrange(self.INIT_VERSION + 2,
- self.REPOSITORY.latest + 1):
+ for version in versions:
# upgrade -> downgrade -> upgrade
self._migrate_up(engine, version, with_data=True)
if snake_walk:
- self._migrate_down(engine, version - 1)
- self._migrate_up(engine, version)
+ downgraded = self._migrate_down(
+ engine, version - 1, with_data=True)
+ if downgraded:
+ self._migrate_up(engine, version)
if downgrade:
# Now walk it back down to 0 from the latest, testing
# the downgrade paths.
- for version in reversed(
- xrange(self.INIT_VERSION + 2,
- self.REPOSITORY.latest + 1)):
+ for version in reversed(versions):
# downgrade -> upgrade -> downgrade
- self._migrate_down(engine, version - 1)
- if snake_walk:
+ downgraded = self._migrate_down(engine, version - 1)
+
+ if snake_walk and downgraded:
self._migrate_up(engine, version)
self._migrate_down(engine, version - 1)
- def _migrate_down(self, engine, version):
- self.migration_api.downgrade(engine,
- self.REPOSITORY,
- version)
+ def _migrate_down(self, engine, version, with_data=False):
+ try:
+ self.migration_api.downgrade(engine, self.REPOSITORY, version)
+ except NotImplementedError:
+ # NOTE(sirp): some migrations, namely release-level
+ # migrations, don't support a downgrade.
+ return False
+
self.assertEqual(version,
self.migration_api.db_version(engine,
self.REPOSITORY))
@@ -400,10 +410,13 @@ class BaseMigrationTestCase(test.TestCase):
# NOTE(sirp): `version` is what we're downgrading to (i.e. the 'target'
# version). So if we have any downgrade checks, they need to be run for
# the previous (higher numbered) migration.
- post_downgrade = getattr(
- self, "_post_downgrade_%d" % (version + 1), None)
- if post_downgrade:
- post_downgrade(engine)
+ if with_data:
+ post_downgrade = getattr(
+ self, "_post_downgrade_%03d" % (version + 1), None)
+ if post_downgrade:
+ post_downgrade(engine)
+
+ return True
def _migrate_up(self, engine, version, with_data=False):
"""migrate up to a new version of the db.
@@ -417,20 +430,17 @@ class BaseMigrationTestCase(test.TestCase):
try:
if with_data:
data = None
- pre_upgrade = getattr(self, "_pre_upgrade_%d" % version, None)
+ pre_upgrade = getattr(
+ self, "_pre_upgrade_%03d" % version, None)
if pre_upgrade:
data = pre_upgrade(engine)
- self.migration_api.upgrade(engine,
- self.REPOSITORY,
- version)
- self.assertEqual(
- version,
- self.migration_api.db_version(engine,
- self.REPOSITORY))
-
+ self.migration_api.upgrade(engine, self.REPOSITORY, version)
+ self.assertEqual(version,
+ self.migration_api.db_version(engine,
+ self.REPOSITORY))
if with_data:
- check = getattr(self, "_check_%d" % version, None)
+ check = getattr(self, "_check_%03d" % version, None)
if check:
check(engine, data)
except Exception:
@@ -588,8 +598,24 @@ class TestNovaMigrations(BaseMigrationTestCase, CommonTestsMixIn):
services = get_table(engine, 'services')
engine.execute(services.insert(), data)
+ self._pre_upgrade_147_no_duplicate_aggregate_hosts(engine)
return data
+ def _pre_upgrade_147_no_duplicate_aggregate_hosts(self, engine):
+ engine.execute(get_table(engine, 'aggregate_metadata').insert(), [
+ {'aggregate_id': 1,
+ 'key': 'availability_zone',
+ 'value': 'custom_az'}])
+
+ engine.execute(get_table(engine, 'aggregate_hosts').insert(), [
+ {'aggregate_id': 1,
+ 'host': 'compute-host3'}])
+
+ engine.execute(get_table(engine, 'services').insert(), [
+ {'id': 99, 'host': 'compute-host3',
+ 'binary': 'nova-compute', 'topic': 'compute',
+ 'report_count': 0, 'availability_zone': 'custom_az'}])
+
def _check_147(self, engine, data):
aggregate_md = get_table(engine, 'aggregate_metadata')
aggregate_hosts = get_table(engine, 'aggregate_hosts')
@@ -612,6 +638,15 @@ class TestNovaMigrations(BaseMigrationTestCase, CommonTestsMixIn):
).execute().first()
self.assertEqual(host, None)
+ self._check_147_no_duplicate_aggregate_hosts(engine, data)
+
+ def _check_147_no_duplicate_aggregate_hosts(self, engine, data):
+ aggregate_hosts = get_table(engine, 'aggregate_hosts')
+ agg1_hosts = [h['host'] for h in aggregate_hosts.select(
+ aggregate_hosts.c.aggregate_id == 1
+ ).execute().fetchall()]
+ self.assertEqual(['compute-host3'], agg1_hosts)
+
# migration 149, changes IPAddr storage format
def _pre_upgrade_149(self, engine):
provider_fw_rules = get_table(engine, 'provider_fw_rules')
@@ -814,7 +849,6 @@ class TestNovaMigrations(BaseMigrationTestCase, CommonTestsMixIn):
meta.reflect(engine)
table_names = set(meta.tables.keys())
for table_name in table_names:
- print table_name
if table_name.startswith("shadow_"):
shadow_name = table_name
base_name = table_name.replace("shadow_", "")
@@ -901,11 +935,108 @@ class TestNovaMigrations(BaseMigrationTestCase, CommonTestsMixIn):
fetchall()
self.assertEqual(len(rows), 1)
+ def _pre_upgrade_159(self, engine):
+ data = {
+ 'provider_fw_rules':
+ [
+ {'protocol': 'tcp', 'from_port': 1234,
+ 'to_port': 1234, 'cidr': "127.0.0.1/30"},
+ {'protocol': 'tcp', 'from_port': 1234,
+ 'to_port': 1234, 'cidr': "128.128.128.128/16"},
+ {'protocol': 'tcp', 'from_port': 1234,
+ 'to_port': 1234, 'cidr': "128.128.128.128/32"},
+ {'protocol': 'tcp', 'from_port': 1234,
+ 'to_port': 1234, 'cidr': "2001:db8::1:2/48"},
+ {'protocol': 'tcp', 'from_port': 1234,
+ 'to_port': 1234, 'cidr': "::1/64"},
+ {'protocol': 'tcp', 'from_port': 1234, 'to_port': 1234,
+ 'cidr': "0000:0000:0000:2013:0000:6535:abcd:ef11/64"},
+ {'protocol': 'tcp', 'from_port': 1234, 'to_port': 1234,
+ 'cidr': "0000:1020:0000:2013:0000:6535:abcd:ef11/128"},
+ ],
+ 'console_pools':
+ [
+ {'address': '10.10.10.10'},
+ {'address': '128.100.100.100'},
+ {'address': '2002:2002:2002:2002:2002:2002:2002:2002'},
+ {'address': '::1'},
+ {'address': '0000:0000:0000:2013:0000:6535:abcd:ef11'}
+ ]
+ }
+ return data
+
+ # migration 159 - revert ip column size
+ def _check_159(self, engine, data):
+ dialect = engine.url.get_dialect()
+ # NOTE(maurosr): check if column length is 39 again (it currently makes
+ # sense only for mysql)
+ if dialect not in [postgresql.dialect, sqlite.dialect]:
+ console_pools = get_table(engine, 'console_pools')
+ self.assertEqual(console_pools.columns['address'].type.length, 39)
+ # recheck the 149 data
+ self._check_149(engine, data)
+
+ def _post_downgrade_159(self, engine):
+ dialect = engine.url.get_dialect()
+ # NOTE(maurosr): check if column length is 43 again (it currently makes
+ # sense only for mysql)
+ if dialect not in [postgresql.dialect, sqlite.dialect]:
+ console_pools = get_table(engine, 'console_pools')
+ self.assertEqual(console_pools.columns['address'].type.length, 43)
+
+ # migration 160, fix system_metadata NULL deleted entries to be 0
+ def _pre_upgrade_160(self, engine):
+ fake_instances = [
+ dict(uuid='m160-uuid1'),
+ dict(uuid='m160-uuid2'),
+ dict(uuid='m160-uuid3'),
+ ]
+ fake_sys_meta = [
+ dict(instance_uuid='m160-uuid1', key='foo', value='bar'),
+ dict(instance_uuid='m160-uuid2', key='foo2', value='bar2'),
+ dict(instance_uuid='m160-uuid3', key='foo3', value='bar3')]
+
+ instances = get_table(engine, 'instances')
+ sys_meta = get_table(engine, 'instance_system_metadata')
+ engine.execute(instances.insert(), fake_instances)
+
+ # Create the metadata entries
+ data = {}
+ for sm in fake_sys_meta:
+ result = sys_meta.insert().values(sm).execute()
+ sm['id'] = result.inserted_primary_key[0]
+ data[sm['id']] = sm
+
+ # Make sure the entries in the DB for 'deleted' are None.
+ our_ids = data.keys()
+ results = sys_meta.select().where(sys_meta.c.id.in_(our_ids)).\
+ execute()
+ results = list(results)
+ self.assertEqual(len(our_ids), len(results))
+ for result in results:
+ self.assertEqual(result['deleted'], None)
+ return data
+
+ def _check_160(self, engine, data):
+ our_ids = data.keys()
+ sys_meta = get_table(engine, 'instance_system_metadata')
+ results = sys_meta.select().where(sys_meta.c.id.in_(our_ids)).\
+ execute()
+ results = list(results)
+ self.assertEqual(len(our_ids), len(results))
+ for result in results:
+ the_id = result['id']
+ # Make sure this is now 0.
+ self.assertEqual(result['deleted'], 0)
+ # Make sure nothing else changed.
+ for key, value in data[the_id].items():
+ self.assertEqual(value, result[key])
+
class TestBaremetalMigrations(BaseMigrationTestCase, CommonTestsMixIn):
"""Test sqlalchemy-migrate migrations."""
- USER = "openstack_baremetal_citest"
- PASSWD = "openstack_baremetal_citest"
+ USER = "openstack_citest"
+ PASSWD = "openstack_citest"
DATABASE = "openstack_baremetal_citest"
def __init__(self, *args, **kwargs):
@@ -945,3 +1076,7 @@ class TestBaremetalMigrations(BaseMigrationTestCase, CommonTestsMixIn):
def _check_002(self, engine, data):
self.assertRaises(sqlalchemy.exc.NoSuchTableError,
get_table, engine, 'bm_deployments')
+
+ def _post_downgrade_004(self, engine):
+ bm_nodes = get_table(engine, 'bm_nodes')
+ self.assertNotIn(u'instance_name', [c.name for c in bm_nodes.columns])
diff --git a/nova/tests/test_misc.py b/nova/tests/test_misc.py
index 6732c4007..6744a2a6a 100644
--- a/nova/tests/test_misc.py
+++ b/nova/tests/test_misc.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC
+# Copyright 2010 OpenStack Foundation
#
# 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/tests/test_notifications.py b/nova/tests/test_notifications.py
index 9b38756c8..c9c80818a 100644
--- a/nova/tests/test_notifications.py
+++ b/nova/tests/test_notifications.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py
index ff316826a..b1d1958f0 100644
--- a/nova/tests/test_nova_manage.py
+++ b/nova/tests/test_nova_manage.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
# Copyright 2011 Ilya Alekseyev
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -372,3 +372,13 @@ class ProjectCommandsTestCase(test.TestCase):
self.assertRaises(SystemExit,
self.commands.quota, 'admin', 'volumes1', '10'
)
+
+
+class DBCommandsTestCase(test.TestCase):
+ def setUp(self):
+ super(DBCommandsTestCase, self).setUp()
+ self.commands = nova_manage.DbCommands()
+
+ def test_archive_deleted_rows_negative(self):
+ self.assertRaises(SystemExit,
+ self.commands.archive_deleted_rows, -1)
diff --git a/nova/tests/test_periodic_tasks.py b/nova/tests/test_periodic_tasks.py
index 621e86b3a..2539332a9 100644
--- a/nova/tests/test_periodic_tasks.py
+++ b/nova/tests/test_periodic_tasks.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/test_pipelib.py b/nova/tests/test_pipelib.py
index 4b76581a4..99d840a83 100644
--- a/nova/tests/test_pipelib.py
+++ b/nova/tests/test_pipelib.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/test_plugin_api_extensions.py b/nova/tests/test_plugin_api_extensions.py
index 77985854a..3aac638c6 100644
--- a/nova/tests/test_plugin_api_extensions.py
+++ b/nova/tests/test_plugin_api_extensions.py
@@ -1,4 +1,4 @@
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/test_powervm.py b/nova/tests/test_powervm.py
index 640497fb0..6fd3fa035 100644
--- a/nova/tests/test_powervm.py
+++ b/nova/tests/test_powervm.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
@@ -23,9 +23,11 @@ from nova import db
from nova import test
from nova.compute import power_state
+from nova.compute import task_states
from nova.network import model as network_model
from nova.openstack.common import log as logging
from nova.tests import fake_network_cache_model
+from nova.tests.image import fake
from nova.virt import images
from nova.virt.powervm import blockdev as powervm_blockdev
from nova.virt.powervm import common
@@ -58,7 +60,7 @@ class FakeIVMOperator(object):
def start_lpar(self, instance_name):
pass
- def stop_lpar(self, instance_name):
+ def stop_lpar(self, instance_name, time_out=30):
pass
def remove_lpar(self, instance_name):
@@ -96,6 +98,9 @@ class FakeIVMOperator(object):
def get_hostname(self):
return 'fake-powervm'
+ def rename_lpar(self, old, new):
+ pass
+
class FakeBlockAdapter(powervm_blockdev.PowerVMLocalVolumeAdapter):
@@ -112,10 +117,20 @@ class FakeBlockAdapter(powervm_blockdev.PowerVMLocalVolumeAdapter):
pass
def _copy_image_file(self, sourcePath, remotePath, decompress=False):
- finalPath = '/home/images/rhel62.raw.7e358754160433febd6f3318b7c9e335'
+ finalPath = '/tmp/rhel62.raw.7e358754160433febd6f3318b7c9e335'
size = 4294967296
return finalPath, size
+ def _copy_device_to_file(self, device_name, file_path):
+ pass
+
+ def _copy_image_file_from_host(self, remote_source_path, local_dest_dir,
+ compress=False):
+ snapshot_file = '/tmp/rhel62.raw.7e358754160433febd6f3318b7c9e335'
+ snap_ref = open(snapshot_file, 'w+')
+ snap_ref.close()
+ return snapshot_file
+
def fake_get_powervm_operator():
return FakeIVMOperator()
@@ -134,12 +149,14 @@ class PowerVMDriverTestCase(test.TestCase):
self.instance = self._create_instance()
def _create_instance(self):
+ fake.stub_out_image_service(self.stubs)
return db.instance_create(context.get_admin_context(),
- {'user_id': 'fake',
- 'project_id': 'fake',
- 'instance_type_id': 1,
- 'memory_mb': 1024,
- 'vcpus': 2})
+ {'user_id': 'fake',
+ 'project_id': 'fake',
+ 'instance_type_id': 1,
+ 'memory_mb': 1024,
+ 'image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
+ 'vcpus': 2})
def test_list_instances(self):
instances = self.powervm_connection.list_instances()
@@ -189,6 +206,27 @@ class PowerVMDriverTestCase(test.TestCase):
self.instance,
{'id': 'ANY_ID'}, [], 's3cr3t', fake_net_info)
+ def test_snapshot(self):
+
+ def update_task_state(task_state, expected_state=None):
+ self._loc_task_state = task_state
+ self._loc_expected_task_state = expected_state
+
+ loc_context = context.get_admin_context()
+ properties = {'instance_id': self.instance['id'],
+ 'user_id': str(loc_context.user_id)}
+ sent_meta = {'name': 'fake_snap', 'is_public': False,
+ 'status': 'creating', 'properties': properties}
+ image_service = fake.FakeImageService()
+ recv_meta = image_service.create(loc_context, sent_meta)
+
+ self.powervm_connection.snapshot(loc_context,
+ self.instance, recv_meta['id'],
+ update_task_state)
+
+ self.assertTrue(self._loc_task_state == task_states.IMAGE_UPLOADING and
+ self._loc_expected_task_state == task_states.IMAGE_PENDING_UPLOAD)
+
def test_destroy(self):
self.powervm_connection.destroy(self.instance, None)
self.stubs.Set(FakeIVMOperator, 'get_lpar', lambda x, y: None)
@@ -230,3 +268,36 @@ class PowerVMDriverTestCase(test.TestCase):
joined_path = common.aix_path_join(path_one, path_two)
expected_path = '/some/file/path/filename'
self.assertEqual(joined_path, expected_path)
+
+ def _test_finish_revert_migration_after_crash(self, backup_made, new_made):
+ inst = {'name': 'foo'}
+
+ self.mox.StubOutWithMock(self.powervm_connection, 'instance_exists')
+ self.mox.StubOutWithMock(self.powervm_connection._powervm, 'destroy')
+ self.mox.StubOutWithMock(self.powervm_connection._powervm._operator,
+ 'rename_lpar')
+ self.mox.StubOutWithMock(self.powervm_connection._powervm, 'power_on')
+
+ self.powervm_connection.instance_exists('rsz_foo').AndReturn(
+ backup_made)
+
+ if backup_made:
+ self.powervm_connection.instance_exists('foo').AndReturn(new_made)
+ if new_made:
+ self.powervm_connection._powervm.destroy('foo')
+ self.powervm_connection._powervm._operator.rename_lpar('rsz_foo',
+ 'foo')
+ self.powervm_connection._powervm.power_on('foo')
+
+ self.mox.ReplayAll()
+
+ self.powervm_connection.finish_revert_migration(inst, [])
+
+ def test_finish_revert_migration_after_crash(self):
+ self._test_finish_revert_migration_after_crash(True, True)
+
+ def test_finish_revert_migration_after_crash_before_new(self):
+ self._test_finish_revert_migration_after_crash(True, False)
+
+ def test_finish_revert_migration_after_crash_before_backup(self):
+ self._test_finish_revert_migration_after_crash(False, False)
diff --git a/nova/tests/test_safeutils.py b/nova/tests/test_safeutils.py
new file mode 100644
index 000000000..430e2f020
--- /dev/null
+++ b/nova/tests/test_safeutils.py
@@ -0,0 +1,100 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 Justin Santa Barbara
+#
+# 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 nova import safe_utils
+from nova import test
+
+
+class GetCallArgsTestCase(test.TestCase):
+ def _test_func(self, instance, red=None, blue=None):
+ pass
+
+ def test_all_kwargs(self):
+ args = ()
+ kwargs = {'instance': {'uuid': 1}, 'red': 3, 'blue': 4}
+ callargs = safe_utils.getcallargs(self._test_func, *args, **kwargs)
+ #implicit self counts as an arg
+ self.assertEqual(4, len(callargs))
+ self.assertTrue('instance' in callargs)
+ self.assertEqual({'uuid': 1}, callargs['instance'])
+ self.assertTrue('red' in callargs)
+ self.assertEqual(3, callargs['red'])
+ self.assertTrue('blue' in callargs)
+ self.assertEqual(4, callargs['blue'])
+
+ def test_all_args(self):
+ args = ({'uuid': 1}, 3, 4)
+ kwargs = {}
+ callargs = safe_utils.getcallargs(self._test_func, *args, **kwargs)
+ #implicit self counts as an arg
+ self.assertEqual(4, len(callargs))
+ self.assertTrue('instance' in callargs)
+ self.assertEqual({'uuid': 1}, callargs['instance'])
+ self.assertTrue('red' in callargs)
+ self.assertEqual(3, callargs['red'])
+ self.assertTrue('blue' in callargs)
+ self.assertEqual(4, callargs['blue'])
+
+ def test_mixed_args(self):
+ args = ({'uuid': 1}, 3)
+ kwargs = {'blue': 4}
+ callargs = safe_utils.getcallargs(self._test_func, *args, **kwargs)
+ #implicit self counts as an arg
+ self.assertEqual(4, len(callargs))
+ self.assertTrue('instance' in callargs)
+ self.assertEqual({'uuid': 1}, callargs['instance'])
+ self.assertTrue('red' in callargs)
+ self.assertEqual(3, callargs['red'])
+ self.assertTrue('blue' in callargs)
+ self.assertEqual(4, callargs['blue'])
+
+ def test_partial_kwargs(self):
+ args = ()
+ kwargs = {'instance': {'uuid': 1}, 'red': 3}
+ callargs = safe_utils.getcallargs(self._test_func, *args, **kwargs)
+ #implicit self counts as an arg
+ self.assertEqual(4, len(callargs))
+ self.assertTrue('instance' in callargs)
+ self.assertEqual({'uuid': 1}, callargs['instance'])
+ self.assertTrue('red' in callargs)
+ self.assertEqual(3, callargs['red'])
+ self.assertTrue('blue' in callargs)
+ self.assertEqual(None, callargs['blue'])
+
+ def test_partial_args(self):
+ args = ({'uuid': 1}, 3)
+ kwargs = {}
+ callargs = safe_utils.getcallargs(self._test_func, *args, **kwargs)
+ #implicit self counts as an arg
+ self.assertEqual(4, len(callargs))
+ self.assertTrue('instance' in callargs)
+ self.assertEqual({'uuid': 1}, callargs['instance'])
+ self.assertTrue('red' in callargs)
+ self.assertEqual(3, callargs['red'])
+ self.assertTrue('blue' in callargs)
+ self.assertEqual(None, callargs['blue'])
+
+ def test_partial_mixed_args(self):
+ args = (3,)
+ kwargs = {'instance': {'uuid': 1}}
+ callargs = safe_utils.getcallargs(self._test_func, *args, **kwargs)
+ self.assertEqual(4, len(callargs))
+ self.assertTrue('instance' in callargs)
+ self.assertEqual({'uuid': 1}, callargs['instance'])
+ self.assertTrue('red' in callargs)
+ self.assertEqual(3, callargs['red'])
+ self.assertTrue('blue' in callargs)
+ self.assertEqual(None, callargs['blue'])
diff --git a/nova/tests/test_test_utils.py b/nova/tests/test_test_utils.py
index 722377aa5..ef3a6fb68 100644
--- a/nova/tests/test_test_utils.py
+++ b/nova/tests/test_test_utils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2010 OpenStack LLC
+# Copyright 2010 OpenStack Foundation
#
# 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/tests/test_utils.py b/nova/tests/test_utils.py
index 940ddf6ec..d22fb12ea 100644
--- a/nova/tests/test_utils.py
+++ b/nova/tests/test_utils.py
@@ -23,6 +23,7 @@ import os
import os.path
import StringIO
import tempfile
+from xml.dom import minidom
import mox
import netaddr
@@ -514,6 +515,8 @@ class GenericUtilsTestCase(test.TestCase):
self.assertTrue(utils.is_valid_ipv4('127.0.0.1'))
self.assertFalse(utils.is_valid_ipv4('::1'))
self.assertFalse(utils.is_valid_ipv4('bacon'))
+ self.assertFalse(utils.is_valid_ipv4(""))
+ self.assertFalse(utils.is_valid_ipv4(10))
def test_is_valid_ipv6(self):
self.assertTrue(utils.is_valid_ipv6("::1"))
@@ -523,6 +526,8 @@ class GenericUtilsTestCase(test.TestCase):
"0000:0000:0000:0000:0000:0000:0000:0001"))
self.assertFalse(utils.is_valid_ipv6("foo"))
self.assertFalse(utils.is_valid_ipv6("127.0.0.1"))
+ self.assertFalse(utils.is_valid_ipv6(""))
+ self.assertFalse(utils.is_valid_ipv6(10))
def test_is_valid_ipv6_cidr(self):
self.assertTrue(utils.is_valid_ipv6_cidr("2600::/64"))
@@ -964,88 +969,6 @@ class WrappedCodeTestCase(test.TestCase):
self.assertTrue('blue' in func_code.co_varnames)
-class GetCallArgsTestCase(test.TestCase):
- def _test_func(self, instance, red=None, blue=None):
- pass
-
- def test_all_kwargs(self):
- args = ()
- kwargs = {'instance': {'uuid': 1}, 'red': 3, 'blue': 4}
- callargs = utils.getcallargs(self._test_func, *args, **kwargs)
- #implicit self counts as an arg
- self.assertEqual(4, len(callargs))
- self.assertTrue('instance' in callargs)
- self.assertEqual({'uuid': 1}, callargs['instance'])
- self.assertTrue('red' in callargs)
- self.assertEqual(3, callargs['red'])
- self.assertTrue('blue' in callargs)
- self.assertEqual(4, callargs['blue'])
-
- def test_all_args(self):
- args = ({'uuid': 1}, 3, 4)
- kwargs = {}
- callargs = utils.getcallargs(self._test_func, *args, **kwargs)
- #implicit self counts as an arg
- self.assertEqual(4, len(callargs))
- self.assertTrue('instance' in callargs)
- self.assertEqual({'uuid': 1}, callargs['instance'])
- self.assertTrue('red' in callargs)
- self.assertEqual(3, callargs['red'])
- self.assertTrue('blue' in callargs)
- self.assertEqual(4, callargs['blue'])
-
- def test_mixed_args(self):
- args = ({'uuid': 1}, 3)
- kwargs = {'blue': 4}
- callargs = utils.getcallargs(self._test_func, *args, **kwargs)
- #implicit self counts as an arg
- self.assertEqual(4, len(callargs))
- self.assertTrue('instance' in callargs)
- self.assertEqual({'uuid': 1}, callargs['instance'])
- self.assertTrue('red' in callargs)
- self.assertEqual(3, callargs['red'])
- self.assertTrue('blue' in callargs)
- self.assertEqual(4, callargs['blue'])
-
- def test_partial_kwargs(self):
- args = ()
- kwargs = {'instance': {'uuid': 1}, 'red': 3}
- callargs = utils.getcallargs(self._test_func, *args, **kwargs)
- #implicit self counts as an arg
- self.assertEqual(4, len(callargs))
- self.assertTrue('instance' in callargs)
- self.assertEqual({'uuid': 1}, callargs['instance'])
- self.assertTrue('red' in callargs)
- self.assertEqual(3, callargs['red'])
- self.assertTrue('blue' in callargs)
- self.assertEqual(None, callargs['blue'])
-
- def test_partial_args(self):
- args = ({'uuid': 1}, 3)
- kwargs = {}
- callargs = utils.getcallargs(self._test_func, *args, **kwargs)
- #implicit self counts as an arg
- self.assertEqual(4, len(callargs))
- self.assertTrue('instance' in callargs)
- self.assertEqual({'uuid': 1}, callargs['instance'])
- self.assertTrue('red' in callargs)
- self.assertEqual(3, callargs['red'])
- self.assertTrue('blue' in callargs)
- self.assertEqual(None, callargs['blue'])
-
- def test_partial_mixed_args(self):
- args = (3,)
- kwargs = {'instance': {'uuid': 1}}
- callargs = utils.getcallargs(self._test_func, *args, **kwargs)
- self.assertEqual(4, len(callargs))
- self.assertTrue('instance' in callargs)
- self.assertEqual({'uuid': 1}, callargs['instance'])
- self.assertTrue('red' in callargs)
- self.assertEqual(3, callargs['red'])
- self.assertTrue('blue' in callargs)
- self.assertEqual(None, callargs['blue'])
-
-
class StringLengthTestCase(test.TestCase):
def test_check_string_length(self):
self.assertIsNone(utils.check_string_length(
@@ -1059,3 +982,47 @@ class StringLengthTestCase(test.TestCase):
self.assertRaises(exception.InvalidInput,
utils.check_string_length,
'a' * 256, 'name', max_length=255)
+
+
+class SafeParserTestCase(test.TestCase):
+ def test_external_dtd(self):
+ xml_string = ("""<?xml version="1.0" encoding="utf-8"?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html>
+ <head/>
+ <body>html with dtd</body>
+ </html>""")
+
+ parser = utils.ProtectedExpatParser(forbid_dtd=False,
+ forbid_entities=True)
+ self.assertRaises(ValueError,
+ minidom.parseString,
+ xml_string, parser)
+
+ def test_external_file(self):
+ xml_string = """<!DOCTYPE external [
+ <!ENTITY ee SYSTEM "file:///PATH/TO/root.xml">
+ ]>
+ <root>&ee;</root>"""
+
+ parser = utils.ProtectedExpatParser(forbid_dtd=False,
+ forbid_entities=True)
+ self.assertRaises(ValueError,
+ minidom.parseString,
+ xml_string, parser)
+
+ def test_notation(self):
+ xml_string = """<?xml version="1.0" standalone="no"?>
+ <!-- comment data -->
+ <!DOCTYPE x [
+ <!NOTATION notation SYSTEM "notation.jpeg">
+ ]>
+ <root attr1="value1">
+ </root>"""
+
+ parser = utils.ProtectedExpatParser(forbid_dtd=False,
+ forbid_entities=True)
+ self.assertRaises(ValueError,
+ minidom.parseString,
+ xml_string, parser)
diff --git a/nova/tests/test_virt_disk_vfs_localfs.py b/nova/tests/test_virt_disk_vfs_localfs.py
index 096a75964..5bbac670e 100644
--- a/nova/tests/test_virt_disk_vfs_localfs.py
+++ b/nova/tests/test_virt_disk_vfs_localfs.py
@@ -148,10 +148,6 @@ class VirtDiskVFSLocalFSTestPaths(test.TestCase):
class VirtDiskVFSLocalFSTest(test.TestCase):
-
- def setUp(self):
- super(VirtDiskVFSLocalFSTest, self).setUp()
-
def test_makepath(self):
global dirs, commands
dirs = []
diff --git a/nova/tests/test_virt_drivers.py b/nova/tests/test_virt_drivers.py
index f6e0bca38..395663600 100644
--- a/nova/tests/test_virt_drivers.py
+++ b/nova/tests/test_virt_drivers.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2010 OpenStack LLC
+# Copyright 2010 OpenStack Foundation
#
# 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
@@ -192,9 +192,6 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
self.ctxt = test_utils.get_test_admin_context()
self.image_service = fake_image.FakeImageService()
- def tearDown(self):
- super(_VirtDriverTestCase, self).tearDown()
-
def _get_running_instance(self):
instance_ref = test_utils.get_test_instance()
network_info = test_utils.get_test_network_info()
diff --git a/nova/tests/test_vmwareapi.py b/nova/tests/test_vmwareapi.py
index e20a5a7b7..a5f08041b 100644
--- a/nova/tests/test_vmwareapi.py
+++ b/nova/tests/test_vmwareapi.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/test_vmwareapi_vmops.py b/nova/tests/test_vmwareapi_vmops.py
index ad83cd21d..f1806273c 100644
--- a/nova/tests/test_vmwareapi_vmops.py
+++ b/nova/tests/test_vmwareapi_vmops.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2013 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 84c3caa63..6714161f1 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -176,6 +176,15 @@ def stub_vm_utils_with_vdi_attached_here(function, should_return=True):
return decorated_function
+def create_instance_with_system_metadata(context, instance_values):
+ instance_type = db.instance_type_get(context,
+ instance_values['instance_type_id'])
+ sys_meta = instance_types.save_instance_type_info({},
+ instance_type)
+ instance_values['system_metadata'] = sys_meta
+ return db.instance_create(context, instance_values)
+
+
class XenAPIVolumeTestCase(stubs.XenAPITestBase):
"""Unit tests for Volume operations."""
def setUp(self):
@@ -635,7 +644,8 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
'os_type': os_type,
'hostname': hostname,
'architecture': architecture}
- instance = db.instance_create(self.context, instance_values)
+ instance = create_instance_with_system_metadata(self.context,
+ instance_values)
else:
instance = db.instance_get(self.context, instance_id)
@@ -1093,7 +1103,9 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
'os_type': 'linux',
'vm_mode': 'hvm',
'architecture': 'x86-64'}
- instance = db.instance_create(self.context, instance_values)
+
+ instance = create_instance_with_system_metadata(self.context,
+ instance_values)
network_info = fake_network.fake_get_instance_nw_info(self.stubs,
spectacular=True)
image_meta = {'id': IMAGE_VHD,
@@ -1252,7 +1264,8 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
'127.0.0.1', instance_type, None)
def test_revert_migrate(self):
- instance = db.instance_create(self.context, self.instance_values)
+ instance = create_instance_with_system_metadata(self.context,
+ self.instance_values)
self.called = False
self.fake_vm_start_called = False
self.fake_finish_revert_migration_called = False
@@ -1293,7 +1306,8 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
self.assertEqual(self.fake_finish_revert_migration_called, True)
def test_finish_migrate(self):
- instance = db.instance_create(self.context, self.instance_values)
+ instance = create_instance_with_system_metadata(self.context,
+ self.instance_values)
self.called = False
self.fake_vm_start_called = False
@@ -1325,7 +1339,8 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
tiny_type_id = tiny_type['id']
self.instance_values.update({'instance_type_id': tiny_type_id,
'root_gb': 0})
- instance = db.instance_create(self.context, self.instance_values)
+ instance = create_instance_with_system_metadata(self.context,
+ self.instance_values)
def fake_vdi_resize(*args, **kwargs):
raise Exception("This shouldn't be called")
@@ -1341,7 +1356,8 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
network_info, image_meta, resize_instance=True)
def test_finish_migrate_no_resize_vdi(self):
- instance = db.instance_create(self.context, self.instance_values)
+ instance = create_instance_with_system_metadata(self.context,
+ self.instance_values)
def fake_vdi_resize(*args, **kwargs):
raise Exception("This shouldn't be called")
@@ -1616,7 +1632,8 @@ class XenAPIAutoDiskConfigTestCase(stubs.XenAPITestBase):
fake.FakeVirtAPI())
disk_image_type = vm_utils.ImageType.DISK_VHD
- instance = db.instance_create(self.context, self.instance_values)
+ instance = create_instance_with_system_metadata(self.context,
+ self.instance_values)
vm_ref = xenapi_fake.create_vm(instance['name'], 'Halted')
vdi_ref = xenapi_fake.create_vdi(instance['name'], 'fake')
@@ -1716,14 +1733,9 @@ class XenAPIGenerateLocal(stubs.XenAPITestBase):
def test_generate_swap(self):
# Test swap disk generation.
- instance = db.instance_create(self.context, self.instance_values)
- instance = db.instance_update(self.context, instance['uuid'],
- {'instance_type_id': 5})
-
- # NOTE(danms): because we're stubbing out the instance_types from
- # the database, our instance['instance_type'] doesn't get properly
- # filled out here, so put what we need into it
- instance['instance_type']['swap'] = 1024
+ instance_values = dict(self.instance_values, instance_type_id=5)
+ instance = create_instance_with_system_metadata(self.context,
+ instance_values)
def fake_generate_swap(*args, **kwargs):
self.called = True
@@ -1733,14 +1745,9 @@ class XenAPIGenerateLocal(stubs.XenAPITestBase):
def test_generate_ephemeral(self):
# Test ephemeral disk generation.
- instance = db.instance_create(self.context, self.instance_values)
- instance = db.instance_update(self.context, instance['uuid'],
- {'instance_type_id': 4})
-
- # NOTE(danms): because we're stubbing out the instance_types from
- # the database, our instance['instance_type'] doesn't get properly
- # filled out here, so put what we need into it
- instance['instance_type']['ephemeral_gb'] = 160
+ instance_values = dict(self.instance_values, instance_type_id=4)
+ instance = create_instance_with_system_metadata(self.context,
+ instance_values)
def fake_generate_ephemeral(*args):
self.called = True
@@ -2068,8 +2075,10 @@ class XenAPIDom0IptablesFirewallTestCase(stubs.XenAPITestBase):
ipv6 = self.fw.iptables.ipv6['filter'].rules
ipv4_network_rules = len(ipv4) - len(inst_ipv4) - ipv4_len
ipv6_network_rules = len(ipv6) - len(inst_ipv6) - ipv6_len
- self.assertEquals(ipv4_network_rules,
- ipv4_rules_per_addr * ipv4_addr_per_network * networks_count)
+ # Extra rules are for the DHCP request
+ rules = (ipv4_rules_per_addr * ipv4_addr_per_network *
+ networks_count) + 2
+ self.assertEquals(ipv4_network_rules, rules)
self.assertEquals(ipv6_network_rules,
ipv6_rules_per_addr * ipv6_addr_per_network * networks_count)
@@ -3112,6 +3121,42 @@ class VMOpsTestCase(test.TestCase):
'VDI.resize',
ops.check_resize_func_name())
+ def _test_finish_revert_migration_after_crash(self, backup_made, new_made):
+ instance = {'name': 'foo',
+ 'task_state': task_states.RESIZE_MIGRATING}
+ session = self._get_mock_session(None, None)
+ ops = vmops.VMOps(session, fake.FakeVirtAPI())
+
+ self.mox.StubOutWithMock(vm_utils, 'lookup')
+ self.mox.StubOutWithMock(ops, '_destroy')
+ self.mox.StubOutWithMock(vm_utils, 'set_vm_name_label')
+ self.mox.StubOutWithMock(ops, '_attach_mapped_block_devices')
+ self.mox.StubOutWithMock(ops, '_start')
+
+ vm_utils.lookup(session, 'foo-orig').AndReturn(
+ backup_made and 'foo' or None)
+ vm_utils.lookup(session, 'foo').AndReturn(
+ (not backup_made or new_made) and 'foo' or None)
+ if backup_made:
+ if new_made:
+ ops._destroy(instance, 'foo')
+ vm_utils.set_vm_name_label(session, 'foo', 'foo')
+ ops._attach_mapped_block_devices(instance, [])
+ ops._start(instance, 'foo')
+
+ self.mox.ReplayAll()
+
+ ops.finish_revert_migration(instance, [])
+
+ def test_finish_revert_migration_after_crash(self):
+ self._test_finish_revert_migration_after_crash(True, True)
+
+ def test_finish_revert_migration_after_crash_before_new(self):
+ self._test_finish_revert_migration_after_crash(True, False)
+
+ def test_finish_revert_migration_after_crash_before_backup(self):
+ self._test_finish_revert_migration_after_crash(False, False)
+
class XenAPISessionTestCase(test.TestCase):
def _get_mock_xapisession(self, software_version):
diff --git a/nova/tests/utils.py b/nova/tests/utils.py
index 9daa72f34..755d49be1 100644
--- a/nova/tests/utils.py
+++ b/nova/tests/utils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/virt/disk/test_api.py b/nova/tests/virt/disk/test_api.py
index 15fb2fc2f..772c8cb1b 100644
--- a/nova/tests/virt/disk/test_api.py
+++ b/nova/tests/virt/disk/test_api.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC
+# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/virt/xenapi/imageupload/test_glance.py b/nova/tests/virt/xenapi/imageupload/test_glance.py
index b0518228d..34e95ab80 100644
--- a/nova/tests/virt/xenapi/imageupload/test_glance.py
+++ b/nova/tests/virt/xenapi/imageupload/test_glance.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -30,9 +30,6 @@ class TestGlanceStore(test.TestCase):
self.store = glance.GlanceStore()
self.mox = mox.Mox()
- def tearDown(self):
- super(TestGlanceStore, self).tearDown()
-
def test_upload_image(self):
glance_host = '0.1.2.3'
glance_port = 8143
diff --git a/nova/tests/virt/xenapi/test_vm_utils.py b/nova/tests/virt/xenapi/test_vm_utils.py
index 633e6f835..f757a57ad 100644
--- a/nova/tests/virt/xenapi/test_vm_utils.py
+++ b/nova/tests/virt/xenapi/test_vm_utils.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 OpenStack LLC
+# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/tests/vmwareapi/__init__.py b/nova/tests/vmwareapi/__init__.py
index 228186621..d22b919f3 100644
--- a/nova/tests/vmwareapi/__init__.py
+++ b/nova/tests/vmwareapi/__init__.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/vmwareapi/db_fakes.py b/nova/tests/vmwareapi/db_fakes.py
index f3191670d..54e3cf43b 100644
--- a/nova/tests/vmwareapi/db_fakes.py
+++ b/nova/tests/vmwareapi/db_fakes.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/vmwareapi/stubs.py b/nova/tests/vmwareapi/stubs.py
index 0330246e2..dc87b2355 100644
--- a/nova/tests/vmwareapi/stubs.py
+++ b/nova/tests/vmwareapi/stubs.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/tests/volume/__init__.py b/nova/tests/volume/__init__.py
index 4549abf92..efbc9063d 100644
--- a/nova/tests/volume/__init__.py
+++ b/nova/tests/volume/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC
+# Copyright 2012 OpenStack Foundation
#
# 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/utils.py b/nova/utils.py
index 2c7d0b427..eb6c44106 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -672,19 +672,33 @@ class ProtectedExpatParser(expatreader.ExpatParser):
def entity_decl(self, entityName, is_parameter_entity, value, base,
systemId, publicId, notationName):
- raise ValueError("<!ENTITY> forbidden")
+ raise ValueError("<!ENTITY> entity declaration forbidden")
def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
# expat 1.2
- raise ValueError("<!ENTITY> forbidden")
+ raise ValueError("<!ENTITY> unparsed entity forbidden")
+
+ def external_entity_ref(self, context, base, systemId, publicId):
+ raise ValueError("<!ENTITY> external entity forbidden")
+
+ def notation_decl(self, name, base, sysid, pubid):
+ raise ValueError("<!ENTITY> notation forbidden")
def reset(self):
expatreader.ExpatParser.reset(self)
if self.forbid_dtd:
self._parser.StartDoctypeDeclHandler = self.start_doctype_decl
+ self._parser.EndDoctypeDeclHandler = None
if self.forbid_entities:
self._parser.EntityDeclHandler = self.entity_decl
self._parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl
+ self._parser.ExternalEntityRefHandler = self.external_entity_ref
+ self._parser.NotationDeclHandler = self.notation_decl
+ try:
+ self._parser.SkippedEntityHandler = None
+ except AttributeError:
+ # some pyexpat versions do not support SkippedEntity
+ pass
def safe_minidom_parse_string(xml_string):
@@ -931,14 +945,16 @@ def is_valid_boolstr(val):
def is_valid_ipv4(address):
"""Verify that address represents a valid IPv4 address."""
try:
- addr = netaddr.IPAddress(address)
- return addr.version == 4
+ return netaddr.valid_ipv4(address)
except Exception:
return False
def is_valid_ipv6(address):
- return netaddr.valid_ipv6(address)
+ try:
+ return netaddr.valid_ipv6(address)
+ except Exception:
+ return False
def is_valid_ipv6_cidr(address):
@@ -1367,39 +1383,6 @@ def get_wrapped_function(function):
return _get_wrapped_function(function)
-def getcallargs(function, *args, **kwargs):
- """This is a simplified inspect.getcallargs (2.7+).
-
- It should be replaced when python >= 2.7 is standard.
- """
- keyed_args = {}
- argnames, varargs, keywords, defaults = inspect.getargspec(function)
-
- keyed_args.update(kwargs)
-
- #NOTE(alaski) the implicit 'self' or 'cls' argument shows up in
- # argnames but not in args or kwargs. Uses 'in' rather than '==' because
- # some tests use 'self2'.
- if 'self' in argnames[0] or 'cls' == argnames[0]:
- # The function may not actually be a method or have im_self.
- # Typically seen when it's stubbed with mox.
- if inspect.ismethod(function) and hasattr(function, 'im_self'):
- keyed_args[argnames[0]] = function.im_self
- else:
- keyed_args[argnames[0]] = None
-
- remaining_argnames = filter(lambda x: x not in keyed_args, argnames)
- keyed_args.update(dict(zip(remaining_argnames, args)))
-
- if defaults:
- num_defaults = len(defaults)
- for argname, value in zip(argnames[-num_defaults:], defaults):
- if argname not in keyed_args:
- keyed_args[argname] = value
-
- return keyed_args
-
-
class ExceptionHelper(object):
"""Class to wrap another and translate the ClientExceptions raised by its
function calls to the actual ones"""
diff --git a/nova/version.py b/nova/version.py
index d54c112be..6f2cbbb28 100644
--- a/nova/version.py
+++ b/nova/version.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/baremetal/baremetal_states.py b/nova/virt/baremetal/baremetal_states.py
index 115ed091c..c669b4116 100644
--- a/nova/virt/baremetal/baremetal_states.py
+++ b/nova/virt/baremetal/baremetal_states.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 NTT DOCOMO, INC.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/virt/baremetal/base.py b/nova/virt/baremetal/base.py
index 8cd9e9b3c..2029400ba 100644
--- a/nova/virt/baremetal/base.py
+++ b/nova/virt/baremetal/base.py
@@ -21,8 +21,8 @@ from nova.virt.baremetal import baremetal_states
class NodeDriver(object):
- def __init__(self):
- pass
+ def __init__(self, virtapi):
+ self.virtapi = virtapi
def cache_images(self, context, node, instance, **kwargs):
raise NotImplementedError()
diff --git a/nova/virt/baremetal/db/sqlalchemy/api.py b/nova/virt/baremetal/db/sqlalchemy/api.py
index d64bc4872..d117ad46d 100644
--- a/nova/virt/baremetal/db/sqlalchemy/api.py
+++ b/nova/virt/baremetal/db/sqlalchemy/api.py
@@ -28,6 +28,7 @@ from sqlalchemy.sql.expression import literal_column
import nova.context
from nova.db.sqlalchemy import api as sqlalchemy_api
from nova import exception
+from nova.openstack.common.db import exception as db_exc
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
from nova.openstack.common import uuidutils
@@ -399,7 +400,7 @@ def bm_interface_set_vif_uuid(context, if_id, vif_uuid):
try:
session.add(bm_interface)
session.flush()
- except db_session.DBError, e:
+ except db_exc.DBError, e:
# TODO(deva): clean up when db layer raises DuplicateKeyError
if str(e).find('IntegrityError') != -1:
raise exception.NovaException(_("Baremetal interface %s "
diff --git a/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/001_init.py b/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/001_init.py
index 2d899406c..fad83e21b 100644
--- a/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/001_init.py
+++ b/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/001_init.py
@@ -120,4 +120,4 @@ def upgrade(migrate_engine):
def downgrade(migrate_engine):
- pass
+ raise NotImplementedError('Downgrade from 001_init is unsupported.')
diff --git a/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/004_add_instance_name_to_bm_nodes.py b/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/004_add_instance_name_to_bm_nodes.py
index 68fbe0960..6f85b9cec 100644
--- a/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/004_add_instance_name_to_bm_nodes.py
+++ b/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/004_add_instance_name_to_bm_nodes.py
@@ -32,6 +32,4 @@ def downgrade(migrate_engine):
meta.bind = migrate_engine
t = Table('bm_nodes', meta, autoload=True)
- name_col = Column('instance_name', String(length=255))
-
- t.drop_column(name_col)
+ t.drop_column('instance_name')
diff --git a/nova/virt/baremetal/db/sqlalchemy/session.py b/nova/virt/baremetal/db/sqlalchemy/session.py
index 585096c94..fc045d5ca 100644
--- a/nova/virt/baremetal/db/sqlalchemy/session.py
+++ b/nova/virt/baremetal/db/sqlalchemy/session.py
@@ -44,8 +44,6 @@ CONF.import_opt('sqlite_db', 'nova.openstack.common.db.sqlalchemy.session')
_ENGINE = None
_MAKER = None
-DBError = nova_session.DBError
-
def get_session(autocommit=True, expire_on_commit=False):
"""Return a SQLAlchemy session."""
diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py
index 8dff0a785..94d3f0a92 100755
--- a/nova/virt/baremetal/driver.py
+++ b/nova/virt/baremetal/driver.py
@@ -122,7 +122,7 @@ class BareMetalDriver(driver.ComputeDriver):
super(BareMetalDriver, self).__init__(virtapi)
self.driver = importutils.import_object(
- CONF.baremetal.driver)
+ CONF.baremetal.driver, virtapi)
self.vif_driver = importutils.import_object(
CONF.baremetal.vif_driver)
self.firewall_driver = firewall.load_driver(
@@ -410,9 +410,13 @@ class BareMetalDriver(driver.ComputeDriver):
def get_available_resource(self, nodename):
context = nova_context.get_admin_context()
- node = db.bm_node_get_by_node_uuid(context, nodename)
- dic = self._node_resource(node)
- return dic
+ resource = {}
+ try:
+ node = db.bm_node_get_by_node_uuid(context, nodename)
+ resource = self._node_resource(node)
+ except exception.NodeNotFoundByUUID:
+ pass
+ return resource
def ensure_filtering_rules_for_instance(self, instance_ref, network_info):
self.firewall_driver.setup_basic_filtering(instance_ref, network_info)
diff --git a/nova/virt/baremetal/pxe.py b/nova/virt/baremetal/pxe.py
index 813f95c05..5d97298ca 100644
--- a/nova/virt/baremetal/pxe.py
+++ b/nova/virt/baremetal/pxe.py
@@ -27,7 +27,7 @@ from oslo.config import cfg
from nova.compute import instance_types
from nova import exception
-from nova.openstack.common.db.sqlalchemy import session as db_session
+from nova.openstack.common.db import exception as db_exc
from nova.openstack.common import fileutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
@@ -148,14 +148,14 @@ def build_network_config(network_info):
return network_config
-def get_deploy_aki_id(instance):
- return instance.get('extra_specs', {}).\
- get('deploy_kernel_id', CONF.baremetal.deploy_kernel)
+def get_deploy_aki_id(instance_type):
+ return instance_type.get('extra_specs', {}).\
+ get('baremetal:deploy_kernel_id', CONF.baremetal.deploy_kernel)
-def get_deploy_ari_id(instance):
- return instance.get('extra_specs', {}).\
- get('deploy_ramdisk_id', CONF.baremetal.deploy_ramdisk)
+def get_deploy_ari_id(instance_type):
+ return instance_type.get('extra_specs', {}).\
+ get('baremetal:deploy_ramdisk_id', CONF.baremetal.deploy_ramdisk)
def get_image_dir_path(instance):
@@ -196,13 +196,13 @@ def get_pxe_mac_path(mac):
)
-def get_tftp_image_info(instance):
+def get_tftp_image_info(instance, instance_type):
"""Generate the paths for tftp files for this instance
Raises NovaException if
- instance does not contain kernel_id or ramdisk_id
- deploy_kernel_id or deploy_ramdisk_id can not be read from
- instance['extra_specs'] and defaults are not set
+ instance_type['extra_specs'] and defaults are not set
"""
image_info = {
@@ -214,8 +214,8 @@ def get_tftp_image_info(instance):
try:
image_info['kernel'][0] = str(instance['kernel_id'])
image_info['ramdisk'][0] = str(instance['ramdisk_id'])
- image_info['deploy_kernel'][0] = get_deploy_aki_id(instance)
- image_info['deploy_ramdisk'][0] = get_deploy_ari_id(instance)
+ image_info['deploy_kernel'][0] = get_deploy_aki_id(instance_type)
+ image_info['deploy_ramdisk'][0] = get_deploy_ari_id(instance_type)
except KeyError as e:
pass
@@ -237,8 +237,8 @@ def get_tftp_image_info(instance):
class PXE(base.NodeDriver):
"""PXE bare metal driver."""
- def __init__(self):
- super(PXE, self).__init__()
+ def __init__(self, virtapi):
+ super(PXE, self).__init__(virtapi)
def _collect_mac_addresses(self, context, node):
macs = set()
@@ -341,7 +341,9 @@ class PXE(base.NodeDriver):
def cache_images(self, context, node, instance,
admin_password, image_meta, injected_files, network_info):
"""Prepare all the images for this instance."""
- tftp_image_info = get_tftp_image_info(instance)
+ instance_type = self.virtapi.instance_type_get(
+ context, instance['instance_type_id'])
+ tftp_image_info = get_tftp_image_info(instance, instance_type)
self._cache_tftp_images(context, instance, tftp_image_info)
self._cache_image(context, instance, image_meta)
@@ -374,7 +376,9 @@ class PXE(base.NodeDriver):
./pxelinux.cfg/
{mac} -> ../{uuid}/config
"""
- image_info = get_tftp_image_info(instance)
+ instance_type = self.virtapi.instance_type_get(
+ context, instance['instance_type_id'])
+ image_info = get_tftp_image_info(instance, instance_type)
(root_mb, swap_mb) = get_partition_sizes(instance)
pxe_config_file_path = get_pxe_config_file_path(instance)
image_file_path = get_image_file_path(instance)
@@ -416,8 +420,14 @@ class PXE(base.NodeDriver):
except exception.NodeNotFound:
pass
+ # NOTE(danms): the instance_type extra_specs do not need to be
+ # present/correct at deactivate time, so pass something empty
+ # to avoid an extra lookup
+ instance_type = dict(extra_specs={
+ 'baremetal:deploy_ramdisk_id': 'ignore',
+ 'baremetal:deploy_kernel_id': 'ignore'})
try:
- image_info = get_tftp_image_info(instance)
+ image_info = get_tftp_image_info(instance, instance_type)
except exception.NovaException:
pass
else:
@@ -428,7 +438,7 @@ class PXE(base.NodeDriver):
bm_utils.unlink_without_raise(get_pxe_config_file_path(instance))
try:
macs = self._collect_mac_addresses(context, node)
- except db_session.DBError:
+ except db_exc.DBError:
pass
else:
for mac in macs:
diff --git a/nova/virt/baremetal/virtual_power_driver.py b/nova/virt/baremetal/virtual_power_driver.py
index a18a2f9d3..d3f612ddd 100644
--- a/nova/virt/baremetal/virtual_power_driver.py
+++ b/nova/virt/baremetal/virtual_power_driver.py
@@ -31,8 +31,11 @@ opts = [
cfg.StrOpt('virtual_power_ssh_host',
default='',
help='ip or name to virtual power host'),
+ cfg.StrOpt('virtual_power_ssh_port',
+ default='22',
+ help='Port to use for ssh to virtual power host'),
cfg.StrOpt('virtual_power_type',
- default='vbox',
+ default='virsh',
help='base command to use for virtual power(vbox,virsh)'),
cfg.StrOpt('virtual_power_host_user',
default='',
@@ -40,6 +43,10 @@ opts = [
cfg.StrOpt('virtual_power_host_pass',
default='',
help='password for virtual power host_user'),
+ cfg.StrOpt('virtual_power_host_key',
+ default=None,
+ help='ssh key for virtual power host_user'),
+
]
baremetal_vp = cfg.OptGroup(name='baremetal',
@@ -101,13 +108,17 @@ class VirtualPowerManager(base.PowerManager):
_('virtual_power_host_user not defined. Can not Start'))
if not CONF.baremetal.virtual_power_host_pass:
- raise exception.NovaException(
- _('virtual_power_host_pass not defined. Can not Start'))
+ # it is ok to not have a password if you have a keyfile
+ if CONF.baremetal.virtual_power_host_key is None:
+ raise exception.NovaException(
+ _('virtual_power_host_pass/key not set. Can not Start'))
_conn = connection.Connection(
CONF.baremetal.virtual_power_ssh_host,
CONF.baremetal.virtual_power_host_user,
- CONF.baremetal.virtual_power_host_pass)
+ CONF.baremetal.virtual_power_host_pass,
+ CONF.baremetal.virtual_power_ssh_port,
+ CONF.baremetal.virtual_power_host_key)
return _conn
def _set_connection(self):
diff --git a/nova/virt/disk/vfs/guestfs.py b/nova/virt/disk/vfs/guestfs.py
index 11cf9d098..985858a0d 100644
--- a/nova/virt/disk/vfs/guestfs.py
+++ b/nova/virt/disk/vfs/guestfs.py
@@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from eventlet import tpool
import guestfs
from nova import exception
@@ -93,7 +94,7 @@ class VFSGuestFS(vfs.VFS):
def setup(self):
LOG.debug(_("Setting up appliance for %(imgfile)s %(imgfmt)s") %
{'imgfile': self.imgfile, 'imgfmt': self.imgfmt})
- self.handle = guestfs.GuestFS()
+ self.handle = tpool.Proxy(guestfs.GuestFS())
try:
self.handle.add_drive_opts(self.imgfile, format=self.imgfmt)
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index bc53aa88a..11c65519c 100755
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -36,7 +36,7 @@ driver_opts = [
help='Driver to use for controlling virtualization. Options '
'include: libvirt.LibvirtDriver, xenapi.XenAPIDriver, '
'fake.FakeDriver, baremetal.BareMetalDriver, '
- 'vmwareapi.VMWareESXDriver'),
+ 'vmwareapi.VMwareESXDriver, vmwareapi.VMwareVCDriver'),
cfg.StrOpt('default_ephemeral_format',
default=None,
help='The default format an ephemeral_volume will be '
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 5545dcf96..58f303efc 100755
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -321,7 +321,7 @@ class FakeDriver(driver.ComputeDriver):
disk and ram.
"""
if nodename not in _FAKE_NODES:
- raise exception.NovaException("node %s is not found" % nodename)
+ return {}
dic = {'vcpus': 1,
'memory_mb': 8192,
@@ -470,3 +470,6 @@ class FakeVirtAPI(virtapi.VirtAPI):
def agent_build_get_by_triple(self, context, hypervisor, os, architecture):
return db.agent_build_get_by_triple(context,
hypervisor, os, architecture)
+
+ def instance_type_get(self, context, instance_type_id):
+ return db.instance_type_get(context, instance_type_id)
diff --git a/nova/virt/firewall.py b/nova/virt/firewall.py
index a36beb7f0..7e133135d 100644
--- a/nova/virt/firewall.py
+++ b/nova/virt/firewall.py
@@ -149,6 +149,10 @@ class IptablesFirewallDriver(FirewallDriver):
self.network_infos = {}
self.basically_filtered = False
+ # Flags for DHCP request rule
+ self.dhcp_create = False
+ self.dhcp_created = False
+
self.iptables.ipv4['filter'].add_chain('sg-fallback')
self.iptables.ipv4['filter'].add_rule('sg-fallback', '-j DROP')
self.iptables.ipv6['filter'].add_chain('sg-fallback')
@@ -191,6 +195,17 @@ class IptablesFirewallDriver(FirewallDriver):
LOG.debug(_('Filters added to instance'), instance=instance)
self.refresh_provider_fw_rules()
LOG.debug(_('Provider Firewall Rules refreshed'), instance=instance)
+ # Ensure that DHCP request rule is updated if necessary
+ if (self.dhcp_create and not self.dhcp_created):
+ self.iptables.ipv4['filter'].add_rule(
+ 'INPUT',
+ '-s 0.0.0.0/32 -d 255.255.255.255/32 '
+ '-p udp -m udp --sport 68 --dport 67 -j ACCEPT')
+ self.iptables.ipv4['filter'].add_rule(
+ 'FORWARD',
+ '-s 0.0.0.0/32 -d 255.255.255.255/32 '
+ '-p udp -m udp --sport 68 --dport 67 -j ACCEPT')
+ self.dhcp_created = True
self.iptables.apply()
def _create_filter(self, ips, chain_name):
@@ -272,6 +287,7 @@ class IptablesFirewallDriver(FirewallDriver):
if dhcp_server:
ipv4_rules.append('-s %s -p udp --sport 67 --dport 68 '
'-j ACCEPT' % (dhcp_server,))
+ self.dhcp_create = True
def _do_project_network_rules(self, ipv4_rules, ipv6_rules, network_info):
# make sure this is legacy nw_info
diff --git a/nova/virt/hyperv/driver.py b/nova/virt/hyperv/driver.py
index aac47deef..289f3c4b6 100755
--- a/nova/virt/hyperv/driver.py
+++ b/nova/virt/hyperv/driver.py
@@ -57,9 +57,10 @@ class HyperVDriver(driver.ComputeDriver):
block_device_info=None):
self._vmops.reboot(instance, network_info, reboot_type)
- def destroy(self, instance, network_info=None, cleanup=True,
+ def destroy(self, instance, network_info, block_device_info=None,
destroy_disks=True):
- self._vmops.destroy(instance, network_info, cleanup, destroy_disks)
+ self._vmops.destroy(instance, network_info, block_device_info,
+ destroy_disks)
def get_info(self, instance):
return self._vmops.get_info(instance)
@@ -112,9 +113,6 @@ class HyperVDriver(driver.ComputeDriver):
post_method, recover_method,
block_migration, migrate_data)
- def compare_cpu(self, cpu_info):
- return self._livemigrationops.compare_cpu(cpu_info)
-
def pre_live_migration(self, context, instance, block_device_info,
network_info, migrate_data=None):
self._livemigrationops.pre_live_migration(context, instance,
@@ -134,14 +132,19 @@ class HyperVDriver(driver.ComputeDriver):
src_compute_info, dst_compute_info,
block_migration=False,
disk_over_commit=False):
- pass
+ return self._livemigrationops.check_can_live_migrate_destination(
+ ctxt, instance_ref, src_compute_info, dst_compute_info,
+ block_migration, disk_over_commit)
def check_can_live_migrate_destination_cleanup(self, ctxt,
dest_check_data):
- pass
+ self._livemigrationops.check_can_live_migrate_destination_cleanup(
+ ctxt, dest_check_data)
- def check_can_live_migrate_source(self, ctxt, instance, dest_check_data):
- pass
+ def check_can_live_migrate_source(self, ctxt, instance_ref,
+ dest_check_data):
+ return self._livemigrationops.check_can_live_migrate_source(
+ ctxt, instance_ref, dest_check_data)
def plug_vifs(self, instance, network_info):
LOG.debug(_("plug_vifs called"), instance=instance)
diff --git a/nova/virt/hyperv/imagecache.py b/nova/virt/hyperv/imagecache.py
index 93ea32b25..5d68bab61 100644
--- a/nova/virt/hyperv/imagecache.py
+++ b/nova/virt/hyperv/imagecache.py
@@ -19,15 +19,21 @@ Image caching and management.
"""
import os
+from nova.compute import instance_types
+from nova.openstack.common import excutils
from nova.openstack.common import lockutils
from nova.openstack.common import log as logging
from nova.virt.hyperv import pathutils
from nova.virt.hyperv import vhdutils
from nova.virt.hyperv import vmutils
from nova.virt import images
+from oslo.config import cfg
LOG = logging.getLogger(__name__)
+CONF = cfg.CONF
+CONF.import_opt('use_cow_images', 'nova.virt.driver')
+
class ImageCache(object):
def __init__(self):
@@ -36,12 +42,59 @@ class ImageCache(object):
def _validate_vhd_image(self, vhd_path):
try:
- self._vhdutils.get_vhd_info(vhd_path)
+ self._vhdutils.validate_vhd(vhd_path)
except Exception as ex:
LOG.exception(ex)
raise vmutils.HyperVException(_('The image is not a valid VHD: %s')
% vhd_path)
+ def _get_root_vhd_size_gb(self, instance):
+ try:
+ # In case of resizes we need the old root disk size
+ old_instance_type = instance_types.extract_instance_type(
+ instance, prefix='old_')
+ return old_instance_type['root_gb']
+ except KeyError:
+ return instance['root_gb']
+
+ def _resize_and_cache_vhd(self, instance, vhd_path):
+ vhd_info = self._vhdutils.get_vhd_info(vhd_path)
+ vhd_size = vhd_info['MaxInternalSize']
+
+ root_vhd_size_gb = self._get_root_vhd_size_gb(instance)
+ root_vhd_size = root_vhd_size_gb * 1024 ** 3
+
+ if root_vhd_size < vhd_size:
+ raise vmutils.HyperVException(_("Cannot resize the image to a "
+ "size smaller than the VHD max. "
+ "internal size: %(vhd_size)s. "
+ "Requested disk size: "
+ "%(root_vhd_size)s") % locals())
+ if root_vhd_size > vhd_size:
+ path_parts = os.path.splitext(vhd_path)
+ resized_vhd_path = '%s_%s%s' % (path_parts[0],
+ root_vhd_size_gb,
+ path_parts[1])
+
+ @lockutils.synchronized(resized_vhd_path, 'nova-')
+ def copy_and_resize_vhd():
+ if not self._pathutils.exists(resized_vhd_path):
+ try:
+ LOG.debug(_("Copying VHD %(vhd_path)s to "
+ "%(resized_vhd_path)s") % locals())
+ self._pathutils.copyfile(vhd_path, resized_vhd_path)
+ LOG.debug(_("Resizing VHD %(resized_vhd_path)s to new "
+ "size %(root_vhd_size)s") % locals())
+ self._vhdutils.resize_vhd(resized_vhd_path,
+ root_vhd_size)
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ if self._pathutils.exists(resized_vhd_path):
+ self._pathutils.remove(resized_vhd_path)
+
+ copy_and_resize_vhd()
+ return resized_vhd_path
+
def get_cached_image(self, context, instance):
image_id = instance['image_ref']
@@ -51,10 +104,22 @@ class ImageCache(object):
@lockutils.synchronized(vhd_path, 'nova-')
def fetch_image_if_not_existing():
if not self._pathutils.exists(vhd_path):
- images.fetch(context, image_id, vhd_path,
- instance['user_id'],
- instance['project_id'])
- self._validate_vhd_image(vhd_path)
+ try:
+ images.fetch(context, image_id, vhd_path,
+ instance['user_id'],
+ instance['project_id'])
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ if self._pathutils.exists(vhd_path):
+ self._pathutils.remove(vhd_path)
fetch_image_if_not_existing()
+
+ if CONF.use_cow_images:
+ # Resize the base VHD image as it's not possible to resize a
+ # differencing VHD.
+ resized_vhd_path = self._resize_and_cache_vhd(instance, vhd_path)
+ if resized_vhd_path:
+ return resized_vhd_path
+
return vhd_path
diff --git a/nova/virt/hyperv/livemigrationops.py b/nova/virt/hyperv/livemigrationops.py
index dca5de0cc..94f6f74d8 100644
--- a/nova/virt/hyperv/livemigrationops.py
+++ b/nova/virt/hyperv/livemigrationops.py
@@ -76,6 +76,18 @@ class LiveMigrationOps(object):
LOG.debug(_("post_live_migration_at_destination called"),
instance=instance_ref)
- def compare_cpu(self, cpu_info):
- LOG.debug(_("compare_cpu called %s"), cpu_info)
- return True
+ def check_can_live_migrate_destination(self, ctxt, instance_ref,
+ src_compute_info, dst_compute_info,
+ block_migration=False,
+ disk_over_commit=False):
+ LOG.debug(_("check_can_live_migrate_destination called"), instance_ref)
+ return {}
+
+ def check_can_live_migrate_destination_cleanup(self, ctxt,
+ dest_check_data):
+ LOG.debug(_("check_can_live_migrate_destination_cleanup called"))
+
+ def check_can_live_migrate_source(self, ctxt, instance_ref,
+ dest_check_data):
+ LOG.debug(_("check_can_live_migrate_source called"), instance_ref)
+ return dest_check_data
diff --git a/nova/virt/hyperv/migrationops.py b/nova/virt/hyperv/migrationops.py
index 8d5b5e90c..07bf453e5 100644
--- a/nova/virt/hyperv/migrationops.py
+++ b/nova/virt/hyperv/migrationops.py
@@ -137,16 +137,15 @@ class MigrationOps(object):
self._revert_migration_files(instance_name)
if self._volumeops.ebs_root_in_block_devices(block_device_info):
- boot_vhd_path = None
+ root_vhd_path = None
else:
- boot_vhd_path = self._pathutils.get_vhd_path(instance_name)
+ root_vhd_path = self._pathutils.get_vhd_path(instance_name)
self._vmops.create_instance(instance, network_info, block_device_info,
- boot_vhd_path)
+ root_vhd_path)
self._vmops.power_on(instance)
def _merge_base_vhd(self, diff_vhd_path, base_vhd_path):
-
base_vhd_copy_path = os.path.join(os.path.dirname(diff_vhd_path),
os.path.basename(base_vhd_path))
try:
@@ -183,10 +182,6 @@ class MigrationOps(object):
def _check_base_disk(self, context, instance, diff_vhd_path,
src_base_disk_path):
- base_disk_file_name = os.path.basename(src_base_disk_path)
- if os.path.splitext(base_disk_file_name)[0] != instance["image_ref"]:
- raise vmutils.HyperVException(_("Unexpected base VHD path"))
-
base_vhd_path = self._imagecache.get_cached_image(context, instance)
# If the location of the base host differs between source
@@ -206,28 +201,28 @@ class MigrationOps(object):
instance_name = instance['name']
if self._volumeops.ebs_root_in_block_devices(block_device_info):
- boot_vhd_path = None
+ root_vhd_path = None
else:
- boot_vhd_path = self._pathutils.get_vhd_path(instance_name)
- if not self._pathutils.exists(boot_vhd_path):
+ root_vhd_path = self._pathutils.get_vhd_path(instance_name)
+ if not self._pathutils.exists(root_vhd_path):
raise vmutils.HyperVException(_("Cannot find boot VHD "
- "file: %s") % boot_vhd_path)
+ "file: %s") % root_vhd_path)
- vhd_info = self._vhdutils.get_vhd_info(boot_vhd_path)
+ vhd_info = self._vhdutils.get_vhd_info(root_vhd_path)
src_base_disk_path = vhd_info.get("ParentPath")
if src_base_disk_path:
- self._check_base_disk(context, instance, boot_vhd_path,
+ self._check_base_disk(context, instance, root_vhd_path,
src_base_disk_path)
if resize_instance:
curr_size = vhd_info['MaxInternalSize']
- new_size = instance['root_gb'] * 1024 * 1024 * 1024
+ new_size = instance['root_gb'] * 1024 ** 3
if new_size < curr_size:
raise vmutils.HyperVException(_("Cannot resize a VHD to a "
"smaller size"))
elif new_size > curr_size:
- self._resize_vhd(boot_vhd_path, new_size)
+ self._resize_vhd(root_vhd_path, new_size)
self._vmops.create_instance(instance, network_info, block_device_info,
- boot_vhd_path)
+ root_vhd_path)
self._vmops.power_on(instance)
diff --git a/nova/virt/hyperv/pathutils.py b/nova/virt/hyperv/pathutils.py
index 1297cd1ed..6c57b8f82 100644
--- a/nova/virt/hyperv/pathutils.py
+++ b/nova/virt/hyperv/pathutils.py
@@ -18,9 +18,9 @@
import os
import shutil
-from oslo.config import cfg
-
+from eventlet.green import subprocess
from nova.openstack.common import log as logging
+from oslo.config import cfg
LOG = logging.getLogger(__name__)
@@ -35,7 +35,7 @@ hyperv_opts = [
]
CONF = cfg.CONF
-CONF.register_opts(hyperv_opts, 'HYPERV')
+CONF.register_opts(hyperv_opts, 'hyperv')
CONF.import_opt('instances_path', 'nova.compute.manager')
@@ -58,10 +58,17 @@ class PathUtils(object):
os.rename(src, dest)
def copyfile(self, src, dest):
- shutil.copyfile(src, dest)
+ self.copy(src, dest)
def copy(self, src, dest):
- shutil.copy(src, dest)
+ # With large files this is 2x-3x faster than shutil.copy(src, dest),
+ # especially when copying to a UNC target.
+ # shutil.copyfileobj(...) with a proper buffer is better than
+ # shutil.copy(...) but still 20% slower than a shell copy.
+ # It can be replaced with Win32 API calls to avoid the process
+ # spawning overhead.
+ if subprocess.call(['cmd.exe', '/C', 'copy', '/Y', src, dest]):
+ raise IOError(_('The file copy from %(src)s to %(dest)s failed'))
def rmtree(self, path):
shutil.rmtree(path)
@@ -70,8 +77,8 @@ class PathUtils(object):
local_instance_path = os.path.normpath(CONF.instances_path)
if remote_server:
- if CONF.HYPERV.instances_path_share:
- path = CONF.HYPERV.instances_path_share
+ if CONF.hyperv.instances_path_share:
+ path = CONF.hyperv.instances_path_share
else:
# Use an administrative share
path = local_instance_path.replace(':', '$')
diff --git a/nova/virt/hyperv/vhdutils.py b/nova/virt/hyperv/vhdutils.py
index 1e529807d..c21799051 100644
--- a/nova/virt/hyperv/vhdutils.py
+++ b/nova/virt/hyperv/vhdutils.py
@@ -31,6 +31,13 @@ class VHDUtils(object):
if sys.platform == 'win32':
self._conn = wmi.WMI(moniker='//./root/virtualization')
+ def validate_vhd(self, vhd_path):
+ image_man_svc = self._conn.Msvm_ImageManagementService()[0]
+
+ (job_path, ret_val) = image_man_svc.ValidateVirtualHardDisk(
+ Path=vhd_path)
+ self._vmutils.check_ret_val(ret_val, job_path)
+
def create_differencing_vhd(self, path, parent_path):
image_man_svc = self._conn.Msvm_ImageManagementService()[0]
diff --git a/nova/virt/hyperv/vif.py b/nova/virt/hyperv/vif.py
index d49441cee..8cf401908 100644
--- a/nova/virt/hyperv/vif.py
+++ b/nova/virt/hyperv/vif.py
@@ -29,11 +29,12 @@ hyperv_opts = [
default=None,
help='External virtual switch Name, '
'if not provided, the first external virtual '
- 'switch is used'),
+ 'switch is used',
+ deprecated_group='DEFAULT'),
]
CONF = cfg.CONF
-CONF.register_opts(hyperv_opts)
+CONF.register_opts(hyperv_opts, 'hyperv')
LOG = logging.getLogger(__name__)
@@ -69,7 +70,7 @@ class HyperVNovaNetworkVIFDriver(HyperVBaseVIFDriver):
def plug(self, instance, vif):
vswitch_path = self._netutils.get_external_vswitch(
- CONF.vswitch_name)
+ CONF.hyperv.vswitch_name)
vm_name = instance['name']
LOG.debug(_('Creating vswitch port for instance: %s') % vm_name)
diff --git a/nova/virt/hyperv/vmops.py b/nova/virt/hyperv/vmops.py
index c7a4e5468..230c5ea40 100644
--- a/nova/virt/hyperv/vmops.py
+++ b/nova/virt/hyperv/vmops.py
@@ -44,22 +44,26 @@ hyperv_opts = [
cfg.BoolOpt('limit_cpu_features',
default=False,
help='Required for live migration among '
- 'hosts with different CPU features'),
+ 'hosts with different CPU features',
+ deprecated_group='DEFAULT'),
cfg.BoolOpt('config_drive_inject_password',
default=False,
- help='Sets the admin password in the config drive image'),
+ help='Sets the admin password in the config drive image',
+ deprecated_group='DEFAULT'),
cfg.StrOpt('qemu_img_cmd',
default="qemu-img.exe",
help='qemu-img is used to convert between '
- 'different image types'),
+ 'different image types',
+ deprecated_group='DEFAULT'),
cfg.BoolOpt('config_drive_cdrom',
default=False,
help='Attaches the Config Drive image as a cdrom drive '
- 'instead of a disk drive')
+ 'instead of a disk drive',
+ deprecated_group='DEFAULT')
]
CONF = cfg.CONF
-CONF.register_opts(hyperv_opts)
+CONF.register_opts(hyperv_opts, 'hyperv')
CONF.import_opt('use_cow_images', 'nova.virt.driver')
CONF.import_opt('network_api_class', 'nova.network')
@@ -111,19 +115,39 @@ class VMOps(object):
'num_cpu': info['NumberOfProcessors'],
'cpu_time': info['UpTime']}
- def _create_boot_vhd(self, context, instance):
+ def _create_root_vhd(self, context, instance):
base_vhd_path = self._imagecache.get_cached_image(context, instance)
- boot_vhd_path = self._pathutils.get_vhd_path(instance['name'])
-
- if CONF.use_cow_images:
- LOG.debug(_("Creating differencing VHD. Parent: "
- "%(base_vhd_path)s, Target: %(boot_vhd_path)s")
- % locals())
- self._vhdutils.create_differencing_vhd(boot_vhd_path,
- base_vhd_path)
- else:
- self._pathutils.copyfile(base_vhd_path, boot_vhd_path)
- return boot_vhd_path
+ root_vhd_path = self._pathutils.get_vhd_path(instance['name'])
+
+ try:
+ if CONF.use_cow_images:
+ LOG.debug(_("Creating differencing VHD. Parent: "
+ "%(base_vhd_path)s, Target: %(root_vhd_path)s")
+ % locals())
+ self._vhdutils.create_differencing_vhd(root_vhd_path,
+ base_vhd_path)
+ else:
+ LOG.debug(_("Copying VHD image %(base_vhd_path)s to target: "
+ "%(root_vhd_path)s") % locals())
+ self._pathutils.copyfile(base_vhd_path, root_vhd_path)
+
+ base_vhd_info = self._vhdutils.get_vhd_info(base_vhd_path)
+ base_vhd_size = base_vhd_info['MaxInternalSize']
+ root_vhd_size = instance['root_gb'] * 1024 ** 3
+
+ if root_vhd_size < base_vhd_size:
+ raise vmutils.HyperVException(_("Cannot resize a VHD to a "
+ "smaller size"))
+ elif root_vhd_size > base_vhd_size:
+ LOG.debug(_("Resizing VHD %(root_vhd_path)s to new "
+ "size %(root_vhd_size)s") % locals())
+ self._vhdutils.resize_vhd(root_vhd_path, root_vhd_size)
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ if self._pathutils.exists(root_vhd_path):
+ self._pathutils.remove(root_vhd_path)
+
+ return root_vhd_path
def spawn(self, context, instance, image_meta, injected_files,
admin_password, network_info, block_device_info=None):
@@ -135,13 +159,13 @@ class VMOps(object):
raise exception.InstanceExists(name=instance_name)
if self._volumeops.ebs_root_in_block_devices(block_device_info):
- boot_vhd_path = None
+ root_vhd_path = None
else:
- boot_vhd_path = self._create_boot_vhd(context, instance)
+ root_vhd_path = self._create_root_vhd(context, instance)
try:
self.create_instance(instance, network_info, block_device_info,
- boot_vhd_path)
+ root_vhd_path)
if configdrive.required_by(instance):
self._create_config_drive(instance, injected_files,
@@ -154,17 +178,17 @@ class VMOps(object):
raise vmutils.HyperVException(_('Spawn instance failed'))
def create_instance(self, instance, network_info,
- block_device_info, boot_vhd_path):
+ block_device_info, root_vhd_path):
instance_name = instance['name']
self._vmutils.create_vm(instance_name,
instance['memory_mb'],
instance['vcpus'],
- CONF.limit_cpu_features)
+ CONF.hyperv.limit_cpu_features)
- if boot_vhd_path:
+ if root_vhd_path:
self._vmutils.attach_ide_drive(instance_name,
- boot_vhd_path,
+ root_vhd_path,
0,
0,
constants.IDE_DISK)
@@ -173,7 +197,7 @@ class VMOps(object):
self._volumeops.attach_volumes(block_device_info,
instance_name,
- boot_vhd_path is None)
+ root_vhd_path is None)
for vif in network_info:
LOG.debug(_('Creating nic for instance: %s'), instance_name)
@@ -190,7 +214,7 @@ class VMOps(object):
LOG.info(_('Using config drive for instance: %s'), instance=instance)
extra_md = {}
- if admin_password and CONF.config_drive_inject_password:
+ if admin_password and CONF.hyperv.config_drive_inject_password:
extra_md['admin_pass'] = admin_password
inst_md = instance_metadata.InstanceMetadata(instance,
@@ -211,11 +235,11 @@ class VMOps(object):
LOG.error(_('Creating config drive failed with error: %s'),
e, instance=instance)
- if not CONF.config_drive_cdrom:
+ if not CONF.hyperv.config_drive_cdrom:
drive_type = constants.IDE_DISK
configdrive_path = os.path.join(instance_path,
'configdrive.vhd')
- utils.execute(CONF.qemu_img_cmd,
+ utils.execute(CONF.hyperv.qemu_img_cmd,
'convert',
'-f',
'raw',
@@ -238,10 +262,10 @@ class VMOps(object):
def _delete_disk_files(self, instance_name):
self._pathutils.get_instance_dir(instance_name,
- create_dir=False,
- remove_dir=True)
+ create_dir=False,
+ remove_dir=True)
- def destroy(self, instance, network_info=None, cleanup=True,
+ def destroy(self, instance, network_info=None, block_device_info=None,
destroy_disks=True):
instance_name = instance['name']
LOG.info(_("Got request to destroy instance: %s"), instance_name)
diff --git a/nova/virt/hyperv/volumeops.py b/nova/virt/hyperv/volumeops.py
index 0d12b93a2..3542a6194 100644
--- a/nova/virt/hyperv/volumeops.py
+++ b/nova/virt/hyperv/volumeops.py
@@ -33,20 +33,24 @@ from nova.virt.hyperv import volumeutilsv2
LOG = logging.getLogger(__name__)
hyper_volumeops_opts = [
- cfg.IntOpt('hyperv_attaching_volume_retry_count',
+ cfg.IntOpt('volume_attach_retry_count',
default=10,
- help='The number of times we retry on attaching volume '),
- cfg.IntOpt('hyperv_wait_between_attach_retry',
+ help='The number of times to retry to attach a volume',
+ deprecated_name='hyperv_attaching_volume_retry_count',
+ deprecated_group='DEFAULT'),
+ cfg.IntOpt('volume_attach_retry_interval',
default=5,
- help='The seconds to wait between an volume '
- 'attachment attempt'),
+ help='Interval between volume attachment attempts, in seconds',
+ deprecated_name='hyperv_wait_between_attach_retry',
+ deprecated_group='DEFAULT'),
cfg.BoolOpt('force_volumeutils_v1',
default=False,
- help='Force volumeutils v1'),
+ help='Force volumeutils v1',
+ deprecated_group='DEFAULT'),
]
CONF = cfg.CONF
-CONF.register_opts(hyper_volumeops_opts)
+CONF.register_opts(hyper_volumeops_opts, 'hyperv')
CONF.import_opt('my_ip', 'nova.netconf')
@@ -63,7 +67,7 @@ class VolumeOps(object):
self._default_root_device = 'vda'
def _get_volume_utils(self):
- if(not CONF.force_volumeutils_v1 and
+ if(not CONF.hyperv.force_volumeutils_v1 and
self._hostutils.get_windows_version() >= 6.2):
return volumeutilsv2.VolumeUtilsV2()
else:
@@ -171,12 +175,12 @@ class VolumeOps(object):
LOG.debug(_('Device number: %(device_number)s, '
'target lun: %(target_lun)s') % locals())
#Finding Mounted disk drive
- for i in range(1, CONF.hyperv_attaching_volume_retry_count):
+ for i in range(1, CONF.hyperv.volume_attach_retry_count):
mounted_disk_path = self._vmutils.get_mounted_disk_by_drive_number(
device_number)
if mounted_disk_path:
break
- time.sleep(CONF.hyperv_wait_between_attach_retry)
+ time.sleep(CONF.hyperv.volume_attach_retry_interval)
if not mounted_disk_path:
raise vmutils.HyperVException(_('Unable to find a mounted disk '
diff --git a/nova/virt/hyperv/volumeutils.py b/nova/virt/hyperv/volumeutils.py
index 6d623fca7..e77b463fe 100644
--- a/nova/virt/hyperv/volumeutils.py
+++ b/nova/virt/hyperv/volumeutils.py
@@ -66,8 +66,10 @@ class VolumeUtils(basevolumeutils.BaseVolumeUtils):
self.execute('iscsicli.exe ' + 'LisTargets')
#Sending login
self.execute('iscsicli.exe ' + 'qlogintarget ' + target_iqn)
- #Waiting the disk to be mounted. Research this to avoid sleep
- time.sleep(CONF.hyperv_wait_between_attach_retry)
+ #Waiting the disk to be mounted.
+ #TODO(pnavarro): Check for the operation to end instead of
+ #relying on a timeout
+ time.sleep(CONF.hyperv.volume_attach_retry_interval)
def logout_storage_target(self, target_iqn):
"""Logs out storage target through its session id."""
diff --git a/nova/virt/hyperv/volumeutilsv2.py b/nova/virt/hyperv/volumeutilsv2.py
index 2dc86c2e0..79d2d1876 100644
--- a/nova/virt/hyperv/volumeutilsv2.py
+++ b/nova/virt/hyperv/volumeutilsv2.py
@@ -56,8 +56,10 @@ class VolumeUtilsV2(basevolumeutils.BaseVolumeUtils):
target = self._conn_storage.MSFT_iSCSITarget
target.Connect(NodeAddress=target_iqn,
IsPersistent=True)
- #Waiting the disk to be mounted. Research this
- time.sleep(CONF.hyperv_wait_between_attach_retry)
+ #Waiting the disk to be mounted.
+ #TODO(pnavarro): Check for the operation to end instead of
+ #relying on a timeout
+ time.sleep(CONF.hyperv.volume_attach_retry_interval)
def logout_storage_target(self, target_iqn):
"""Logs out storage target through its session id."""
diff --git a/nova/virt/libvirt/__init__.py b/nova/virt/libvirt/__init__.py
index 535d6c729..784cf92d3 100644
--- a/nova/virt/libvirt/__init__.py
+++ b/nova/virt/libvirt/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
diff --git a/nova/virt/libvirt/blockinfo.py b/nova/virt/libvirt/blockinfo.py
index 09e3809d9..3e4b3995c 100644
--- a/nova/virt/libvirt/blockinfo.py
+++ b/nova/virt/libvirt/blockinfo.py
@@ -201,7 +201,7 @@ def get_disk_bus_for_device_type(virt_type,
# Prefer a disk bus set against the image first of all
if image_meta:
- key = device_type + "_bus"
+ key = "hw_" + device_type + "_bus"
disk_bus = image_meta.get('properties', {}).get(key)
if disk_bus is not None:
if not is_disk_bus_valid_for_virt(virt_type, disk_bus):
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 5ba97a8a4..9858e0af2 100755
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -714,10 +714,10 @@ class LibvirtDriver(driver.ComputeDriver):
is_okay = True
if not is_okay:
- LOG.error(_("Error from libvirt during destroy. "
- "Code=%(errcode)s Error=%(e)s") %
- locals(), instance=instance)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.error(_("Error from libvirt during destroy. "
+ "Code=%(errcode)s Error=%(e)s") %
+ locals(), instance=instance)
def _wait_for_destroy(expected_domid):
"""Called at an interval until the VM is gone."""
@@ -787,11 +787,11 @@ class LibvirtDriver(driver.ComputeDriver):
pass
virt_dom.undefine()
except libvirt.libvirtError as e:
- errcode = e.get_error_code()
- LOG.error(_("Error from libvirt during undefine. "
- "Code=%(errcode)s Error=%(e)s") %
- locals(), instance=instance)
- raise
+ with excutils.save_and_reraise_exception():
+ errcode = e.get_error_code()
+ LOG.error(_("Error from libvirt during undefine. "
+ "Code=%(errcode)s Error=%(e)s") %
+ locals(), instance=instance)
def _cleanup(self, instance, network_info, block_device_info,
destroy_disks):
@@ -1667,13 +1667,14 @@ class LibvirtDriver(driver.ComputeDriver):
"'%(ex)s'") % {'path': dirpath, 'ex': str(e)})
hasDirectIO = False
else:
+ with excutils.save_and_reraise_exception():
+ LOG.error(_("Error on '%(path)s' while checking "
+ "direct I/O: '%(ex)s'") %
+ {'path': dirpath, 'ex': str(e)})
+ except Exception, e:
+ with excutils.save_and_reraise_exception():
LOG.error(_("Error on '%(path)s' while checking direct I/O: "
"'%(ex)s'") % {'path': dirpath, 'ex': str(e)})
- raise
- except Exception, e:
- LOG.error(_("Error on '%(path)s' while checking direct I/O: "
- "'%(ex)s'") % {'path': dirpath, 'ex': str(e)})
- raise
finally:
try:
os.unlink(testfile)
@@ -1850,9 +1851,10 @@ class LibvirtDriver(driver.ComputeDriver):
try:
cdb.make_drive(configdrive_path)
except exception.ProcessExecutionError, e:
- LOG.error(_('Creating config drive failed with error: %s'),
- e, instance=instance)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.error(_('Creating config drive failed '
+ 'with error: %s'),
+ e, instance=instance)
# File injection
elif CONF.libvirt_inject_partition != -2:
@@ -1892,10 +1894,10 @@ class LibvirtDriver(driver.ComputeDriver):
use_cow=CONF.use_cow_images,
mandatory=('files',))
except Exception as e:
- LOG.error(_('Error injecting data into image '
- '%(img_id)s (%(e)s)') % locals(),
- instance=instance)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.error(_('Error injecting data into image '
+ '%(img_id)s (%(e)s)') % locals(),
+ instance=instance)
if CONF.libvirt_type == 'uml':
libvirt_utils.chown(image('disk').path, 'root')
@@ -1986,7 +1988,7 @@ class LibvirtDriver(driver.ComputeDriver):
return cpu
- def get_guest_disk_config(self, instance, name, disk_mapping,
+ def get_guest_disk_config(self, instance, name, disk_mapping, inst_type,
image_type=None):
image = self.image_backend.image(instance,
name,
@@ -1996,7 +1998,7 @@ class LibvirtDriver(driver.ComputeDriver):
disk_info['dev'],
disk_info['type'],
self.disk_cachemode,
- instance['extra_specs'])
+ inst_type['extra_specs'])
def get_guest_storage_config(self, instance, image_meta,
disk_info,
@@ -2019,24 +2021,28 @@ class LibvirtDriver(driver.ComputeDriver):
if rescue:
diskrescue = self.get_guest_disk_config(instance,
'disk.rescue',
- disk_mapping)
+ disk_mapping,
+ inst_type)
devices.append(diskrescue)
diskos = self.get_guest_disk_config(instance,
'disk',
- disk_mapping)
+ disk_mapping,
+ inst_type)
devices.append(diskos)
else:
if 'disk' in disk_mapping:
diskos = self.get_guest_disk_config(instance,
'disk',
- disk_mapping)
+ disk_mapping,
+ inst_type)
devices.append(diskos)
if 'disk.local' in disk_mapping:
disklocal = self.get_guest_disk_config(instance,
'disk.local',
- disk_mapping)
+ disk_mapping,
+ inst_type)
devices.append(disklocal)
self.virtapi.instance_update(
nova_context.get_admin_context(), instance['uuid'],
@@ -2048,13 +2054,14 @@ class LibvirtDriver(driver.ComputeDriver):
diskeph = self.get_guest_disk_config(
instance,
blockinfo.get_eph_disk(eph),
- disk_mapping)
+ disk_mapping, inst_type)
devices.append(diskeph)
if 'disk.swap' in disk_mapping:
diskswap = self.get_guest_disk_config(instance,
'disk.swap',
- disk_mapping)
+ disk_mapping,
+ inst_type)
devices.append(diskswap)
self.virtapi.instance_update(
nova_context.get_admin_context(), instance['uuid'],
@@ -2072,6 +2079,7 @@ class LibvirtDriver(driver.ComputeDriver):
diskconfig = self.get_guest_disk_config(instance,
'disk.config',
disk_mapping,
+ inst_type,
'raw')
devices.append(diskconfig)
@@ -2100,7 +2108,10 @@ class LibvirtDriver(driver.ComputeDriver):
'ramdisk_id' if a ramdisk is needed for the rescue image and
'kernel_id' if a kernel is needed for the rescue image.
"""
- inst_type = instance['instance_type']
+
+ inst_type = self.virtapi.instance_type_get(
+ nova_context.get_admin_context(read_deleted='yes'),
+ instance['instance_type_id'])
inst_path = libvirt_utils.get_instance_path(instance)
disk_mapping = disk_info['mapping']
@@ -2112,7 +2123,7 @@ class LibvirtDriver(driver.ComputeDriver):
guest.vcpus = inst_type['vcpus']
quota_items = ['cpu_shares', 'cpu_period', 'cpu_quota']
- for key, value in instance['extra_specs'].iteritems():
+ for key, value in inst_type['extra_specs'].iteritems():
if key in quota_items:
setattr(guest, key, value)
@@ -2941,9 +2952,9 @@ class LibvirtDriver(driver.ComputeDriver):
try:
ret = self._conn.compareCPU(cpu.to_xml(), 0)
except libvirt.libvirtError, e:
- ret = e.message
- LOG.error(m % locals())
- raise
+ with excutils.save_and_reraise_exception():
+ ret = e.message
+ LOG.error(m % locals())
if ret <= 0:
LOG.error(m % locals())
@@ -3496,6 +3507,11 @@ class LibvirtDriver(driver.ComputeDriver):
instance)
timer.start(interval=0.5).wait()
+ def _cleanup_failed_migration(self, inst_base):
+ """Make sure that a failed migrate doesn't prevent us from rolling
+ back in a revert."""
+ shutil.rmtree(inst_base)
+
def finish_revert_migration(self, instance, network_info,
block_device_info=None):
LOG.debug(_("Starting finish_revert_migration"),
@@ -3503,7 +3519,15 @@ class LibvirtDriver(driver.ComputeDriver):
inst_base = libvirt_utils.get_instance_path(instance)
inst_base_resize = inst_base + "_resize"
- utils.execute('mv', inst_base_resize, inst_base)
+
+ # NOTE(danms): if we're recovering from a failed migration,
+ # make sure we don't have a left-over same-host base directory
+ # that would conflict. Also, don't fail on the rename if the
+ # failure happened early.
+ if os.path.exists(inst_base_resize):
+ if os.path.exists(inst_base):
+ self._cleanup_failed_migration(inst_base)
+ utils.execute('mv', inst_base_resize, inst_base)
disk_info = blockinfo.get_disk_info(CONF.libvirt_type,
instance,
diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py
index cf3fd9d26..808560b54 100755
--- a/nova/virt/libvirt/utils.py
+++ b/nova/virt/libvirt/utils.py
@@ -5,7 +5,7 @@
# All Rights Reserved.
# Copyright (c) 2010 Citrix Systems, Inc.
# Copyright (c) 2011 Piston Cloud Computing, Inc
-# Copyright (c) 2011 OpenStack LLC
+# Copyright (c) 2011 OpenStack Foundation
# (c) Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py
index 8d9664751..68b0505aa 100644
--- a/nova/virt/libvirt/vif.py
+++ b/nova/virt/libvirt/vif.py
@@ -2,7 +2,7 @@
# Copyright (C) 2011 Midokura KK
# Copyright (C) 2011 Nicira, Inc
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -101,7 +101,8 @@ class LibvirtBaseVIFDriver(object):
# If the user has specified a 'vif_model' against the
# image then honour that model
if image_meta:
- vif_model = image_meta.get('properties', {}).get('vif_model')
+ vif_model = image_meta.get('properties',
+ {}).get('hw_vif_model')
if vif_model is not None:
model = vif_model
diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py
index 1af29fa56..81ac0ac42 100644
--- a/nova/virt/libvirt/volume.py
+++ b/nova/virt/libvirt/volume.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# (c) Copyright 2013 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
diff --git a/nova/virt/powervm/__init__.py b/nova/virt/powervm/__init__.py
index 1b63f8310..88f3adc91 100644
--- a/nova/virt/powervm/__init__.py
+++ b/nova/virt/powervm/__init__.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
diff --git a/nova/virt/powervm/blockdev.py b/nova/virt/powervm/blockdev.py
index 6c8e4b9a5..75f90e327 100644
--- a/nova/virt/powervm/blockdev.py
+++ b/nova/virt/powervm/blockdev.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
@@ -20,6 +20,7 @@ import re
from oslo.config import cfg
+from nova.compute import task_states
from nova.image import glance
from nova.openstack.common import excutils
from nova.openstack.common import log as logging
@@ -69,13 +70,15 @@ class PowerVMDiskAdapter(object):
pass
def create_image_from_volume(self, device_name, context,
- image_id, image_meta):
+ image_id, image_meta, update_task_state):
"""Capture the contents of a volume and upload to glance
:param device_name: device in /dev/ to capture
:param context: nova context for operation
:param image_id: image reference to pre-created image in glance
:param image_meta: metadata for new image
+ :param update_task_state: Function reference that allows for updates
+ to the instance task state
"""
pass
@@ -196,14 +199,18 @@ class PowerVMLocalVolumeAdapter(PowerVMDiskAdapter):
return {'device_name': disk_name}
def create_image_from_volume(self, device_name, context,
- image_id, image_meta):
+ image_id, image_meta, update_task_state):
"""Capture the contents of a volume and upload to glance
:param device_name: device in /dev/ to capture
:param context: nova context for operation
:param image_id: image reference to pre-created image in glance
:param image_meta: metadata for new image
+ :param update_task_state: Function reference that allows for updates
+ to the instance task state.
"""
+ # Updating instance task state before capturing instance as a file
+ update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD)
# do the disk copy
dest_file_path = common.aix_path_join(CONF.powervm_img_remote_path,
@@ -219,6 +226,12 @@ class PowerVMLocalVolumeAdapter(PowerVMDiskAdapter):
glance_service, image_id = glance.get_remote_image_service(
context, image_id)
+ # Updating instance task state before uploading image
+ # Snapshot will complete but instance state will not change
+ # to none in compute manager if expected state is not correct
+ update_task_state(task_state=task_states.IMAGE_UPLOADING,
+ expected_state=task_states.IMAGE_PENDING_UPLOAD)
+
# upload snapshot file to glance
with open(snapshot_file_path, 'r') as img_file:
glance_service.update(context,
diff --git a/nova/virt/powervm/command.py b/nova/virt/powervm/command.py
index 25cc2c6cd..eec7fc2d3 100644
--- a/nova/virt/powervm/command.py
+++ b/nova/virt/powervm/command.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
diff --git a/nova/virt/powervm/common.py b/nova/virt/powervm/common.py
index d98d4ae89..b36fa57f3 100644
--- a/nova/virt/powervm/common.py
+++ b/nova/virt/powervm/common.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
@@ -31,11 +31,12 @@ LOG = logging.getLogger(__name__)
class Connection(object):
- def __init__(self, host, username, password, port=22):
+ def __init__(self, host, username, password, port=22, keyfile=None):
self.host = host
self.username = username
self.password = password
self.port = port
+ self.keyfile = keyfile
def ssh_connect(connection):
@@ -51,7 +52,8 @@ def ssh_connect(connection):
ssh.connect(connection.host,
username=connection.username,
password=connection.password,
- port=connection.port)
+ port=connection.port,
+ key_filename=connection.keyfile)
return ssh
except Exception:
LOG.exception(_('Connection error connecting PowerVM manager'))
diff --git a/nova/virt/powervm/constants.py b/nova/virt/powervm/constants.py
index 0d1e0892e..9c691352d 100644
--- a/nova/virt/powervm/constants.py
+++ b/nova/virt/powervm/constants.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
diff --git a/nova/virt/powervm/driver.py b/nova/virt/powervm/driver.py
index 892ac34ef..7484e91b6 100755
--- a/nova/virt/powervm/driver.py
+++ b/nova/virt/powervm/driver.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
@@ -41,11 +41,13 @@ powervm_opts = [
help='PowerVM manager user password',
secret=True),
cfg.StrOpt('powervm_img_remote_path',
- default=None,
- help='PowerVM image remote path'),
+ default='/home/padmin',
+ help='PowerVM image remote path where images will be moved.'
+ ' Make sure this path can fit your biggest image in glance'),
cfg.StrOpt('powervm_img_local_path',
- default=None,
- help='Local directory to download glance images to')
+ default='/tmp',
+ help='Local directory to download glance images to.'
+ ' Make sure this path can fit your biggest image in glance')
]
CONF = cfg.CONF
@@ -124,13 +126,15 @@ class PowerVMDriver(driver.ComputeDriver):
{'hostname': hostname, 'ip_addr': ip_addr})
return ip_addr
- def snapshot(self, context, instance, image_id):
+ def snapshot(self, context, instance, image_id, update_task_state):
"""Snapshots the specified instance.
:param context: security context
:param instance: Instance object as returned by DB layer.
:param image_id: Reference to a pre-created image that will
hold the snapshot.
+ :param update_task_state: Function reference that allows for updates
+ to the instance task state.
"""
snapshot_start = time.time()
@@ -159,7 +163,7 @@ class PowerVMDriver(driver.ComputeDriver):
# disk capture and glance upload
self._powervm.capture_image(context, instance, image_id,
- new_snapshot_meta)
+ new_snapshot_meta, update_task_state)
snapshot_time = time.time() - snapshot_start
inst_name = instance['name']
@@ -296,7 +300,13 @@ class PowerVMDriver(driver.ComputeDriver):
block_device_info=None):
"""Finish reverting a resize, powering back on the instance."""
- # undo instance rename and start
new_name = self._get_resize_name(instance['name'])
- self._powervm._operator.rename_lpar(new_name, instance['name'])
+
+ # Make sure we don't have a failed same-host migration still
+ # hanging around
+ if self.instance_exists(new_name):
+ if self.instance_exists(instance['name']):
+ self._powervm.destroy(instance['name'])
+ # undo instance rename and start
+ self._powervm._operator.rename_lpar(new_name, instance['name'])
self._powervm.power_on(instance['name'])
diff --git a/nova/virt/powervm/exception.py b/nova/virt/powervm/exception.py
index 50e08eaea..ae9a2be72 100644
--- a/nova/virt/powervm/exception.py
+++ b/nova/virt/powervm/exception.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
diff --git a/nova/virt/powervm/lpar.py b/nova/virt/powervm/lpar.py
index 907818ca8..66d5df6f5 100644
--- a/nova/virt/powervm/lpar.py
+++ b/nova/virt/powervm/lpar.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
diff --git a/nova/virt/powervm/operator.py b/nova/virt/powervm/operator.py
index 87f596765..08db2d18a 100644
--- a/nova/virt/powervm/operator.py
+++ b/nova/virt/powervm/operator.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 IBM
+# Copyright 2012 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
@@ -251,13 +251,16 @@ class PowerVMOperator(object):
LOG.warn(_("During destroy, LPAR instance '%s' was not found on "
"PowerVM system.") % instance_name)
- def capture_image(self, context, instance, image_id, image_meta):
+ def capture_image(self, context, instance, image_id, image_meta,
+ update_task_state):
"""Capture the root disk for a snapshot
:param context: nova context for this operation
:param instance: instance information to capture the image from
:param image_id: uuid of pre-created snapshot image
:param image_meta: metadata to upload with captured image
+ :param update_task_state: Function reference that allows for updates
+ to the instance task state.
"""
lpar = self._operator.get_lpar(instance['name'])
previous_state = lpar['state']
@@ -275,7 +278,7 @@ class PowerVMOperator(object):
# do capture and upload
self._disk_adapter.create_image_from_volume(
- disk_name, context, image_id, image_meta)
+ disk_name, context, image_id, image_meta, update_task_state)
# restart instance if it was running before
if previous_state == 'Running':
diff --git a/nova/virt/virtapi.py b/nova/virt/virtapi.py
index 53cbabc30..963b3c788 100644
--- a/nova/virt/virtapi.py
+++ b/nova/virt/virtapi.py
@@ -97,3 +97,10 @@ class VirtAPI(object):
:param architecture: agent architecture
"""
raise NotImplementedError()
+
+ def instance_type_get(self, context, instance_type_id):
+ """Get information about an instance type
+ :param context: security context
+ :param instance_type_id: the id of the instance type in question
+ """
+ raise NotImplementedError()
diff --git a/nova/virt/vmwareapi/__init__.py b/nova/virt/vmwareapi/__init__.py
index 1b9732b44..3e3a35a68 100644
--- a/nova/virt/vmwareapi/__init__.py
+++ b/nova/virt/vmwareapi/__init__.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py
index 5e48f4cd3..eeec4c5c2 100755
--- a/nova/virt/vmwareapi/driver.py
+++ b/nova/virt/vmwareapi/driver.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/error_util.py b/nova/virt/vmwareapi/error_util.py
index aff890b0c..9527c51d1 100644
--- a/nova/virt/vmwareapi/error_util.py
+++ b/nova/virt/vmwareapi/error_util.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/fake.py b/nova/virt/vmwareapi/fake.py
index 692e5f253..45d4702e2 100644
--- a/nova/virt/vmwareapi/fake.py
+++ b/nova/virt/vmwareapi/fake.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/host.py b/nova/virt/vmwareapi/host.py
index 9d11901d6..95d86311c 100644
--- a/nova/virt/vmwareapi/host.py
+++ b/nova/virt/vmwareapi/host.py
@@ -1,5 +1,5 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
+# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
# Copyright (c) 2012 VMware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -135,6 +135,8 @@ class HostState(object):
data["hypervisor_type"] = summary.config.product.name
data["hypervisor_version"] = summary.config.product.version
data["hypervisor_hostname"] = self._host_name
+ data["supported_instances"] = [('i686', 'vmware', 'hvm'),
+ ('x86_64', 'vmware', 'hvm')]
self._stats = data
return data
diff --git a/nova/virt/vmwareapi/io_util.py b/nova/virt/vmwareapi/io_util.py
index 6a50c4d6e..9a4c2c1f7 100644
--- a/nova/virt/vmwareapi/io_util.py
+++ b/nova/virt/vmwareapi/io_util.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/network_util.py b/nova/virt/vmwareapi/network_util.py
index c353e66fd..b2b774cc6 100644
--- a/nova/virt/vmwareapi/network_util.py
+++ b/nova/virt/vmwareapi/network_util.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/read_write_util.py b/nova/virt/vmwareapi/read_write_util.py
index 5dcdc6fdb..89f5f6908 100644
--- a/nova/virt/vmwareapi/read_write_util.py
+++ b/nova/virt/vmwareapi/read_write_util.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/vif.py b/nova/virt/vmwareapi/vif.py
index 1a28ca35e..4479a926f 100644
--- a/nova/virt/vmwareapi/vif.py
+++ b/nova/virt/vmwareapi/vif.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/vim.py b/nova/virt/vmwareapi/vim.py
index f3a47315b..2b6829d54 100644
--- a/nova/virt/vmwareapi/vim.py
+++ b/nova/virt/vmwareapi/vim.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/vim_util.py b/nova/virt/vmwareapi/vim_util.py
index 7b138d716..e131e007d 100644
--- a/nova/virt/vmwareapi/vim_util.py
+++ b/nova/virt/vmwareapi/vim_util.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py
index bc3bd8a9c..9fb8e9bd5 100644
--- a/nova/virt/vmwareapi/vm_util.py
+++ b/nova/virt/vmwareapi/vm_util.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py
index 9b136f351..911edbe97 100644
--- a/nova/virt/vmwareapi/vmops.py
+++ b/nova/virt/vmwareapi/vmops.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/vmwareapi/vmware_images.py b/nova/virt/vmwareapi/vmware_images.py
index e8510b36e..e789b508a 100644
--- a/nova/virt/vmwareapi/vmware_images.py
+++ b/nova/virt/vmwareapi/vmware_images.py
@@ -2,7 +2,7 @@
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/virt/xenapi/agent.py b/nova/virt/xenapi/agent.py
index 0be26a241..1fe6dff7e 100644
--- a/nova/virt/xenapi/agent.py
+++ b/nova/virt/xenapi/agent.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2010 Citrix Systems, Inc.
-# Copyright 2010-2012 OpenStack LLC.
+# Copyright 2010-2012 OpenStack Foundation
#
# 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/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py
index 347d36255..decaed2b0 100755
--- a/nova/virt/xenapi/driver.py
+++ b/nova/virt/xenapi/driver.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2010 Citrix Systems, Inc.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
#
# 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/virt/xenapi/host.py b/nova/virt/xenapi/host.py
index 6ddc76494..0abcf7444 100644
--- a/nova/virt/xenapi/host.py
+++ b/nova/virt/xenapi/host.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 Citrix Systems, Inc.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
#
# 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/virt/xenapi/imageupload/glance.py b/nova/virt/xenapi/imageupload/glance.py
index 5ea75db16..d306e06b0 100644
--- a/nova/virt/xenapi/imageupload/glance.py
+++ b/nova/virt/xenapi/imageupload/glance.py
@@ -1,4 +1,4 @@
-# Copyright 2013 OpenStack, LLC
+# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -13,8 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
+import time
+
from oslo.config import cfg
+from nova import exception
from nova.image import glance
import nova.openstack.common.log as logging
from nova.virt.xenapi import vm_utils
@@ -22,6 +25,7 @@ from nova.virt.xenapi import vm_utils
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
+CONF.import_opt('glance_num_retries', 'nova.image.glance')
class GlanceStore(object):
@@ -32,24 +36,49 @@ class GlanceStore(object):
"""
# NOTE(sirp): Currently we only support uploading images as VHD, there
# is no RAW equivalent (yet)
- LOG.debug(_("Asking xapi to upload to glance %(vdi_uuids)s as"
- " ID %(image_id)s"), locals(), instance=instance)
-
+ max_attempts = CONF.glance_num_retries + 1
+ sleep_time = 0.5
glance_api_servers = glance.get_api_servers()
- glance_host, glance_port, glance_use_ssl = glance_api_servers.next()
-
properties = {
'auto_disk_config': instance['auto_disk_config'],
'os_type': instance['os_type'] or CONF.default_os_type,
}
- params = {'vdi_uuids': vdi_uuids,
- 'image_id': image_id,
- 'glance_host': glance_host,
- 'glance_port': glance_port,
- 'glance_use_ssl': glance_use_ssl,
- 'sr_path': vm_utils.get_sr_path(session),
- 'auth_token': getattr(context, 'auth_token', None),
- 'properties': properties}
+ for attempt_num in xrange(1, max_attempts + 1):
+
+ (glance_host,
+ glance_port,
+ glance_use_ssl) = glance_api_servers.next()
+
+ try:
+
+ params = {'vdi_uuids': vdi_uuids,
+ 'image_id': image_id,
+ 'glance_host': glance_host,
+ 'glance_port': glance_port,
+ 'glance_use_ssl': glance_use_ssl,
+ 'sr_path': vm_utils.get_sr_path(session),
+ 'auth_token': getattr(context, 'auth_token', None),
+ 'properties': properties}
+
+ LOG.debug(_("Asking xapi to upload to glance %(vdi_uuids)s as"
+ " ID %(image_id)s"
+ " glance server: %(glance_host)s:%(glance_port)d"
+ " attempt %(attempt_num)d/%(max_attempts)d"),
+ locals(), instance=instance)
+
+ return session.call_plugin_serialized('glance',
+ 'upload_vhd',
+ **params)
+
+ except session.XenAPI.Failure as exc:
+ _type, _method, error = exc.details[:3]
+ if error == 'RetryableError':
+ LOG.error(_('upload_vhd failed: %r') %
+ (exc.details[3:],))
+ else:
+ raise
+ time.sleep(sleep_time)
+ sleep_time = min(2 * sleep_time, 15)
- session.call_plugin_serialized('glance', 'upload_vhd', **params)
+ raise exception.CouldNotUploadImage(image_id=image_id)
diff --git a/nova/virt/xenapi/pool.py b/nova/virt/xenapi/pool.py
index ee39fb2da..5080d8308 100644
--- a/nova/virt/xenapi/pool.py
+++ b/nova/virt/xenapi/pool.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 Citrix Systems, Inc.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
#
# 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/virt/xenapi/pool_states.py b/nova/virt/xenapi/pool_states.py
index 138f84831..f2ec02c1d 100644
--- a/nova/virt/xenapi/pool_states.py
+++ b/nova/virt/xenapi/pool_states.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/virt/xenapi/vif.py b/nova/virt/xenapi/vif.py
index f0b9eebbe..66c418e85 100644
--- a/nova/virt/xenapi/vif.py
+++ b/nova/virt/xenapi/vif.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright (C) 2011 Nicira, Inc
# All Rights Reserved.
#
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index 28e83198f..26bd9d268 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -2,7 +2,7 @@
# Copyright (c) 2010 Citrix Systems, Inc.
# Copyright 2011 Piston Cloud Computing, Inc.
-# Copyright 2012 OpenStack, LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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
@@ -37,6 +37,7 @@ from oslo.config import cfg
from nova.api.metadata import base as instance_metadata
from nova import block_device
+from nova.compute import instance_types
from nova.compute import power_state
from nova.compute import task_states
from nova import exception
@@ -208,7 +209,7 @@ def create_vm(session, instance, name_label, kernel, ramdisk,
3. Using hardware virtualization
"""
- instance_type = instance['instance_type']
+ instance_type = instance_types.extract_instance_type(instance)
mem = str(long(instance_type['memory_mb']) * 1024 * 1024)
vcpus = str(instance_type['vcpus'])
@@ -321,8 +322,7 @@ def _is_vm_shutdown(session, vm_ref):
def ensure_free_mem(session, instance):
- inst_type_id = instance['instance_type_id']
- instance_type = instance['instance_type']
+ instance_type = instance_types.extract_instance_type(instance)
mem = long(instance_type['memory_mb']) * 1024 * 1024
host = session.get_xenapi_host()
host_free_mem = long(session.call_xenapi("host.compute_free_memory",
@@ -1143,7 +1143,7 @@ def _check_vdi_size(context, session, instance, vdi_uuid):
# FIXME(jk0): this was copied directly from compute.manager.py, let's
# refactor this to a common area
- instance_type = instance['instance_type']
+ instance_type = instance_types.extract_instance_type(instance)
allowed_size_gb = instance_type['root_gb']
allowed_size_bytes = allowed_size_gb * 1024 * 1024 * 1024
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index bf3f631b3..56dd5bd3d 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2010 Citrix Systems, Inc.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
#
# 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
@@ -29,6 +29,7 @@ from oslo.config import cfg
from nova import block_device
from nova.compute import api as compute
+from nova.compute import instance_types
from nova.compute import power_state
from nova.compute import task_states
from nova.compute import vm_mode
@@ -214,12 +215,22 @@ class VMOps(object):
name_label = self._get_orig_vm_name_label(instance)
vm_ref = vm_utils.lookup(self._session, name_label)
- # Remove the '-orig' suffix (which was added in case the resized VM
- # ends up on the source host, common during testing)
- name_label = instance['name']
- vm_utils.set_vm_name_label(self._session, vm_ref, name_label)
-
- self._attach_mapped_block_devices(instance, block_device_info)
+ # NOTE(danms): if we're reverting migration in the failure case,
+ # make sure we don't have a conflicting vm still running here,
+ # as might be the case in a failed migrate-to-same-host situation
+ new_ref = vm_utils.lookup(self._session, instance['name'])
+ if vm_ref is not None:
+ if new_ref is not None:
+ self._destroy(instance, new_ref)
+ # Remove the '-orig' suffix (which was added in case the
+ # resized VM ends up on the source host, common during
+ # testing)
+ name_label = instance['name']
+ vm_utils.set_vm_name_label(self._session, vm_ref, name_label)
+ self._attach_mapped_block_devices(instance, block_device_info)
+ elif new_ref is not None:
+ # We crashed before the -orig backup was made
+ vm_ref = new_ref
self._start(instance, vm_ref)
@@ -511,7 +522,7 @@ class VMOps(object):
def _attach_disks(self, instance, vm_ref, name_label, vdis,
disk_image_type, admin_password=None, files=None):
ctx = nova_context.get_admin_context()
- instance_type = instance['instance_type']
+ instance_type = instance_types.extract_instance_type(instance)
# Attach (required) root disk
if disk_image_type == vm_utils.ImageType.DISK_ISO:
@@ -638,7 +649,8 @@ class VMOps(object):
agent.resetnetwork()
# Set VCPU weight
- vcpu_weight = instance['instance_type']['vcpu_weight']
+ instance_type = instance_types.extract_instance_type(instance)
+ vcpu_weight = instance_type['vcpu_weight']
if vcpu_weight is not None:
LOG.debug(_("Setting VCPU weight"), instance=instance)
self._session.call_xenapi('VM.add_to_VCPUs_params', vm_ref,
diff --git a/nova/virt/xenapi/volume_utils.py b/nova/virt/xenapi/volume_utils.py
index edf92cee9..7c77b5e0f 100644
--- a/nova/virt/xenapi/volume_utils.py
+++ b/nova/virt/xenapi/volume_utils.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2010 Citrix Systems, Inc.
-# Copyright (c) 2013 Openstack, LLC.
+# Copyright (c) 2013 OpenStack Foundation
#
# 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/virt/xenapi/volumeops.py b/nova/virt/xenapi/volumeops.py
index 88119e10d..d3c3046b7 100644
--- a/nova/virt/xenapi/volumeops.py
+++ b/nova/virt/xenapi/volumeops.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2010 Citrix Systems, Inc.
-# Copyright (c) 2013 Openstack, LLC.
+# Copyright (c) 2013 OpenStack Foundation
#
# 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/vnc/__init__.py b/nova/vnc/__init__.py
index 6a4c2eb4a..f8256beef 100644
--- a/nova/vnc/__init__.py
+++ b/nova/vnc/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010 OpenStack, LLC.
+# Copyright (c) 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/nova/vnc/xvp_proxy.py b/nova/vnc/xvp_proxy.py
index 3efa23f8b..4331e5b40 100644
--- a/nova/vnc/xvp_proxy.py
+++ b/nova/vnc/xvp_proxy.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 OpenStack, LLC.
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/nova/weights.py b/nova/weights.py
index 981171b3e..7dca2e40d 100644
--- a/nova/weights.py
+++ b/nova/weights.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2012 OpenStack, LLC.
+# Copyright (c) 2011-2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/nova/wsgi.py b/nova/wsgi.py
index 7b85d0a5b..72e464919 100644
--- a/nova/wsgi.py
+++ b/nova/wsgi.py
@@ -2,7 +2,7 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -34,6 +34,7 @@ import webob.dec
import webob.exc
from nova import exception
+from nova.openstack.common import excutils
from nova.openstack.common import log as logging
wsgi_opts = [
@@ -175,9 +176,9 @@ class Server(object):
CONF.tcp_keepidle)
except Exception:
- LOG.error(_("Failed to start %(name)s on %(host)s"
- ":%(port)s with SSL support") % self.__dict__)
- raise
+ with excutils.save_and_reraise_exception():
+ LOG.error(_("Failed to start %(name)s on %(host)s"
+ ":%(port)s with SSL support") % self.__dict__)
wsgi_kwargs = {
'func': eventlet.wsgi.server,
diff --git a/openstack-common.conf b/openstack-common.conf
index 36abed038..a2688fa45 100644
--- a/openstack-common.conf
+++ b/openstack-common.conf
@@ -1,7 +1,7 @@
[DEFAULT]
# The list of modules to copy from openstack-common
-modules=cliutils,context,db,db.api,db.sqlalchemy,excutils,eventlet_backdoor,fileutils,gettextutils,importutils,jsonutils,local,lockutils,log,network_utils,notifier,plugin,policy,rootwrap,setup,timeutils,rpc,uuidutils,install_venv_common,flakes,version,processutils
+modules=cliutils,context,db,excutils,eventlet_backdoor,fileutils,gettextutils,importutils,jsonutils,local,lockutils,log,network_utils,notifier,plugin,policy,rootwrap,setup,timeutils,rpc,uuidutils,install_venv_common,flakes,version,processutils
# The base module to hold the copy of openstack.common
base=nova
diff --git a/plugins/xenserver/networking/etc/init.d/host-rules b/plugins/xenserver/networking/etc/init.d/host-rules
index 798da9552..7f8134c91 100755
--- a/plugins/xenserver/networking/etc/init.d/host-rules
+++ b/plugins/xenserver/networking/etc/init.d/host-rules
@@ -5,7 +5,7 @@
# chkconfig: 2345 85 15
# description: Networking Host Rules for Multi Tenancy Protections
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/plugins/xenserver/networking/etc/init.d/openvswitch-nova b/plugins/xenserver/networking/etc/init.d/openvswitch-nova
index 5f5249d9c..096426b2e 100755
--- a/plugins/xenserver/networking/etc/init.d/openvswitch-nova
+++ b/plugins/xenserver/networking/etc/init.d/openvswitch-nova
@@ -6,7 +6,7 @@
# description: Apply initial OVS flows for Nova
# Copyright 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright (C) 2009, 2010, 2011 Nicira Networks, Inc.
# All Rights Reserved.
#
diff --git a/plugins/xenserver/networking/etc/xensource/scripts/novalib.py b/plugins/xenserver/networking/etc/xensource/scripts/novalib.py
index 0f88e52bb..9189c601f 100644
--- a/plugins/xenserver/networking/etc/xensource/scripts/novalib.py
+++ b/plugins/xenserver/networking/etc/xensource/scripts/novalib.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py b/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py
index dabc5be6b..039cda172 100755
--- a/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py
+++ b/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py
@@ -2,7 +2,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py b/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py
index 6e41e1e19..0aea079ff 100755
--- a/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py
+++ b/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py b/plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py
index 106525a16..26bcd16ce 100755
--- a/plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py
+++ b/plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010-2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/_bittorrent_seeder b/plugins/xenserver/xenapi/etc/xapi.d/plugins/_bittorrent_seeder
index 88262139e..3e566a988 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/_bittorrent_seeder
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/_bittorrent_seeder
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright (c) 2012 Openstack, LLC
+# Copyright (c) 2012 OpenStack Foundation
#
# 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/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
index c83cb1ace..261edd406 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2011 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/bandwidth b/plugins/xenserver/xenapi/etc/xapi.d/plugins/bandwidth
index 4c4538fa4..c488b07bd 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/bandwidth
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/bandwidth
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/bittorrent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/bittorrent
index fef1862b1..8ae93698d 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/bittorrent
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/bittorrent
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright (c) 2012 Openstack, LLC
+# Copyright (c) 2012 Openstack Foundation
#
# 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/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance b/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance
index 924bf10d7..7902f8791 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
# Copyright (c) 2010 Citrix Systems, Inc.
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
@@ -126,14 +126,18 @@ def _upload_tarball(staging_path, image_id, glance_host, glance_port,
url = '%s://%s:%s/v1/images/%s' % (scheme, glance_host, glance_port,
image_id)
logging.info("Writing image data to %s" % url)
- if glance_use_ssl:
- conn = httplib.HTTPSConnection(glance_host, glance_port)
- else:
- conn = httplib.HTTPConnection(glance_host, glance_port)
- # NOTE(sirp): httplib under python2.4 won't accept a file-like object
- # to request
- conn.putrequest('PUT', '/v1/images/%s' % image_id)
+ try:
+ if glance_use_ssl:
+ conn = httplib.HTTPSConnection(glance_host, glance_port)
+ else:
+ conn = httplib.HTTPConnection(glance_host, glance_port)
+
+ # NOTE(sirp): httplib under python2.4 won't accept a file-like object
+ # to request
+ conn.putrequest('PUT', '/v1/images/%s' % image_id)
+ except Exception, error:
+ raise RetryableError(error)
# NOTE(sirp): There is some confusion around OVF. Here's a summary of
# where we currently stand:
@@ -172,12 +176,18 @@ def _upload_tarball(staging_path, image_id, glance_host, glance_port,
def send_chunked_transfer_encoded(chunk):
chunk_len = len(chunk)
callback_data['bytes_written'] += chunk_len
- conn.send("%x\r\n%s\r\n" % (chunk_len, chunk))
+ try:
+ conn.send("%x\r\n%s\r\n" % (chunk_len, chunk))
+ except Exception, error:
+ raise RetryableError(error)
utils.create_tarball(
None, staging_path, callback=send_chunked_transfer_encoded)
- conn.send("0\r\n\r\n") # Chunked-Transfer terminator
+ try:
+ conn.send("0\r\n\r\n") # Chunked-Transfer terminator
+ except Exception, error:
+ raise RetryableError(error)
bytes_written = callback_data['bytes_written']
logging.info("Wrote %d bytes to %s" % (bytes_written, url))
@@ -187,9 +197,11 @@ def _upload_tarball(staging_path, image_id, glance_host, glance_port,
logging.error("Unexpected response while writing image data to %s: "
"Response Status: %i, Response body: %s"
% (url, resp.status, resp.read()))
- raise Exception("Unexpected response [%i] while uploading image [%s] "
+ raise RetryableError("Unexpected response [%i] while uploading "
+ "image [%s] "
"to glance host [%s:%s]"
% (resp.status, image_id, glance_host, glance_port))
+
conn.close()
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/kernel b/plugins/xenserver/xenapi/etc/xapi.d/plugins/kernel
index 32e253cde..3aa5a443e 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/kernel
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/kernel
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
# Copyright (c) 2010 Citrix Systems, Inc.
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/migration b/plugins/xenserver/xenapi/etc/xapi.d/plugins/migration
index 4b6bf8811..6fa95c5e6 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/migration
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/migration
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/utils.py b/plugins/xenserver/xenapi/etc/xapi.d/plugins/utils.py
index 510687d7b..2a5d3d9ae 100644
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/utils.py
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/utils.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
#
# 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/plugins/xenserver/xenapi/etc/xapi.d/plugins/workarounds b/plugins/xenserver/xenapi/etc/xapi.d/plugins/workarounds
index 244939f00..1a11416f1 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/workarounds
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/workarounds
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright (c) 2012 OpenStack, LLC
+# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
index 0319af4d2..9f61b79a9 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
# Copyright 2011 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py
index be873a7e8..9c86b7cb7 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# Copyright (c) 2010 Citrix Systems, Inc.
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010 OpenStack Foundation
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
diff --git a/run_tests.sh b/run_tests.sh
index 2b6eda900..29e723c7f 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -127,10 +127,6 @@ function run_tests {
fi
if [ $coverage -eq 1 ]; then
- # Do not test test_coverage_ext when gathering coverage.
- if [ "x$testrargs" = "x" ]; then
- testrargs="^(?!.*test.*coverage).*$"
- fi
TESTRTESTS="$TESTRTESTS --coverage"
else
TESTRTESTS="$TESTRTESTS --slowest"
diff --git a/tools/conf/extract_opts.py b/tools/conf/extract_opts.py
index 83d99dd19..89f335d9b 100644
--- a/tools/conf/extract_opts.py
+++ b/tools/conf/extract_opts.py
@@ -20,6 +20,7 @@
"""Extracts OpenStack config option info from module(s)."""
+import imp
import os
import re
import socket
@@ -98,7 +99,11 @@ def main(srcfiles):
def _import_module(mod_str):
try:
- return importutils.import_module(mod_str)
+ if mod_str.startswith('bin.'):
+ imp.load_source(mod_str[4:], os.path.join('bin', mod_str[4:]))
+ return sys.modules[mod_str[4:]]
+ else:
+ return importutils.import_module(mod_str)
except (ValueError, AttributeError), err:
return None
except ImportError, ie:
@@ -141,9 +146,9 @@ def _guess_groups(opt, mod_obj):
return 'DEFAULT'
if group is None:
- sys.stderr("Unable to guess what group " + opt.dest +
- " in " + mod_obj.__name__ +
- " is in out of " + ','.join(groups) + "\n")
+ sys.stderr.write("Unable to guess what group " + opt.dest +
+ " in " + mod_obj.__name__ +
+ " is in out of " + ','.join(groups) + "\n")
sys.exit(1)
sys.stderr.write("Guessing that " + opt.dest +
@@ -154,13 +159,17 @@ def _guess_groups(opt, mod_obj):
def _list_opts(obj):
+ def is_opt(o):
+ return (isinstance(o, cfg.Opt) and
+ not isinstance(o, cfg.SubCommandOpt))
+
opts = list()
for attr_str in dir(obj):
attr_obj = getattr(obj, attr_str)
- if isinstance(attr_obj, cfg.Opt):
+ if is_opt(attr_obj):
opts.append(attr_obj)
elif (isinstance(attr_obj, list) and
- all(map(lambda x: isinstance(x, cfg.Opt), attr_obj))):
+ all(map(lambda x: is_opt(x), attr_obj))):
opts.extend(attr_obj)
ret = {}
@@ -199,6 +208,8 @@ def _sanitize_default(s):
"""Set up a reasonably sensible default for pybasedir, my_ip and host."""
if s.startswith(BASEDIR):
return s.replace(BASEDIR, '/usr/lib/python/site-packages')
+ elif BASEDIR in s:
+ return s.replace(BASEDIR, '')
elif s == _get_my_ip():
return '10.0.0.1'
elif s == socket.getfqdn():
@@ -241,6 +252,8 @@ def _print_opt(opt):
print '#%s=%s' % (opt_name, ','.join(opt_default))
elif opt_type == MULTISTROPT:
assert(isinstance(opt_default, list))
+ if not opt_default:
+ opt_default = ['']
for default in opt_default:
print '#%s=%s' % (opt_name, default)
print
diff --git a/tools/conf/generate_sample.sh b/tools/conf/generate_sample.sh
index 25462caa2..283d7a654 100755
--- a/tools/conf/generate_sample.sh
+++ b/tools/conf/generate_sample.sh
@@ -19,7 +19,13 @@
FILES=$(find nova -type f -name "*.py" ! -path "nova/tests/*" -exec \
grep -l "Opt(" {} \; | sort -u)
+BINS=$(echo bin/nova-*)
PYTHONPATH=./:${PYTHONPATH} \
- python $(dirname "$0")/extract_opts.py ${FILES} > \
+ python $(dirname "$0")/extract_opts.py ${FILES} ${BINS} > \
etc/nova/nova.conf.sample
+
+# Remove compiled files created by imp.import_source()
+for bin in ${BINS}; do
+ [ -f ${bin}c ] && rm ${bin}c
+done
diff --git a/tools/db/schema_diff.py b/tools/db/schema_diff.py
index a4bcfeaa8..406a2b665 100755
--- a/tools/db/schema_diff.py
+++ b/tools/db/schema_diff.py
@@ -2,7 +2,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2012 OpenStack LLC.
+# Copyright 2012 OpenStack Foundation
#
# 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/tools/enable-pre-commit-hook.sh b/tools/enable-pre-commit-hook.sh
index f4f73ee77..be1ed27d1 100755
--- a/tools/enable-pre-commit-hook.sh
+++ b/tools/enable-pre-commit-hook.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright 2011 OpenStack LLC
+# Copyright 2011 OpenStack Foundation
#
# 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/tools/esx/guest_tool.py b/tools/esx/guest_tool.py
index 9876be7a4..2c2793010 100644
--- a/tools/esx/guest_tool.py
+++ b/tools/esx/guest_tool.py
@@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
#
# 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/tools/hacking.py b/tools/hacking.py
index 1279e87e9..4e2331054 100755
--- a/tools/hacking.py
+++ b/tools/hacking.py
@@ -29,6 +29,7 @@ import re
import subprocess
import sys
import tokenize
+import traceback
import pep8
@@ -176,9 +177,12 @@ def nova_import_rules(logical_line):
Examples:
Okay: from os import path
+ Okay: from os import path as p
+ Okay: from os import (path as p)
Okay: import os.path
Okay: from nova.compute import rpcapi
N302: from os.path import dirname as dirname2
+ N302: from os.path import (dirname as dirname2)
N303: from os.path import *
N304: from .compute import rpcapi
"""
@@ -186,6 +190,7 @@ def nova_import_rules(logical_line):
# pass the doctest, since the relativity depends on the file's locality
def is_module_for_sure(mod, search_path=sys.path):
+ mod = mod.replace('(', '') # Ignore parentheses
try:
mod_name = mod
while '.' in mod_name:
@@ -201,10 +206,16 @@ def nova_import_rules(logical_line):
# NOTE(vish): the import error might be due
# to a missing dependency
missing = str(exc).split()[-1]
- if missing != mod.split('.')[-1]:
+ if (missing != mod.split('.')[-1] or
+ "cannot import" in str(exc)):
_missingImport.add(missing)
return True
return False
+ except Exception, exc:
+ # NOTE(jogo) don't stack trace if unexpected import error,
+ # log and continue.
+ traceback.print_exc()
+ return False
return True
def is_module(mod):
@@ -302,9 +313,22 @@ def nova_import_no_db_in_virt(logical_line, filename):
yield (0, "N307: nova.db import not allowed in nova/virt/*")
-def in_docstring_position(previous_logical):
- return (previous_logical.startswith("def ") or
- previous_logical.startswith("class "))
+def is_docstring(physical_line, previous_logical):
+ """Return True if found docstring
+ 'A docstring is a string literal that occurs as the first statement in a
+ module, function, class,'
+ http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring
+ """
+ line = physical_line.lstrip()
+ start = max([line.find(i) for i in START_DOCSTRING_TRIPLE])
+ end = max([line[-4:-1] == i for i in END_DOCSTRING_TRIPLE])
+ if (previous_logical.startswith("def ") or
+ previous_logical.startswith("class ")):
+ if start is 0:
+ return True
+ else:
+ # Handle multi line comments
+ return end and start in (-1, len(line) - 4)
def nova_docstring_start_space(physical_line, previous_logical):
@@ -314,6 +338,8 @@ def nova_docstring_start_space(physical_line, previous_logical):
Docstring should not start with space
Okay: def foo():\n '''This is good.'''
+ Okay: def foo():\n a = ''' This is not a docstring.'''
+ Okay: def foo():\n pass\n ''' This is not.'''
N401: def foo():\n ''' This is not.'''
"""
# short circuit so that we don't fail on our own fail test
@@ -324,30 +350,32 @@ def nova_docstring_start_space(physical_line, previous_logical):
# it's important that we determine this is actually a docstring,
# and not a doc block used somewhere after the first line of a
# function def
- if in_docstring_position(previous_logical):
+ if is_docstring(physical_line, previous_logical):
pos = max([physical_line.find(i) for i in START_DOCSTRING_TRIPLE])
- if pos != -1 and len(physical_line) > pos + 4:
- if physical_line[pos + 3] == ' ':
- return (pos, "N401: docstring should not start with"
- " a space")
+ if physical_line[pos + 3] == ' ':
+ return (pos, "N401: docstring should not start with"
+ " a space")
-def nova_docstring_one_line(physical_line):
+def nova_docstring_one_line(physical_line, previous_logical):
r"""Check one line docstring end.
nova HACKING guide recommendation for one line docstring:
A one line docstring looks like this and ends in punctuation.
- Okay: '''This is good.'''
- Okay: '''This is good too!'''
- Okay: '''How about this?'''
- N402: '''This is not'''
- N402: '''Bad punctuation,'''
+ Okay: def foo():\n '''This is good.'''
+ Okay: def foo():\n '''This is good too!'''
+ Okay: def foo():\n '''How about this?'''
+ Okay: def foo():\n a = '''This is not a docstring'''
+ Okay: def foo():\n pass\n '''This is not a docstring'''
+ Okay: class Foo:\n pass\n '''This is not a docstring'''
+ N402: def foo():\n '''This is not'''
+ N402: def foo():\n '''Bad punctuation,'''
+ N402: class Foo:\n '''Bad punctuation,'''
"""
#TODO(jogo) make this apply to multi line docstrings as well
line = physical_line.lstrip()
-
- if line.startswith('"') or line.startswith("'"):
+ if is_docstring(physical_line, previous_logical):
pos = max([line.find(i) for i in START_DOCSTRING_TRIPLE]) # start
end = max([line[-4:-1] == i for i in END_DOCSTRING_TRIPLE]) # end
@@ -356,20 +384,27 @@ def nova_docstring_one_line(physical_line):
return pos, "N402: one line docstring needs punctuation."
-def nova_docstring_multiline_end(physical_line, previous_logical):
+def nova_docstring_multiline_end(physical_line, previous_logical, tokens):
r"""Check multi line docstring end.
nova HACKING guide recommendation for docstring:
Docstring should end on a new line
Okay: '''foobar\nfoo\nbar\n'''
- N403: def foo():\n'''foobar\nfoo\nbar\n d'''\n\n
+ Okay: def foo():\n '''foobar\nfoo\nbar\n'''
+ Okay: class Foo:\n '''foobar\nfoo\nbar\n'''
+ Okay: def foo():\n a = '''not\na\ndocstring'''
+ Okay: def foo():\n pass\n'''foobar\nfoo\nbar\n d'''
+ N403: def foo():\n '''foobar\nfoo\nbar\ndocstring'''
+ N403: class Foo:\n '''foobar\nfoo\nbar\ndocstring'''\n\n
"""
- if in_docstring_position(previous_logical):
+ # if find OP tokens, not a docstring
+ ops = [t for t, _, _, _, _ in tokens if t == tokenize.OP]
+ if (is_docstring(physical_line, previous_logical) and len(tokens) > 0 and
+ len(ops) == 0):
pos = max(physical_line.find(i) for i in END_DOCSTRING_TRIPLE)
- if pos != -1 and len(physical_line) == pos + 4:
- if physical_line.strip() not in START_DOCSTRING_TRIPLE:
- return (pos, "N403: multi line docstring end on new line")
+ if physical_line.strip() not in START_DOCSTRING_TRIPLE:
+ return (pos, "N403: multi line docstring end on new line")
def nova_docstring_multiline_start(physical_line, previous_logical, tokens):
@@ -379,9 +414,10 @@ def nova_docstring_multiline_start(physical_line, previous_logical, tokens):
Docstring should start with A multi line docstring has a one-line summary
Okay: '''foobar\nfoo\nbar\n'''
- N404: def foo():\n'''\nfoo\nbar\n''' \n\n
+ Okay: def foo():\n a = '''\nnot\na docstring\n'''
+ N404: def foo():\n'''\nfoo\nbar\n'''\n\n
"""
- if in_docstring_position(previous_logical):
+ if is_docstring(physical_line, previous_logical):
pos = max([physical_line.find(i) for i in START_DOCSTRING_TRIPLE])
# start of docstring when len(tokens)==0
if len(tokens) == 0 and pos != -1 and len(physical_line) == pos + 4:
@@ -391,7 +427,7 @@ def nova_docstring_multiline_start(physical_line, previous_logical, tokens):
def nova_no_cr(physical_line):
- r"""Check that we only use newlines not cariage returns.
+ r"""Check that we only use newlines not carriage returns.
Okay: import os\nimport sys
# pep8 doesn't yet replace \r in strings, will work on an
@@ -560,7 +596,7 @@ def once_git_check_commit_title():
nova HACKING recommends not referencing a bug or blueprint in first line,
it should provide an accurate description of the change
N801
- N802 Title limited to 50 chars
+ N802 Title limited to 72 chars
"""
#Get title of most recent commit
@@ -585,6 +621,8 @@ def once_git_check_commit_title():
"description of the change, not just a reference to a bug "
"or blueprint" % title.strip())
error = True
+ # HACKING.rst recommends commit titles 50 chars or less, but enforces
+ # a 72 character limit
if len(title.decode('utf-8')) > 72:
print ("N802: git commit title ('%s') should be under 50 chars"
% title.strip())
diff --git a/tools/install_venv.py b/tools/install_venv.py
index 17a0be205..dbc7333ec 100644
--- a/tools/install_venv.py
+++ b/tools/install_venv.py
@@ -4,7 +4,7 @@
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
-# Copyright 2010 OpenStack, LLC
+# Copyright 2010 OpenStack Foundation
# Copyright 2013 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tools/install_venv_common.py b/tools/install_venv_common.py
index fd9076f0e..413065640 100644
--- a/tools/install_venv_common.py
+++ b/tools/install_venv_common.py
@@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 OpenStack, LLC
+# Copyright 2013 OpenStack Foundation
# Copyright 2013 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -185,7 +185,8 @@ class Fedora(Distro):
self.run_command(['sudo', 'yum', 'install', '-y', pkg], **kwargs)
def apply_patch(self, originalfile, patchfile):
- self.run_command(['patch', originalfile, patchfile])
+ self.run_command(['patch', '-N', originalfile, patchfile],
+ check_exit_code=False)
def install_virtualenv(self):
if self.check_cmd('virtualenv'):
diff --git a/tools/patch_tox_venv.py b/tools/patch_tox_venv.py
new file mode 100644
index 000000000..399acbcfc
--- /dev/null
+++ b/tools/patch_tox_venv.py
@@ -0,0 +1,38 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Red Hat, Inc.
+#
+# 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.
+
+import os
+import sys
+
+import install_venv_common as install_venv
+
+
+def main(argv):
+ root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+
+ venv = os.environ['VIRTUAL_ENV']
+
+ pip_requires = os.path.join(root, 'tools', 'pip-requires')
+ test_requires = os.path.join(root, 'tools', 'test-requires')
+ py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1])
+ project = 'Nova'
+ install = install_venv.InstallVenv(root, venv, pip_requires, test_requires,
+ py_version, project)
+ #NOTE(dprince): For Tox we only run post_process (which patches files, etc)
+ install.post_process()
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/tools/pip-requires b/tools/pip-requires
index bb4eb7119..d8b836a29 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -1,5 +1,5 @@
SQLAlchemy>=0.7.8,<=0.7.9
-Cheetah==2.4.4
+Cheetah>=2.4.4
amqplib>=0.6.1
anyjson>=0.2.4
argparse
@@ -7,14 +7,14 @@ boto
eventlet>=0.9.17
kombu>=1.0.4
lxml>=2.3
-routes==1.12.3
+routes>=1.12.3
WebOb==1.2.3
greenlet>=0.3.1
-PasteDeploy==1.5.0
+PasteDeploy>=1.5.0
paste
sqlalchemy-migrate>=0.7.2
netaddr
-suds==0.4
+suds>=0.4
paramiko
pyasn1
Babel>=0.9.6
@@ -22,9 +22,9 @@ iso8601>=0.1.4
httplib2
setuptools_git>=0.4
python-cinderclient>=1.0.1
-python-quantumclient>=2.1
+python-quantumclient>=2.1.2
python-glanceclient>=0.5.0,<2
python-keystoneclient>=0.2.0
stevedore>=0.7
websockify
-http://tarballs.openstack.org/oslo-config/oslo-config-2013.1b4.tar.gz#egg=oslo-config
+http://tarballs.openstack.org/oslo-config/oslo.config-1.1.0b1.tar.gz#egg=oslo.config
diff --git a/tools/xenserver/cleanup_sm_locks.py b/tools/xenserver/cleanup_sm_locks.py
index de455b076..5ccb6e0dd 100755
--- a/tools/xenserver/cleanup_sm_locks.py
+++ b/tools/xenserver/cleanup_sm_locks.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright 2013 OpenStack, LLC
+# Copyright 2013 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/tools/xenserver/vdi_chain_cleanup.py b/tools/xenserver/vdi_chain_cleanup.py
index de1744c5b..b2baca059 100644
--- a/tools/xenserver/vdi_chain_cleanup.py
+++ b/tools/xenserver/vdi_chain_cleanup.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright 2012 OpenStack, LLC
+# Copyright 2012 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/tools/xenserver/vm_vdi_cleaner.py b/tools/xenserver/vm_vdi_cleaner.py
index a842282fa..d2137b8e9 100755
--- a/tools/xenserver/vm_vdi_cleaner.py
+++ b/tools/xenserver/vm_vdi_cleaner.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright 2011 OpenStack, LLC
+# Copyright 2011 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/tox.ini b/tox.ini
index b4b5ccc20..4849eff4e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,7 +8,9 @@ setenv = VIRTUAL_ENV={envdir}
LC_ALL=C
deps = -r{toxinidir}/tools/pip-requires
-r{toxinidir}/tools/test-requires
-commands = python setup.py testr --slowest --testr-args='{posargs}'
+commands =
+ python tools/patch_tox_venv.py
+ python setup.py testr --slowest --testr-args='{posargs}'
[tox:jenkins]
sitepackages = True
@@ -30,7 +32,9 @@ commands = python tools/flakes.py nova
[testenv:cover]
# Also do not run test_coverage_ext tests while gathering coverage as those
# tests conflict with coverage.
+setenv = VIRTUAL_ENV={envdir}
commands =
+ python tools/patch_tox_venv.py
python setup.py testr --coverage \
--testr-args='^(?!.*test.*coverage).*$'