From e96b904fea71159a43afdd28af9f6a5921af0418 Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Mon, 16 May 2011 18:09:26 -0500 Subject: MySQL database tables are using the MyISAM engine. Created migration script to change all current tables to InnoDB. --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index 546c9091f..b17c4f63e 100644 --- a/Authors +++ b/Authors @@ -28,6 +28,7 @@ Gabe Westmaas Hisaharu Ishii Hisaki Ohara Ilya Alekseyev +Jason Cannavale Jason Koelker Jay Pipes Jesse Andrews -- cgit From 2b5652b4ec191d3f31ce35684f0dd86f033416c2 Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Mon, 16 May 2011 18:13:08 -0500 Subject: MySQL database tables are using the MyISAM engine. Created migration script to change all current tables to InnoDB. --- .../versions/017_set_engine_mysql_innodb.py | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/017_set_engine_mysql_innodb.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/017_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/017_set_engine_mysql_innodb.py new file mode 100644 index 000000000..be7ff5abd --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/017_set_engine_mysql_innodb.py @@ -0,0 +1,57 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import MetaData, Table + +meta = MetaData() + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + if migrate_engine.name == "mysql": + migrate_engine.execute("ALTER TABLE auth_tokens Engine=InnoDB") + migrate_engine.execute("ALTER TABLE certificates Engine=InnoDB") + migrate_engine.execute("ALTER TABLE compute_nodes Engine=InnoDB") + migrate_engine.execute("ALTER TABLE console_pools Engine=InnoDB") + migrate_engine.execute("ALTER TABLE consoles Engine=InnoDB") + migrate_engine.execute("ALTER TABLE export_devices Engine=InnoDB") + migrate_engine.execute("ALTER TABLE fixed_ips Engine=InnoDB") + migrate_engine.execute("ALTER TABLE floating_ips Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_actions Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_metadata Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_types Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instances Engine=InnoDB") + migrate_engine.execute("ALTER TABLE iscsi_targets Engine=InnoDB") + migrate_engine.execute("ALTER TABLE key_pairs Engine=InnoDB") + migrate_engine.execute("ALTER TABLE migrate_version Engine=InnoDB") + migrate_engine.execute("ALTER TABLE migrations Engine=InnoDB") + migrate_engine.execute("ALTER TABLE networks Engine=InnoDB") + migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") + migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_group_instance_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_group_rules Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") + migrate_engine.execute("ALTER TABLE services Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_project_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_project_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE users Engine=InnoDB") + migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") + migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") + +def downgrade(migrate_engine): + meta.bind = migrate_engine -- cgit From 3ff9051c2ae60493d39d7e276c61689ffca2ac8d Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 17 May 2011 20:38:02 -0500 Subject: MySQL database tables are using the MyISAM engine. Created migration script to change all current tables to InnoDB, updated version to 019 --- .../versions/017_set_engine_mysql_innodb.py | 57 ---------------------- 1 file changed, 57 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/017_set_engine_mysql_innodb.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/017_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/017_set_engine_mysql_innodb.py deleted file mode 100644 index be7ff5abd..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/017_set_engine_mysql_innodb.py +++ /dev/null @@ -1,57 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 OpenStack LLC. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from sqlalchemy import MetaData, Table - -meta = MetaData() - -def upgrade(migrate_engine): - # Upgrade operations go here. Don't create your own engine; - # bind migrate_engine to your metadata - meta.bind = migrate_engine - if migrate_engine.name == "mysql": - migrate_engine.execute("ALTER TABLE auth_tokens Engine=InnoDB") - migrate_engine.execute("ALTER TABLE certificates Engine=InnoDB") - migrate_engine.execute("ALTER TABLE compute_nodes Engine=InnoDB") - migrate_engine.execute("ALTER TABLE console_pools Engine=InnoDB") - migrate_engine.execute("ALTER TABLE consoles Engine=InnoDB") - migrate_engine.execute("ALTER TABLE export_devices Engine=InnoDB") - migrate_engine.execute("ALTER TABLE fixed_ips Engine=InnoDB") - migrate_engine.execute("ALTER TABLE floating_ips Engine=InnoDB") - migrate_engine.execute("ALTER TABLE instance_actions Engine=InnoDB") - migrate_engine.execute("ALTER TABLE instance_metadata Engine=InnoDB") - migrate_engine.execute("ALTER TABLE instance_types Engine=InnoDB") - migrate_engine.execute("ALTER TABLE instances Engine=InnoDB") - migrate_engine.execute("ALTER TABLE iscsi_targets Engine=InnoDB") - migrate_engine.execute("ALTER TABLE key_pairs Engine=InnoDB") - migrate_engine.execute("ALTER TABLE migrate_version Engine=InnoDB") - migrate_engine.execute("ALTER TABLE migrations Engine=InnoDB") - migrate_engine.execute("ALTER TABLE networks Engine=InnoDB") - migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") - migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_group_instance_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_group_rules Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") - migrate_engine.execute("ALTER TABLE services Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_project_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_project_role_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_role_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE users Engine=InnoDB") - migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") - migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") - -def downgrade(migrate_engine): - meta.bind = migrate_engine -- cgit From d43603e2702f41936a9a85915280b9d773d6c74c Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 17 May 2011 20:38:18 -0500 Subject: MySQL database tables are using the MyISAM engine. Created migration script to change all current tables to InnoDB, updated version to 019 --- .../versions/019_set_engine_mysql_innodb.py | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/019_set_engine_mysql_innodb.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/019_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/019_set_engine_mysql_innodb.py new file mode 100644 index 000000000..be7ff5abd --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/019_set_engine_mysql_innodb.py @@ -0,0 +1,57 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import MetaData, Table + +meta = MetaData() + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + if migrate_engine.name == "mysql": + migrate_engine.execute("ALTER TABLE auth_tokens Engine=InnoDB") + migrate_engine.execute("ALTER TABLE certificates Engine=InnoDB") + migrate_engine.execute("ALTER TABLE compute_nodes Engine=InnoDB") + migrate_engine.execute("ALTER TABLE console_pools Engine=InnoDB") + migrate_engine.execute("ALTER TABLE consoles Engine=InnoDB") + migrate_engine.execute("ALTER TABLE export_devices Engine=InnoDB") + migrate_engine.execute("ALTER TABLE fixed_ips Engine=InnoDB") + migrate_engine.execute("ALTER TABLE floating_ips Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_actions Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_metadata Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_types Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instances Engine=InnoDB") + migrate_engine.execute("ALTER TABLE iscsi_targets Engine=InnoDB") + migrate_engine.execute("ALTER TABLE key_pairs Engine=InnoDB") + migrate_engine.execute("ALTER TABLE migrate_version Engine=InnoDB") + migrate_engine.execute("ALTER TABLE migrations Engine=InnoDB") + migrate_engine.execute("ALTER TABLE networks Engine=InnoDB") + migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") + migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_group_instance_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_group_rules Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") + migrate_engine.execute("ALTER TABLE services Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_project_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_project_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE users Engine=InnoDB") + migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") + migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") + +def downgrade(migrate_engine): + meta.bind = migrate_engine -- cgit From ce37d88a91c016fdb7f29a9178fb0b08a6a8f1b2 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 19 May 2011 11:17:20 -0700 Subject: temp --- nova/api/openstack/servers.py | 2 +- nova/scheduler/zone_aware_scheduler.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 12008d44a..738910bc8 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -162,7 +162,7 @@ class Controller(common.OpenstackController): msg = _("Server name is not defined") return exc.HTTPBadRequest(msg) - zone_blob = env.get('blob', None) + zone_blob = env['server'].get('blob') name = env['server']['name'] self._validate_server_name(name) name = name.strip() diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 6600951fb..9572d1c9f 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -150,7 +150,8 @@ class ZoneAwareScheduler(driver.Scheduler): raise exception.NotAuthorized(_("Bad credentials attempting " "to talk to zone at %(url)s.") % locals()) - nova.servers.create(name, image, flavor, ipgroup, meta, files) + nova.servers.create(name, image, flavor, ipgroup, meta, files, + child_blob) def select(self, context, request_spec, *args, **kwargs): """Select returns a list of weights and zone/host information -- cgit From 27a0d56d921caa700f4aa84fb177c471071f2ddd Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 20 May 2011 05:02:34 -0700 Subject: temp fixes --- nova/api/openstack/servers.py | 2 +- nova/scheduler/zone_aware_scheduler.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 12008d44a..738910bc8 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -162,7 +162,7 @@ class Controller(common.OpenstackController): msg = _("Server name is not defined") return exc.HTTPBadRequest(msg) - zone_blob = env.get('blob', None) + zone_blob = env['server'].get('blob') name = env['server']['name'] self._validate_server_name(name) name = name.strip() diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 6600951fb..9572d1c9f 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -150,7 +150,8 @@ class ZoneAwareScheduler(driver.Scheduler): raise exception.NotAuthorized(_("Bad credentials attempting " "to talk to zone at %(url)s.") % locals()) - nova.servers.create(name, image, flavor, ipgroup, meta, files) + nova.servers.create(name, image, flavor, ipgroup, meta, files, + child_blob) def select(self, context, request_spec, *args, **kwargs): """Select returns a list of weights and zone/host information -- cgit From c61ed0605d443551087c54406b39e00273a6750d Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 20 May 2011 06:03:43 -0700 Subject: syntax errors --- nova/scheduler/zone_aware_scheduler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 9572d1c9f..20f7694a1 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -75,7 +75,7 @@ class ZoneAwareScheduler(driver.Scheduler): if "hostname" in item: self._provision_resource_locally(context, item, instance_id, kwargs) - return + return self._provision_resource_in_child_zone(context, item, instance_id, request_spec, kwargs) @@ -131,7 +131,7 @@ class ZoneAwareScheduler(driver.Scheduler): instance_properties = request_spec['instance_properties'] name = instance_properties['display_name'] - image_id = instance_properties['image_id']) + image_id = instance_properties['image_id'] flavor_id = instance_type['flavor_id'] meta = instance_type['metadata'] -- cgit From 0ed410621b3c2d621aa3fa52ca7ac46c6a5f0b70 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 23 May 2011 16:19:12 -0700 Subject: getting closer to working select call --- nova/api/openstack/servers.py | 3 +++ nova/api/openstack/zones.py | 6 +----- nova/compute/api.py | 18 ++++++++++-------- nova/flags.py | 2 ++ nova/scheduler/api.py | 5 +++++ nova/scheduler/manager.py | 4 +++- nova/scheduler/zone_aware_scheduler.py | 17 +++++++++++++++-- 7 files changed, 39 insertions(+), 16 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 738910bc8..474695d98 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -189,6 +189,9 @@ class Controller(common.OpenstackController): inst['instance_type'] = inst_type inst['image_id'] = requested_image_id + # TODO(sandy): REMOVE THIS + LOG.debug(_("***** INST = %(inst)s") % locals()) + builder = self._get_view_builder(req) server = builder.build(inst, is_detail=True) server['server']['adminPass'] = password diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index 70653dc0e..b9662761d 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -18,6 +18,7 @@ import urlparse from nova import crypto from nova import db +from nova import exception from nova import flags from nova import log as logging from nova.api.openstack import common @@ -25,11 +26,6 @@ from nova.scheduler import api FLAGS = flags.FLAGS -flags.DEFINE_string('build_plan_encryption_key', - None, - '128bit (hex) encryption key for scheduler build plans.') - - LOG = logging.getLogger('nova.api.openstack.zones') diff --git a/nova/compute/api.py b/nova/compute/api.py index 785aff397..301c777bb 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -257,19 +257,21 @@ class API(base.Base): # we'll be ripping this whole for-loop out and deferring the # creation of the Instance record. At that point all this will # change. + filter_driver = 'nova.scheduler.host_filter.InstanceTypeFilter' + request_spec = { + 'instance_properties': base_options, + 'instance_type': instance_type, + 'filter_driver': filter_driver, + 'blob': zone_blob + } + LOG.debug(_("**** REQUEST SPEC: %(request_spec)s") % locals()) + rpc.cast(context, FLAGS.scheduler_topic, {"method": "run_instance", "args": {"topic": FLAGS.compute_topic, "instance_id": instance_id, - "request_spec": { - 'instance_properties': instance, - 'instance_type': instance_type, - 'filter_driver': - 'nova.scheduler.host_filter.' - 'InstanceTypeFilter', - 'blob': zone_blob - }, + "request_spec": request_spec, "availability_zone": availability_zone, "injected_files": injected_files}}) diff --git a/nova/flags.py b/nova/flags.py index 519793643..0b7cd478e 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -376,3 +376,5 @@ DEFINE_string('zone_name', 'nova', 'name of this zone') DEFINE_list('zone_capabilities', ['hypervisor=xenserver;kvm', 'os=linux;windows'], 'Key/Multi-value list representng capabilities of this zone') +DEFINE_string('build_plan_encryption_key', None, + '128bit (hex) encryption key for scheduler build plans.') diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 55f8e0a6d..f9a4f238b 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -18,6 +18,7 @@ Handles all requests relating to schedulers. """ import novaclient +import traceback #nuke from nova import db from nova import exception @@ -124,6 +125,7 @@ def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs): nova = novaclient.OpenStack(zone.username, zone.password, zone.api_url) nova.authenticate() + LOG.warn(_("*** AUTHENTICATED") % locals())#asdads except novaclient.exceptions.BadRequest, e: url = zone.api_url LOG.warn(_("Failed request to zone; URL=%(url)s: %(e)s") @@ -135,10 +137,13 @@ def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs): def _error_trap(*args, **kwargs): try: + LOG.warn(_("*** CALLING ZONE") % locals())#asdads return zone_method(*args, **kwargs) except Exception as e: if type(e) in errors_to_ignore: return None + ex = traceback.format_exc(e) + LOG.warn(_("*** CAUGHT EXCEPTION %(ex)s") % locals())#asdads # TODO (dabo) - want to be able to re-raise here. # Returning a string now; raising was causing issues. # raise e diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py index bd40e73c0..96e69566d 100644 --- a/nova/scheduler/manager.py +++ b/nova/scheduler/manager.py @@ -80,7 +80,9 @@ class SchedulerManager(manager.Manager): try: host = getattr(self.driver, driver_method)(elevated, *args, **kwargs) - except AttributeError: + except AttributeError, e: + LOG.exception(_("Driver Method %(driver_method)s missing: %(e)s") + % locals()) host = self.driver.schedule(elevated, topic, *args, **kwargs) if not host: diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 20f7694a1..6c666d1a8 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -23,12 +23,16 @@ across zones. There are two expansion points to this class for: import operator import M2Crypto +from nova import crypto from nova import db -from nova import rpc +from nova import flags from nova import log as logging +from nova import rpc + from nova.scheduler import api from nova.scheduler import driver +FLAGS = flags.FLAGS LOG = logging.getLogger('nova.scheduler.zone_aware_scheduler') @@ -51,7 +55,8 @@ class ZoneAwareScheduler(driver.Scheduler): # TODO(sandy): We'll have to look for richer specs at some point. - if 'blob' in request_spec: + blob = request_spec['blob'] + if blob: self.provision_resource(context, request_spec, instance_id, request_spec, kwargs) return None @@ -99,6 +104,8 @@ class ZoneAwareScheduler(driver.Scheduler): # 1. valid, # 2. intended for this zone or a child zone. # if 2 ... forward call to child zone. + LOG.debug(_("****** PROVISION IN CHILD %(item)s") % locals()) + blob = item['blob'] decryptor = crypto.decryptor(FLAGS.build_plan_encryption_key) host_info = None @@ -182,16 +189,21 @@ class ZoneAwareScheduler(driver.Scheduler): #TODO(sandy): how to infer this from OS API params? num_instances = 1 + LOG.debug(_("XXXXXXX - 1 - _SCHEDULE")) + # Filter local hosts based on requirements ... host_list = self.filter_hosts(num_instances, request_spec) + LOG.debug(_("XXXXXXX - 2 - _SCHEDULE")) # then weigh the selected hosts. # weighted = [{weight=weight, name=hostname}, ...] weighted = self.weigh_hosts(num_instances, request_spec, host_list) + LOG.debug(_("XXXXXXX - 3 - _SCHEDULE")) # Next, tack on the best weights from the child zones ... child_results = self._call_zone_method(context, "select", specs=request_spec) + LOG.debug(_("XXXXXXX - 4 - _SCHEDULE - CHILD RESULTS %(child_results)s") % locals()) for child_zone, result in child_results: for weighting in result: # Remember the child_zone so we can get back to @@ -203,6 +215,7 @@ class ZoneAwareScheduler(driver.Scheduler): "child_blob": weighting["blob"]} weighted.append(host_dict) + LOG.debug(_("XXXXXXX - 4 - _SCHEDULE")) weighted.sort(key=operator.itemgetter('weight')) return weighted -- cgit From 9a2c944be8e7187a12bfd363a2a74325403e00d8 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 23 May 2011 22:30:01 -0700 Subject: select partially going through --- nova/scheduler/api.py | 4 ++-- nova/scheduler/manager.py | 4 ++++ nova/scheduler/zone_aware_scheduler.py | 6 ++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index f9a4f238b..f5b570dbd 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -85,7 +85,7 @@ def get_zone_capabilities(context): def select(context, specs=None): """Returns a list of hosts.""" return _call_scheduler('select', context=context, - params={"specs": specs}) + params={"request_spec": specs}) def update_service_capabilities(context, service_name, host, capabilities): @@ -137,7 +137,7 @@ def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs): def _error_trap(*args, **kwargs): try: - LOG.warn(_("*** CALLING ZONE") % locals())#asdads + LOG.warn(_("*** CALLING ZONE %(args)s ^^ %(kwargs)s") % locals())#asdads return zone_method(*args, **kwargs) except Exception as e: if type(e) in errors_to_ignore: diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py index 96e69566d..db8c41e71 100644 --- a/nova/scheduler/manager.py +++ b/nova/scheduler/manager.py @@ -70,6 +70,10 @@ class SchedulerManager(manager.Manager): self.zone_manager.update_service_capabilities(service_name, host, capabilities) + def select(self, context=None, *args, **kwargs): + """Select a list of hosts best matching the provided specs.""" + return self.driver.select(context, *args, **kwargs) + def _schedule(self, method, context, topic, *args, **kwargs): """Tries to call schedule_* method on the driver to retrieve host. diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 6c666d1a8..c6f2935b7 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -21,6 +21,7 @@ across zones. There are two expansion points to this class for: """ import operator +import json import M2Crypto from nova import crypto @@ -199,10 +200,11 @@ class ZoneAwareScheduler(driver.Scheduler): # weighted = [{weight=weight, name=hostname}, ...] weighted = self.weigh_hosts(num_instances, request_spec, host_list) - LOG.debug(_("XXXXXXX - 3 - _SCHEDULE")) + LOG.debug(_("XXXXXXX - 3 - _SCHEDULE >> %s") % request_spec) # Next, tack on the best weights from the child zones ... + json_spec = json.dumps(request_spec) child_results = self._call_zone_method(context, "select", - specs=request_spec) + specs=json_spec) LOG.debug(_("XXXXXXX - 4 - _SCHEDULE - CHILD RESULTS %(child_results)s") % locals()) for child_zone, result in child_results: for weighting in result: -- cgit From fe30e4f8d6f757b03b22b821878aee22a35e1161 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 24 May 2011 05:46:09 -0700 Subject: sending calls --- nova/scheduler/zone_aware_scheduler.py | 45 ++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index c6f2935b7..238a50d04 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -23,6 +23,7 @@ across zones. There are two expansion points to this class for: import operator import json import M2Crypto +import novaclient from nova import crypto from nova import db @@ -105,16 +106,24 @@ class ZoneAwareScheduler(driver.Scheduler): # 1. valid, # 2. intended for this zone or a child zone. # if 2 ... forward call to child zone. + # Note: If we have "blob" that means the request was passed + # into us. If we have "child_blob" that means we just asked + # the child zone for the weight info. LOG.debug(_("****** PROVISION IN CHILD %(item)s") % locals()) - blob = item['blob'] - decryptor = crypto.decryptor(FLAGS.build_plan_encryption_key) - host_info = None - try: - json_entry = decryptor(blob) - host_info = json.dumps(entry) - except M2Crypto.EVP.EVPError: - pass + if "blob" in item: + # Request was passed in from above. Is it for us? + blob = item['blob'] + decryptor = crypto.decryptor(FLAGS.build_plan_encryption_key) + host_info = None + try: + json_entry = decryptor(blob) + host_info = json.dumps(entry) + except M2Crypto.EVP.EVPError: + pass + elif "child_blob" in item: + # Our immediate child zone provided this info ... + host_info = item if not host_info: raise exception.Invalid(_("Ill-formed or incorrectly " @@ -129,26 +138,27 @@ class ZoneAwareScheduler(driver.Scheduler): self._provision_resource_locally(context, host_info, instance_id, kwargs) - def _ask_child_zone_to_create_instance(self, zone_info, request_spec, - kwargs): + def _ask_child_zone_to_create_instance(self, context, zone_info, + request_spec, kwargs): # Note: we have to reverse engineer from our args to get back the # image, flavor, ipgroup, etc. since the original call could have # come in from EC2 (which doesn't use these things). + LOG.debug(_("****** ASK CHILD %(zone_info)s ** %(request_spec)s") % locals()) instance_type = request_spec['instance_type'] instance_properties = request_spec['instance_properties'] name = instance_properties['display_name'] image_id = instance_properties['image_id'] - flavor_id = instance_type['flavor_id'] - meta = instance_type['metadata'] + meta = instance_properties['metadata'] + flavor_id = instance_type['flavorid'] files = kwargs['injected_files'] ipgroup = None # Not supported in OS API ... yet child_zone = zone_info['child_zone'] child_blob = zone_info['child_blob'] - zone = db.zone_get(child_zone) + zone = db.zone_get(context, child_zone) url = zone.api_url nova = None try: @@ -158,7 +168,7 @@ class ZoneAwareScheduler(driver.Scheduler): raise exception.NotAuthorized(_("Bad credentials attempting " "to talk to zone at %(url)s.") % locals()) - nova.servers.create(name, image, flavor, ipgroup, meta, files, + nova.servers.create(name, image_id, flavor_id, ipgroup, meta, files, child_blob) def select(self, context, request_spec, *args, **kwargs): @@ -211,10 +221,9 @@ class ZoneAwareScheduler(driver.Scheduler): # Remember the child_zone so we can get back to # it later if needed. This implicitly builds a zone # path structure. - host_dict = { - "weight": weighting["weight"], - "child_zone": child_zone, - "child_blob": weighting["blob"]} + host_dict = {"weight": weighting["weight"], + "child_zone": child_zone, + "child_blob": weighting["blob"]} weighted.append(host_dict) LOG.debug(_("XXXXXXX - 4 - _SCHEDULE")) -- cgit From b8fd215635b850bb9c0309fd7e8e723a78250c32 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 24 May 2011 07:36:32 -0700 Subject: removed most of debugging code --- nova/api/openstack/servers.py | 2 +- nova/rpc.py | 1 - nova/scheduler/manager.py | 3 +-- nova/scheduler/zone_aware_scheduler.py | 24 +++++++----------------- 4 files changed, 9 insertions(+), 21 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index f726a3709..f3fa36028 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -190,7 +190,7 @@ class Controller(common.OpenstackController): inst['image_id'] = requested_image_id # TODO(sandy): REMOVE THIS - LOG.debug(_("***** INST = %(inst)s") % locals()) #pep8 + LOG.debug(_("***** API.OPENSTACK.SERVER.CREATE = %(inst)s") % locals()) #pep8 builder = self._get_view_builder(req) server = builder.build(inst, is_detail=True) diff --git a/nova/rpc.py b/nova/rpc.py index af3625eee..2116f22c3 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -194,7 +194,6 @@ class AdapterConsumer(Consumer): node_func = getattr(self.proxy, str(method)) node_args = dict((str(k), v) for k, v in args.iteritems()) # NOTE(vish): magic is fun! - logging.exception('CALLING %s on SCHEDULER with %s' % (node_func, node_args)) try: rval = node_func(context=ctxt, **node_args) if msg_id: diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py index ba0d5b962..a6fc53be5 100644 --- a/nova/scheduler/manager.py +++ b/nova/scheduler/manager.py @@ -73,14 +73,13 @@ class SchedulerManager(manager.Manager): def select(self, context=None, *args, **kwargs): """Select a list of hosts best matching the provided specs.""" return self.driver.select(context, *args, **kwargs) - + def _schedule(self, method, context, topic, *args, **kwargs): """Tries to call schedule_* method on the driver to retrieve host. Falls back to schedule(context, topic) if method doesn't exist. """ driver_method = 'schedule_%s' % method - LOG.debug(_("CALLING %(driver_method)s handled in Scheduler") % locals()) # nuke elevated = context.elevated() try: host = getattr(self.driver, driver_method)(elevated, *args, diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index d387011eb..1a96c56c3 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -64,7 +64,6 @@ class ZoneAwareScheduler(driver.Scheduler): return None # Create build plan and provision ... - LOG.debug(_("****** SCHEDULE RUN INSTANCE") % locals()) build_plan = self.select(context, request_spec) if not build_plan: raise driver.NoValidHost(_('No hosts were available')) @@ -84,7 +83,7 @@ class ZoneAwareScheduler(driver.Scheduler): self._provision_resource_locally(context, item, instance_id, kwargs) return - + self._provision_resource_in_child_zone(context, item, instance_id, request_spec, kwargs) @@ -104,13 +103,12 @@ class ZoneAwareScheduler(driver.Scheduler): """Create the requested resource in a child zone.""" # Start by attempting to decrypt the blob to see if this # request is: - # 1. valid, + # 1. valid, # 2. intended for this zone or a child zone. # if 2 ... forward call to child zone. # Note: If we have "blob" that means the request was passed # into us. If we have "child_blob" that means we just asked # the child zone for the weight info. - LOG.debug(_("****** PROVISION IN CHILD %(item)s") % locals()) if "blob" in item: # Request was passed in from above. Is it for us? @@ -156,7 +154,7 @@ class ZoneAwareScheduler(driver.Scheduler): files = kwargs['injected_files'] ipgroup = None # Not supported in OS API ... yet - + child_zone = zone_info['child_zone'] child_blob = zone_info['child_blob'] zone = db.zone_get(context, child_zone) @@ -166,18 +164,17 @@ class ZoneAwareScheduler(driver.Scheduler): nova = novaclient.OpenStack(zone.username, zone.password, url) nova.authenticate() except novaclient.exceptions.BadRequest, e: - raise exception.NotAuthorized(_("Bad credentials attempting " + raise exception.NotAuthorized(_("Bad credentials attempting " "to talk to zone at %(url)s.") % locals()) - + nova.servers.create(name, image_id, flavor_id, ipgroup, meta, files, child_blob) - + def select(self, context, request_spec, *args, **kwargs): """Select returns a list of weights and zone/host information corresponding to the best hosts to service the request. Any child zone information has been encrypted so as not to reveal - anything about the children.""" - LOG.debug(_("XXXXXXX - SELECT %(request_spec)s") % locals()) # nuke this !!! + anything about the children.""" return self._schedule(context, "compute", request_spec, *args, **kwargs) @@ -188,7 +185,6 @@ class ZoneAwareScheduler(driver.Scheduler): """The schedule() contract requires we return the one best-suited host for this request. """ - LOG.debug(_("XXXXXXX - DEFAULT SCHEDULE %(request_spec)s") % locals()) # nuke this !!! raise driver.NoValidHost(_('No hosts were available')) def _schedule(self, context, topic, request_spec, *args, **kwargs): @@ -203,22 +199,17 @@ class ZoneAwareScheduler(driver.Scheduler): #TODO(sandy): how to infer this from OS API params? num_instances = 1 - LOG.debug(_("XXXXXXX - 1 - _SCHEDULE")) - # Filter local hosts based on requirements ... host_list = self.filter_hosts(num_instances, request_spec) - LOG.debug(_("XXXXXXX - 2 - _SCHEDULE")) # then weigh the selected hosts. # weighted = [{weight=weight, name=hostname}, ...] weighted = self.weigh_hosts(num_instances, request_spec, host_list) - LOG.debug(_("XXXXXXX - 3 - _SCHEDULE >> %s") % request_spec) # Next, tack on the best weights from the child zones ... json_spec = json.dumps(request_spec) child_results = self._call_zone_method(context, "select", specs=json_spec) - LOG.debug(_("XXXXXXX - 4 - _SCHEDULE - CHILD RESULTS %(child_results)s") % locals()) for child_zone, result in child_results: for weighting in result: # Remember the child_zone so we can get back to @@ -229,7 +220,6 @@ class ZoneAwareScheduler(driver.Scheduler): "child_blob": weighting["blob"]} weighted.append(host_dict) - LOG.debug(_("XXXXXXX - 4 - _SCHEDULE")) weighted.sort(key=operator.itemgetter('weight')) return weighted -- cgit From 48a3ec6e55f029578d5dc8ef7fe2e9fbe0de1b81 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 24 May 2011 12:05:46 -0700 Subject: more fix up --- nova/api/openstack/servers.py | 1 - nova/api/openstack/zones.py | 2 +- nova/compute/api.py | 1 - nova/scheduler/api.py | 4 ---- nova/scheduler/zone_aware_scheduler.py | 41 +++++++++++++++++++++------------- nova/service.py | 2 -- 6 files changed, 26 insertions(+), 25 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index f3fa36028..8d5e78d3a 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -189,7 +189,6 @@ class Controller(common.OpenstackController): inst['instance_type'] = inst_type inst['image_id'] = requested_image_id - # TODO(sandy): REMOVE THIS LOG.debug(_("***** API.OPENSTACK.SERVER.CREATE = %(inst)s") % locals()) #pep8 builder = self._get_view_builder(req) diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index 96a6552b3..f8867f5a4 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -119,7 +119,7 @@ class Controller(common.OpenstackController): ctx = req.environ['nova.context'] json_specs = json.loads(req.body) specs = json.loads(json_specs) - LOG.debug("INCOMING SELECT '%s'" % specs) + LOG.debug("NOVA.API.OPENSTACK.ZONES.SELECT '%s'" % specs)#pep8 build_plan = api.select(ctx, specs=specs) cooked = self._scrub_build_plan(build_plan) return {"weights": cooked} diff --git a/nova/compute/api.py b/nova/compute/api.py index 301c777bb..d66ee7920 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -264,7 +264,6 @@ class API(base.Base): 'filter_driver': filter_driver, 'blob': zone_blob } - LOG.debug(_("**** REQUEST SPEC: %(request_spec)s") % locals()) rpc.cast(context, FLAGS.scheduler_topic, diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index f5b570dbd..24d7ed0d6 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -18,7 +18,6 @@ Handles all requests relating to schedulers. """ import novaclient -import traceback #nuke from nova import db from nova import exception @@ -125,7 +124,6 @@ def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs): nova = novaclient.OpenStack(zone.username, zone.password, zone.api_url) nova.authenticate() - LOG.warn(_("*** AUTHENTICATED") % locals())#asdads except novaclient.exceptions.BadRequest, e: url = zone.api_url LOG.warn(_("Failed request to zone; URL=%(url)s: %(e)s") @@ -137,13 +135,11 @@ def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs): def _error_trap(*args, **kwargs): try: - LOG.warn(_("*** CALLING ZONE %(args)s ^^ %(kwargs)s") % locals())#asdads return zone_method(*args, **kwargs) except Exception as e: if type(e) in errors_to_ignore: return None ex = traceback.format_exc(e) - LOG.warn(_("*** CAUGHT EXCEPTION %(ex)s") % locals())#asdads # TODO (dabo) - want to be able to re-raise here. # Returning a string now; raising was causing issues. # raise e diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 1a96c56c3..3dd43443a 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -84,7 +84,7 @@ class ZoneAwareScheduler(driver.Scheduler): kwargs) return - self._provision_resource_in_child_zone(context, item, instance_id, + self._provision_resource_from_blob(context, item, instance_id, request_spec, kwargs) def _provision_resource_locally(self, context, item, instance_id, kwargs): @@ -95,20 +95,24 @@ class ZoneAwareScheduler(driver.Scheduler): db.queue_get_for(context, "compute", host), {"method": "run_instance", "args": kwargs}) - LOG.debug(_("Casted to compute %(host)s for run_instance") + LOG.debug(_("Provisioning locally via compute node %(host)s") % locals()) - def _provision_resource_in_child_zone(self, context, item, instance_id, + def _provision_resource_from_blob(self, context, item, instance_id, request_spec, kwargs): - """Create the requested resource in a child zone.""" - # Start by attempting to decrypt the blob to see if this - # request is: - # 1. valid, - # 2. intended for this zone or a child zone. - # if 2 ... forward call to child zone. - # Note: If we have "blob" that means the request was passed - # into us. If we have "child_blob" that means we just asked - # the child zone for the weight info. + """Create the requested resource locally or in a child zone + based on what is stored in the zone blob info. + + Attempt to decrypt the blob to see if this request is: + 1. valid, and + 2. intended for this zone or a child zone. + + Note: If we have "blob" that means the request was passed + into us from a parent zone. If we have "child_blob" that + means we gathered the info from one of our children. + It's possible that, when we decrypt the 'blob' field, it + contains "child_blob" data. In which case we forward the + request.""" if "blob" in item: # Request was passed in from above. Is it for us? @@ -139,11 +143,14 @@ class ZoneAwareScheduler(driver.Scheduler): def _ask_child_zone_to_create_instance(self, context, zone_info, request_spec, kwargs): + """Once we have determined that the request should go to one + of our children, we need to fabricate a new POST /servers/ + call with the same parameters that were passed into us. + + Note that we have to reverse engineer from our args to get back the + image, flavor, ipgroup, etc. since the original call could have + come in from EC2 (which doesn't use these things).""" - # Note: we have to reverse engineer from our args to get back the - # image, flavor, ipgroup, etc. since the original call could have - # come in from EC2 (which doesn't use these things). - LOG.debug(_("****** ASK CHILD %(zone_info)s ** %(request_spec)s") % locals()) instance_type = request_spec['instance_type'] instance_properties = request_spec['instance_properties'] @@ -159,6 +166,8 @@ class ZoneAwareScheduler(driver.Scheduler): child_blob = zone_info['child_blob'] zone = db.zone_get(context, child_zone) url = zone.api_url + LOG.debug(_("Forwarding instance create call to child zone %(url)s") + % locals()) nova = None try: nova = novaclient.OpenStack(zone.username, zone.password, url) diff --git a/nova/service.py b/nova/service.py index 93020d94f..2532b9df2 100644 --- a/nova/service.py +++ b/nova/service.py @@ -132,9 +132,7 @@ class Service(object): self.service_id = service_ref['id'] def __getattr__(self, key): - logging.warn(_('SERVICE __GETATTR__ %s') % (key, )) manager = self.__dict__.get('manager', None) - logging.warn(_('SERVICE MANAGER %s') % (manager, )) return getattr(manager, key) @classmethod -- cgit From a33970f17abb0fed47cd03d48a25709d987b5c25 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 24 May 2011 18:09:25 -0700 Subject: tests working again --- nova/scheduler/zone_aware_scheduler.py | 2 +- nova/tests/api/openstack/test_zones.py | 4 ++++ nova/tests/test_zone_aware_scheduler.py | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 3dd43443a..00f5660f3 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -57,7 +57,7 @@ class ZoneAwareScheduler(driver.Scheduler): # TODO(sandy): We'll have to look for richer specs at some point. - blob = request_spec['blob'] + blob = request_spec.get('blob') if blob: self.provision_resource(context, request_spec, instance_id, request_spec, kwargs) diff --git a/nova/tests/api/openstack/test_zones.py b/nova/tests/api/openstack/test_zones.py index b42b3e7d8..e21b5ce86 100644 --- a/nova/tests/api/openstack/test_zones.py +++ b/nova/tests/api/openstack/test_zones.py @@ -209,6 +209,10 @@ class ZonesTest(test.TestCase): self.stubs.Set(api, 'select', zone_select) req = webob.Request.blank('/v1.0/zones/select') + req.method = 'POST' + # Select queries end up being JSON encoded twice. + # Once to a string and again as an HTTP POST Body + req.body = json.dumps(json.dumps({})) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) diff --git a/nova/tests/test_zone_aware_scheduler.py b/nova/tests/test_zone_aware_scheduler.py index 37169fb97..493eb294f 100644 --- a/nova/tests/test_zone_aware_scheduler.py +++ b/nova/tests/test_zone_aware_scheduler.py @@ -118,4 +118,5 @@ class ZoneAwareSchedulerTestCase(test.TestCase): fake_context = {} self.assertRaises(driver.NoValidHost, sched.schedule_run_instance, fake_context, 1, - dict(host_filter=None, instance_type={})) + dict(host_filter=None, + request_spec={'instance_type': {}})) -- cgit From f4cc59f0d4344deecea59a7276a50d446f1ea2cd Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 25 May 2011 08:17:50 -0700 Subject: New tests added --- nova/api/openstack/servers.py | 2 - nova/api/openstack/zones.py | 1 - nova/exception.py | 2 +- nova/scheduler/zone_aware_scheduler.py | 177 +++++++++++++++++--------------- nova/tests/test_zone_aware_scheduler.py | 143 ++++++++++++++++++++++++++ 5 files changed, 237 insertions(+), 88 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 8d5e78d3a..738910bc8 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -189,8 +189,6 @@ class Controller(common.OpenstackController): inst['instance_type'] = inst_type inst['image_id'] = requested_image_id - LOG.debug(_("***** API.OPENSTACK.SERVER.CREATE = %(inst)s") % locals()) #pep8 - builder = self._get_view_builder(req) server = builder.build(inst, is_detail=True) server['server']['adminPass'] = password diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index f8867f5a4..411eb2b54 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -119,7 +119,6 @@ class Controller(common.OpenstackController): ctx = req.environ['nova.context'] json_specs = json.loads(req.body) specs = json.loads(json_specs) - LOG.debug("NOVA.API.OPENSTACK.ZONES.SELECT '%s'" % specs)#pep8 build_plan = api.select(ctx, specs=specs) cooked = self._scrub_build_plan(build_plan) return {"weights": cooked} diff --git a/nova/exception.py b/nova/exception.py index cf6069454..0927a42f8 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -122,7 +122,7 @@ class NotAuthorized(NovaException): message = _("Not authorized.") def __init__(self, *args, **kwargs): - super(NotFound, self).__init__(**kwargs) + super(NotAuthorized, self).__init__(**kwargs) class AdminRequired(NotAuthorized): diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 00f5660f3..58a9eca55 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -27,6 +27,7 @@ import novaclient from nova import crypto from nova import db +from nova import exception from nova import flags from nova import log as logging from nova import rpc @@ -38,6 +39,11 @@ FLAGS = flags.FLAGS LOG = logging.getLogger('nova.scheduler.zone_aware_scheduler') +class InvalidBlob(exception.NovaException): + message = _("Ill-formed or incorrectly routed 'blob' data sent " + "to instance create request.") + + class ZoneAwareScheduler(driver.Scheduler): """Base class for creating Zone Aware Schedulers.""" @@ -45,48 +51,6 @@ class ZoneAwareScheduler(driver.Scheduler): """Call novaclient zone method. Broken out for testing.""" return api.call_zone_method(context, method, specs=specs) - def schedule_run_instance(self, context, instance_id, request_spec, - *args, **kwargs): - """This method is called from nova.compute.api to provision - an instance. However we need to look at the parameters being - passed in to see if this is a request to: - 1. Create a Build Plan and then provision, or - 2. Use the Build Plan information in the request parameters - to simply create the instance (either in this zone or - a child zone).""" - - # TODO(sandy): We'll have to look for richer specs at some point. - - blob = request_spec.get('blob') - if blob: - self.provision_resource(context, request_spec, instance_id, - request_spec, kwargs) - return None - - # Create build plan and provision ... - build_plan = self.select(context, request_spec) - if not build_plan: - raise driver.NoValidHost(_('No hosts were available')) - - for item in build_plan: - self.provision_resource(context, item, instance_id, request_spec, - kwargs) - - # Returning None short-circuits the routing to Compute (since - # we've already done it here) - return None - - def provision_resource(self, context, item, instance_id, request_spec, - kwargs): - """Create the requested resource in this Zone or a child zone.""" - if "hostname" in item: - self._provision_resource_locally(context, item, instance_id, - kwargs) - return - - self._provision_resource_from_blob(context, item, instance_id, - request_spec, kwargs) - def _provision_resource_locally(self, context, item, instance_id, kwargs): """Create the requested resource in this Zone.""" host = item['hostname'] @@ -98,48 +62,16 @@ class ZoneAwareScheduler(driver.Scheduler): LOG.debug(_("Provisioning locally via compute node %(host)s") % locals()) - def _provision_resource_from_blob(self, context, item, instance_id, - request_spec, kwargs): - """Create the requested resource locally or in a child zone - based on what is stored in the zone blob info. - - Attempt to decrypt the blob to see if this request is: - 1. valid, and - 2. intended for this zone or a child zone. - - Note: If we have "blob" that means the request was passed - into us from a parent zone. If we have "child_blob" that - means we gathered the info from one of our children. - It's possible that, when we decrypt the 'blob' field, it - contains "child_blob" data. In which case we forward the - request.""" - - if "blob" in item: - # Request was passed in from above. Is it for us? - blob = item['blob'] - decryptor = crypto.decryptor(FLAGS.build_plan_encryption_key) - host_info = None - try: - json_entry = decryptor(blob) - host_info = json.dumps(entry) - except M2Crypto.EVP.EVPError: - pass - elif "child_blob" in item: - # Our immediate child zone provided this info ... - host_info = item - - if not host_info: - raise exception.Invalid(_("Ill-formed or incorrectly " - "routed 'blob' data sent " - "to instance create request.") % locals()) - - # Valid data ... is it for us? - if 'child_zone' in host_info and 'child_blob' in host_info: - self._ask_child_zone_to_create_instance(context, host_info, - request_spec, kwargs) - else: - self._provision_resource_locally(context, host_info, - instance_id, kwargs) + def _decrypt_blob(self, blob): + """Returns the decrypted blob or None if invalid. Broken out + for testing.""" + decryptor = crypto.decryptor(FLAGS.build_plan_encryption_key) + try: + json_entry = decryptor(blob) + return json.dumps(entry) + except M2Crypto.EVP.EVPError: + pass + return None def _ask_child_zone_to_create_instance(self, context, zone_info, request_spec, kwargs): @@ -179,6 +111,83 @@ class ZoneAwareScheduler(driver.Scheduler): nova.servers.create(name, image_id, flavor_id, ipgroup, meta, files, child_blob) + def _provision_resource_from_blob(self, context, item, instance_id, + request_spec, kwargs): + """Create the requested resource locally or in a child zone + based on what is stored in the zone blob info. + + Attempt to decrypt the blob to see if this request is: + 1. valid, and + 2. intended for this zone or a child zone. + + Note: If we have "blob" that means the request was passed + into us from a parent zone. If we have "child_blob" that + means we gathered the info from one of our children. + It's possible that, when we decrypt the 'blob' field, it + contains "child_blob" data. In which case we forward the + request.""" + + host_info = None + if "blob" in item: + # Request was passed in from above. Is it for us? + host_info = self._decrypt_blob(item['blob']) + elif "child_blob" in item: + # Our immediate child zone provided this info ... + host_info = item + + if not host_info: + raise InvalidBlob() + + # Valid data ... is it for us? + if 'child_zone' in host_info and 'child_blob' in host_info: + self._ask_child_zone_to_create_instance(context, host_info, + request_spec, kwargs) + else: + self._provision_resource_locally(context, host_info, + instance_id, kwargs) + + def _provision_resource(self, context, item, instance_id, request_spec, + kwargs): + """Create the requested resource in this Zone or a child zone.""" + if "hostname" in item: + self._provision_resource_locally(context, item, instance_id, + kwargs) + return + + self._provision_resource_from_blob(context, item, instance_id, + request_spec, kwargs) + + def schedule_run_instance(self, context, instance_id, request_spec, + *args, **kwargs): + """This method is called from nova.compute.api to provision + an instance. However we need to look at the parameters being + passed in to see if this is a request to: + 1. Create a Build Plan and then provision, or + 2. Use the Build Plan information in the request parameters + to simply create the instance (either in this zone or + a child zone).""" + + # TODO(sandy): We'll have to look for richer specs at some point. + + blob = request_spec.get('blob') + if blob: + self._provision_resource(context, request_spec, instance_id, + request_spec, kwargs) + return None + + # Create build plan and provision ... + build_plan = self.select(context, request_spec) + if not build_plan: + raise driver.NoValidHost(_('No hosts were available')) + + for item in build_plan: + self._provision_resource(context, item, instance_id, request_spec, + kwargs) + + # Returning None short-circuits the routing to Compute (since + # we've already done it here) + return None + def select(self, context, request_spec, *args, **kwargs): """Select returns a list of weights and zone/host information corresponding to the best hosts to service the request. Any diff --git a/nova/tests/test_zone_aware_scheduler.py b/nova/tests/test_zone_aware_scheduler.py index 493eb294f..2ec0f2199 100644 --- a/nova/tests/test_zone_aware_scheduler.py +++ b/nova/tests/test_zone_aware_scheduler.py @@ -16,6 +16,7 @@ Tests For Zone Aware Scheduler. """ +from nova import exception from nova import test from nova.scheduler import driver from nova.scheduler import zone_aware_scheduler @@ -59,6 +60,41 @@ def fake_empty_call_zone_method(context, method, specs): return [] +# Hmm, I should probably be using mox for this. +was_called = False + + +def fake_provision_resource(context, item, instance_id, request_spec, kwargs): + global was_called + was_called = True + + +def fake_ask_child_zone_to_create_instance(context, zone_info, + request_spec, kwargs): + global was_called + was_called = True + + +def fake_provision_resource_locally(context, item, instance_id, kwargs): + global was_called + was_called = True + + +def fake_provision_resource_from_blob(context, item, instance_id, + request_spec, kwargs): + global was_called + was_called = True + + +def fake_decrypt_blob_returns_local_info(blob): + return {'foo': True} # values aren't important. + + +def fake_decrypt_blob_returns_child_info(blob): + return {'child_zone': True, + 'child_blob': True} # values aren't important. Keys are. + + def fake_call_zone_method(context, method, specs): return [ ('zone1', [ @@ -120,3 +156,110 @@ class ZoneAwareSchedulerTestCase(test.TestCase): fake_context, 1, dict(host_filter=None, request_spec={'instance_type': {}})) + + def test_schedule_do_not_schedule_with_hint(self): + """ + Check the local/child zone routing in the run_instance() call. + If the zone_blob hint was passed in, don't re-schedule. + """ + global was_called + sched = FakeZoneAwareScheduler() + was_called = False + self.stubs.Set(sched, '_provision_resource', fake_provision_resource) + request_spec = { + 'instance_properties': {}, + 'instance_type': {}, + 'filter_driver': 'nova.scheduler.host_filter.AllHostsFilter', + 'blob': "Non-None blob data" + } + + result = sched.schedule_run_instance(None, 1, request_spec) + self.assertEquals(None, result) + self.assertTrue(was_called) + + def test_provision_resource_local(self): + """Provision a resource locally or remotely.""" + global was_called + sched = FakeZoneAwareScheduler() + was_called = False + self.stubs.Set(sched, '_provision_resource_locally', + fake_provision_resource_locally) + + request_spec = {'hostname': "foo"} + sched._provision_resource(None, request_spec, 1, request_spec, {}) + self.assertTrue(was_called) + + def test_provision_resource_remote(self): + """Provision a resource locally or remotely.""" + global was_called + sched = FakeZoneAwareScheduler() + was_called = False + self.stubs.Set(sched, '_provision_resource_from_blob', + fake_provision_resource_from_blob) + + request_spec = {} + sched._provision_resource(None, request_spec, 1, request_spec, {}) + self.assertTrue(was_called) + + def test_provision_resource_from_blob_empty(self): + """Provision a resource locally or remotely given no hints.""" + global was_called + sched = FakeZoneAwareScheduler() + request_spec = {} + self.assertRaises(zone_aware_scheduler.InvalidBlob, + sched._provision_resource_from_blob, + None, {}, 1, {}, {}) + + def test_provision_resource_from_blob_with_local_blob(self): + """ + Provision a resource locally or remotely when blob hint passed in. + """ + global was_called + sched = FakeZoneAwareScheduler() + was_called = False + self.stubs.Set(sched, '_decrypt_blob', + fake_decrypt_blob_returns_local_info) + self.stubs.Set(sched, '_provision_resource_locally', + fake_provision_resource_locally) + + request_spec = {'blob': "Non-None blob data"} + + sched._provision_resource_from_blob(None, request_spec, 1, + request_spec, {}) + self.assertTrue(was_called) + + def test_provision_resource_from_blob_with_child_blob(self): + """ + Provision a resource locally or remotely when child blob hint + passed in. + """ + global was_called + sched = FakeZoneAwareScheduler() + self.stubs.Set(sched, '_decrypt_blob', + fake_decrypt_blob_returns_child_info) + was_called = False + self.stubs.Set(sched, '_ask_child_zone_to_create_instance', + fake_ask_child_zone_to_create_instance) + + request_spec = {'blob': "Non-None blob data"} + + sched._provision_resource_from_blob(None, request_spec, 1, + request_spec, {}) + self.assertTrue(was_called) + + def test_provision_resource_from_blob_with_immediate_child_blob(self): + """ + Provision a resource locally or remotely when blob hint passed in + from an immediate child. + """ + global was_called + sched = FakeZoneAwareScheduler() + was_called = False + self.stubs.Set(sched, '_ask_child_zone_to_create_instance', + fake_ask_child_zone_to_create_instance) + + request_spec = {'child_blob': True, 'child_zone': True} + + sched._provision_resource_from_blob(None, request_spec, 1, + request_spec, {}) + self.assertTrue(was_called) -- cgit From f6f98f1fe905443eacbfb036f1b6ff6c6f5d5261 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 25 May 2011 09:00:13 -0700 Subject: dist-sched-2a merge --- nova/api/openstack/zones.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index 78715f1cc..29b7b2279 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -26,9 +26,6 @@ from nova.scheduler import api FLAGS = flags.FLAGS -flags.DEFINE_string('build_plan_encryption_key', - None, - '128bit (hex) encryption key for scheduler build plans.') LOG = logging.getLogger('nova.api.openstack.zones') -- cgit From 660d1802a6c202465af585a059930113de5ae646 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 25 May 2011 13:20:34 -0700 Subject: starting breakdown of nova.compute.api.create() --- nova/compute/api.py | 67 +++++++++++++++++++++++++++++++++++++++++++++------ nova/scheduler/api.py | 7 ++++++ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 57f8c421a..1d75dbc80 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -54,6 +54,7 @@ def generate_default_hostname(instance_id): class API(base.Base): """API for interacting with the compute manager.""" + scheduler_rules = None def __init__(self, image_service=None, network_api=None, volume_api=None, hostname_factory=generate_default_hostname, @@ -128,18 +129,15 @@ class API(base.Base): LOG.warn(msg) raise quota.QuotaError(msg, "MetadataLimitExceeded") - def create(self, context, instance_type, + def _check_create_parameters(self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name='', display_description='', key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, injected_files=None, zone_blob=None): - """Create the number and type of instances requested. - - Verifies that quota and other arguments are valid. - - """ + """Verify all the input parameters regardless of the provisioning + strategy being performed.""" if not instance_type: instance_type = instance_types.get_default_instance_type() @@ -220,7 +218,46 @@ class API(base.Base): 'metadata': metadata, 'availability_zone': availability_zone, 'os_type': os_type} - elevated = context.elevated() + + return (num_instances, base_options) + + def create_all_at_once(self, context, instance_type, + image_id, kernel_id=None, ramdisk_id=None, + min_count=1, max_count=1, + display_name='', display_description='', + key_name=None, key_data=None, security_group='default', + availability_zone=None, user_data=None, metadata={}, + injected_files=None, zone_blob=None): + """Provision the instances by passing the whole request to + the Scheduler for execution.""" + self._check_create_parameters(self, context, instance_type, + image_id, kernel_id, ramdisk_id, min_count=1, max_count=1, + display_name, display_description, + key_name, key_data, security_group, + availability_zone, user_data, metadata, + injected_files, zone_blob) + + def create(self, context, instance_type, + image_id, kernel_id=None, ramdisk_id=None, + min_count=1, max_count=1, + display_name='', display_description='', + key_name=None, key_data=None, security_group='default', + availability_zone=None, user_data=None, metadata={}, + injected_files=None, zone_blob=None): + """Provision the instances by sending off a series of single + instance requests to the Schedulers. This is fine for trival + Scheduler drivers, but may remove the effectiveness of the + more complicated drivers.""" + + num_instances, base_options = self._check_create_parameters( + context, instance_type, + image_id, kernel_id, ramdisk_id, + min_count=1, max_count=1, + display_name, display_description, + key_name, key_data, security_group, + availability_zone, user_data, metadata, + injected_files, zone_blob) + instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): @@ -279,6 +316,22 @@ class API(base.Base): return [dict(x.iteritems()) for x in instances] + def smart_create(self, *args, **kwargs): + """Ask the scheduler if we should: 1. do single shot instance + requests or all-at-once, and 2. defer the DB work until + a suitable host has been selected (if at all). Cache this + information and act accordingly.""" + + if API.scheduler_rules == None: + API.scheduler_rules = scheduler_api.get_scheduler_rules(context) + + should_create_all_at_once, should_defer_database_create = \ + API.scheduler_rules + + if should_create_all_at_once: + return self.create_all_at_once(*args, **kwargs) + return self.create(*args, **kwargs) + def has_finished_migration(self, context, instance_id): """Returns true if an instance has a finished migration.""" try: diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 09e7c9140..8123082f9 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -87,6 +87,13 @@ def select(context, specs=None): params={"request_spec": specs}) +def get_scheduler_rules(context): + """Returns a tuple of rules for how instances should + be created given the current Scheduler driver being used.""" + return _call_scheduler('get_scheduler_rules', context=context, + params={}) + + def update_service_capabilities(context, service_name, host, capabilities): """Send an update to all the scheduler services informing them of the capabilities of this service.""" -- cgit From bc176751de7f55d22d1bb04552bbff9c496979ed Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 26 May 2011 08:28:57 -0700 Subject: refactoring compute.api.create() --- nova/compute/api.py | 193 ++++++++++++++++++++------------- nova/scheduler/driver.py | 7 ++ nova/scheduler/manager.py | 4 + nova/scheduler/zone_aware_scheduler.py | 6 + 4 files changed, 135 insertions(+), 75 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 1d75dbc80..cd4d7ca47 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -54,7 +54,11 @@ def generate_default_hostname(instance_id): class API(base.Base): """API for interacting with the compute manager.""" - scheduler_rules = None + + # Should we create instances all-at-once or as single-shot requests. + # Different schedulers use different approaches. + # This is cached across all API instances. + should_create_all_at_once = None # None implies uninitialized. def __init__(self, image_service=None, network_api=None, volume_api=None, hostname_factory=generate_default_hostname, @@ -219,8 +223,74 @@ class API(base.Base): 'availability_zone': availability_zone, 'os_type': os_type} - return (num_instances, base_options) + return (num_instances, base_options, security_groups) + + def create_db_entry_for_new_instance(self, context, base_options, + security_groups, num=1): + """Create an entry in the DB for this new instance, + including any related table updates (such as security + groups, MAC address, etc). This will called by create() + in the majority of situations, but all-at-once style + Schedulers may initiate the call.""" + instance = dict(mac_address=utils.generate_mac(), + launch_index=num, + **base_options) + instance = self.db.instance_create(context, instance) + instance_id = instance['id'] + + elevated = context.elevated() + if not security_groups: + security_groups = [] + for security_group_id in security_groups: + self.db.instance_add_security_group(elevated, + instance_id, + security_group_id) + + # Set sane defaults if not specified + updates = dict(hostname=self.hostname_factory(instance_id)) + if (not hasattr(instance, 'display_name') or + instance.display_name is None): + updates['display_name'] = "Server %s" % instance_id + + instance = self.update(context, instance_id, **updates) + + for group_id in security_groups: + self.trigger_security_group_members_refresh(elevated, group_id) + + return instance + def _ask_scheduler_to_create_instance(self, context, base_options, + instance_type, zone_blob, + availability_zone, injected_files, + instance_id=None, num_instances=1): + """Send the run_instance request to the schedulers for processing.""" + pid = context.project_id + uid = context.user_id + if instance_id: + LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" + " instance %(instance_id)s (single-shot)") % locals()) + else: + LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" + " (all-at-once)") % locals()) + + filter_class = 'nova.scheduler.host_filter.InstanceTypeFilter' + request_spec = { + 'instance_properties': base_options, + 'instance_type': instance_type, + 'filter': filter_class, + 'blob': zone_blob, + 'num_instances': num_instances + } + + rpc.cast(context, + FLAGS.scheduler_topic, + {"method": "run_instance", + "args": {"topic": FLAGS.compute_topic, + "instance_id": instance_id, + "request_spec": request_spec, + "availability_zone": availability_zone, + "injected_files": injected_files}}) + def create_all_at_once(self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, @@ -229,13 +299,24 @@ class API(base.Base): availability_zone=None, user_data=None, metadata={}, injected_files=None, zone_blob=None): """Provision the instances by passing the whole request to - the Scheduler for execution.""" - self._check_create_parameters(self, context, instance_type, - image_id, kernel_id, ramdisk_id, min_count=1, max_count=1, - display_name, display_description, - key_name, key_data, security_group, - availability_zone, user_data, metadata, - injected_files, zone_blob) + the Scheduler for execution. Returns a Reservation ID + related to the creation of all of these instances.""" + num_instances, base_options, security_groups = \ + self._check_create_parameters( + context, instance_type, + image_id, kernel_id, ramdisk_id, + min_count, max_count, + display_name, display_description, + key_name, key_data, security_group, + availability_zone, user_data, metadata, + injected_files, zone_blob) + + self._ask_scheduler_to_create_instance(context, base_options, + instance_type, zone_blob, + availability_zone, injected_files, + num_instances=num_instances) + + return base_options['reservation_id'] def create(self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, @@ -244,15 +325,20 @@ class API(base.Base): key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, injected_files=None, zone_blob=None): - """Provision the instances by sending off a series of single + """ + Provision the instances by sending off a series of single instance requests to the Schedulers. This is fine for trival Scheduler drivers, but may remove the effectiveness of the - more complicated drivers.""" + more complicated drivers. + + Returns a list of instance dicts. + """ - num_instances, base_options = self._check_create_parameters( + num_instances, base_options, security_groups = \ + self._check_create_parameters( context, instance_type, image_id, kernel_id, ramdisk_id, - min_count=1, max_count=1, + min_count, max_count, display_name, display_description, key_name, key_data, security_group, availability_zone, user_data, metadata, @@ -261,74 +347,31 @@ class API(base.Base): instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): - instance = dict(mac_address=utils.generate_mac(), - launch_index=num, - **base_options) - instance = self.db.instance_create(context, instance) - instance_id = instance['id'] - - elevated = context.elevated() - if not security_groups: - security_groups = [] - for security_group_id in security_groups: - self.db.instance_add_security_group(elevated, - instance_id, - security_group_id) - - # Set sane defaults if not specified - updates = dict(hostname=self.hostname_factory(instance_id)) - if (not hasattr(instance, 'display_name') or - instance.display_name is None): - updates['display_name'] = "Server %s" % instance_id - - instance = self.update(context, instance_id, **updates) + instance = self.create_db_entry_for_new_instance(context, + base_options, security_groups, num=num) instances.append(instance) - - pid = context.project_id - uid = context.user_id - LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" - " instance %(instance_id)s") % locals()) - - # NOTE(sandy): For now we're just going to pass in the - # instance_type record to the scheduler. In a later phase - # we'll be ripping this whole for-loop out and deferring the - # creation of the Instance record. At that point all this will - # change. - filter_driver = 'nova.scheduler.host_filter.InstanceTypeFilter' - request_spec = { - 'instance_properties': base_options, - 'instance_type': instance_type, - 'filter_driver': filter_driver, - 'blob': zone_blob - } - - rpc.cast(context, - FLAGS.scheduler_topic, - {"method": "run_instance", - "args": {"topic": FLAGS.compute_topic, - "instance_id": instance_id, - "request_spec": request_spec, - "availability_zone": availability_zone, - "injected_files": injected_files}}) - - for group_id in security_groups: - self.trigger_security_group_members_refresh(elevated, group_id) - - return [dict(x.iteritems()) for x in instances] + instance_id = instance['id'] + + self._ask_scheduler_to_create_instance(context, base_options, + instance_type, zone_blob, + availability_zone, injected_files, + instance_id=instance_id) + + return [x.items() for x in instances] def smart_create(self, *args, **kwargs): - """Ask the scheduler if we should: 1. do single shot instance - requests or all-at-once, and 2. defer the DB work until - a suitable host has been selected (if at all). Cache this - information and act accordingly.""" + """ + Ask the scheduler if we should do single shot instance requests + or all-at-once. - if API.scheduler_rules == None: - API.scheduler_rules = scheduler_api.get_scheduler_rules(context) + Cache this information on first request and act accordingly. + """ - should_create_all_at_once, should_defer_database_create = \ - API.scheduler_rules + if API.should_create_all_at_once == None: + API.should_create_all_at_once = \ + scheduler_api.should_create_all_at_once(context) - if should_create_all_at_once: + if API.should_create_all_at_once: return self.create_all_at_once(*args, **kwargs) return self.create(*args, **kwargs) diff --git a/nova/scheduler/driver.py b/nova/scheduler/driver.py index 2094e3565..237e31c04 100644 --- a/nova/scheduler/driver.py +++ b/nova/scheduler/driver.py @@ -72,6 +72,13 @@ class Scheduler(object): for service in services if self.service_is_up(service)] + def should_create_all_at_once(self, context=None, *args, **kwargs): + """ + Does this driver prefer single-shot requests or all-at-once? + By default, prefer single-shot. + """ + return False + def schedule(self, context, topic, *_args, **_kwargs): """Must override at least this method for scheduler to work.""" raise NotImplementedError(_("Must implement a fallback schedule")) diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py index a6fc53be5..a29703aaf 100644 --- a/nova/scheduler/manager.py +++ b/nova/scheduler/manager.py @@ -74,6 +74,10 @@ class SchedulerManager(manager.Manager): """Select a list of hosts best matching the provided specs.""" return self.driver.select(context, *args, **kwargs) + def get_scheduler_rules(self, context=None, *args, **kwargs): + """Ask the driver how requests should be made of it.""" + return self.driver.get_scheduler_rules(context, *args, **kwargs) + def _schedule(self, method, context, topic, *args, **kwargs): """Tries to call schedule_* method on the driver to retrieve host. diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index 58a9eca55..35ffdbde1 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -157,6 +157,12 @@ class ZoneAwareScheduler(driver.Scheduler): self._provision_resource_from_blob(context, item, instance_id, request_spec, kwargs) + def should_create_all_at_once(self, context=None, *args, **kwargs): + """ + This driver prefers all-at-once requests. + """ + return True + def schedule_run_instance(self, context, instance_id, request_spec, *args, **kwargs): """This method is called from nova.compute.api to provision -- cgit From 9a9dc80bcb47db5864b0c35fe1dd1a636b0a933e Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 26 May 2011 11:34:53 -0700 Subject: tests pass and pep8'ed --- nova/compute/api.py | 30 +++++++++++++++--------------- nova/scheduler/api.py | 4 ++-- nova/scheduler/host_filter.py | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index cd4d7ca47..032ef7469 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -225,9 +225,9 @@ class API(base.Base): return (num_instances, base_options, security_groups) - def create_db_entry_for_new_instance(self, context, base_options, + def create_db_entry_for_new_instance(self, context, base_options, security_groups, num=1): - """Create an entry in the DB for this new instance, + """Create an entry in the DB for this new instance, including any related table updates (such as security groups, MAC address, etc). This will called by create() in the majority of situations, but all-at-once style @@ -272,7 +272,7 @@ class API(base.Base): else: LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" " (all-at-once)") % locals()) - + filter_class = 'nova.scheduler.host_filter.InstanceTypeFilter' request_spec = { 'instance_properties': base_options, @@ -290,7 +290,7 @@ class API(base.Base): "request_spec": request_spec, "availability_zone": availability_zone, "injected_files": injected_files}}) - + def create_all_at_once(self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, @@ -298,10 +298,10 @@ class API(base.Base): key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, injected_files=None, zone_blob=None): - """Provision the instances by passing the whole request to - the Scheduler for execution. Returns a Reservation ID - related to the creation of all of these instances.""" - num_instances, base_options, security_groups = \ + """Provision the instances by passing the whole request to + the Scheduler for execution. Returns a Reservation ID + related to the creation of all of these instances.""" + num_instances, base_options, security_groups = \ self._check_create_parameters( context, instance_type, image_id, kernel_id, ramdisk_id, @@ -311,12 +311,12 @@ class API(base.Base): availability_zone, user_data, metadata, injected_files, zone_blob) - self._ask_scheduler_to_create_instance(context, base_options, + self._ask_scheduler_to_create_instance(context, base_options, instance_type, zone_blob, availability_zone, injected_files, num_instances=num_instances) - return base_options['reservation_id'] + return base_options['reservation_id'] def create(self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, @@ -330,7 +330,7 @@ class API(base.Base): instance requests to the Schedulers. This is fine for trival Scheduler drivers, but may remove the effectiveness of the more complicated drivers. - + Returns a list of instance dicts. """ @@ -343,7 +343,7 @@ class API(base.Base): key_name, key_data, security_group, availability_zone, user_data, metadata, injected_files, zone_blob) - + instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): @@ -351,13 +351,13 @@ class API(base.Base): base_options, security_groups, num=num) instances.append(instance) instance_id = instance['id'] - + self._ask_scheduler_to_create_instance(context, base_options, instance_type, zone_blob, availability_zone, injected_files, instance_id=instance_id) - - return [x.items() for x in instances] + + return [dict(x.iteritems()) for x in instances] def smart_create(self, *args, **kwargs): """ diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 8123082f9..de0660713 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -87,10 +87,10 @@ def select(context, specs=None): params={"request_spec": specs}) -def get_scheduler_rules(context): +def should_create_all_at_once(context): """Returns a tuple of rules for how instances should be created given the current Scheduler driver being used.""" - return _call_scheduler('get_scheduler_rules', context=context, + return _call_scheduler('should_create_all_at_once', context=context, params={}) diff --git a/nova/scheduler/host_filter.py b/nova/scheduler/host_filter.py index d9771754a..ed76c90bf 100644 --- a/nova/scheduler/host_filter.py +++ b/nova/scheduler/host_filter.py @@ -296,13 +296,13 @@ class HostFilterScheduler(zone_aware_scheduler.ZoneAwareScheduler): hosts for weighing. The particular filter used may be passed in as an argument or the default will be used. - request_spec = {'filter_name': , + request_spec = {'filter': , 'instance_type': } """ def filter_hosts(self, num, request_spec): """Filter the full host list (from the ZoneManager)""" - filter_name = request_spec.get('filter_name', None) + filter_name = request_spec.get('filter', None) host_filter = choose_host_filter(filter_name) # TODO(sandy): We're only using InstanceType-based specs -- cgit From 0f7ac8903dd05d3477bad014c269470d395c879a Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 11:20:40 -0500 Subject: MySQL database tables are currently using the MyISAM engine. Created migration script nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py to change all current tables to InnoDB. --- .../versions/019_set_engine_mysql_innodb.py | 57 ---------------------- .../versions/020_set_engine_mysql_innodb.py | 57 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 57 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/019_set_engine_mysql_innodb.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/019_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/019_set_engine_mysql_innodb.py deleted file mode 100644 index be7ff5abd..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/019_set_engine_mysql_innodb.py +++ /dev/null @@ -1,57 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 OpenStack LLC. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from sqlalchemy import MetaData, Table - -meta = MetaData() - -def upgrade(migrate_engine): - # Upgrade operations go here. Don't create your own engine; - # bind migrate_engine to your metadata - meta.bind = migrate_engine - if migrate_engine.name == "mysql": - migrate_engine.execute("ALTER TABLE auth_tokens Engine=InnoDB") - migrate_engine.execute("ALTER TABLE certificates Engine=InnoDB") - migrate_engine.execute("ALTER TABLE compute_nodes Engine=InnoDB") - migrate_engine.execute("ALTER TABLE console_pools Engine=InnoDB") - migrate_engine.execute("ALTER TABLE consoles Engine=InnoDB") - migrate_engine.execute("ALTER TABLE export_devices Engine=InnoDB") - migrate_engine.execute("ALTER TABLE fixed_ips Engine=InnoDB") - migrate_engine.execute("ALTER TABLE floating_ips Engine=InnoDB") - migrate_engine.execute("ALTER TABLE instance_actions Engine=InnoDB") - migrate_engine.execute("ALTER TABLE instance_metadata Engine=InnoDB") - migrate_engine.execute("ALTER TABLE instance_types Engine=InnoDB") - migrate_engine.execute("ALTER TABLE instances Engine=InnoDB") - migrate_engine.execute("ALTER TABLE iscsi_targets Engine=InnoDB") - migrate_engine.execute("ALTER TABLE key_pairs Engine=InnoDB") - migrate_engine.execute("ALTER TABLE migrate_version Engine=InnoDB") - migrate_engine.execute("ALTER TABLE migrations Engine=InnoDB") - migrate_engine.execute("ALTER TABLE networks Engine=InnoDB") - migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") - migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_group_instance_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_group_rules Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") - migrate_engine.execute("ALTER TABLE services Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_project_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_project_role_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_role_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE users Engine=InnoDB") - migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") - migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") - -def downgrade(migrate_engine): - meta.bind = migrate_engine diff --git a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py new file mode 100644 index 000000000..be7ff5abd --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py @@ -0,0 +1,57 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import MetaData, Table + +meta = MetaData() + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + if migrate_engine.name == "mysql": + migrate_engine.execute("ALTER TABLE auth_tokens Engine=InnoDB") + migrate_engine.execute("ALTER TABLE certificates Engine=InnoDB") + migrate_engine.execute("ALTER TABLE compute_nodes Engine=InnoDB") + migrate_engine.execute("ALTER TABLE console_pools Engine=InnoDB") + migrate_engine.execute("ALTER TABLE consoles Engine=InnoDB") + migrate_engine.execute("ALTER TABLE export_devices Engine=InnoDB") + migrate_engine.execute("ALTER TABLE fixed_ips Engine=InnoDB") + migrate_engine.execute("ALTER TABLE floating_ips Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_actions Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_metadata Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instance_types Engine=InnoDB") + migrate_engine.execute("ALTER TABLE instances Engine=InnoDB") + migrate_engine.execute("ALTER TABLE iscsi_targets Engine=InnoDB") + migrate_engine.execute("ALTER TABLE key_pairs Engine=InnoDB") + migrate_engine.execute("ALTER TABLE migrate_version Engine=InnoDB") + migrate_engine.execute("ALTER TABLE migrations Engine=InnoDB") + migrate_engine.execute("ALTER TABLE networks Engine=InnoDB") + migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") + migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_group_instance_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_group_rules Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") + migrate_engine.execute("ALTER TABLE services Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_project_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_project_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE users Engine=InnoDB") + migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") + migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") + +def downgrade(migrate_engine): + meta.bind = migrate_engine -- cgit From 6bf9bd5f785ed4fc1ca576e5b729e75fc0a3aa27 Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 11:25:38 -0500 Subject: MySQL database tables are currently using the MyISAM engine. Created migration script nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py to change all current tables to InnoDB. --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index b17c4f63e..0ce729261 100644 --- a/Authors +++ b/Authors @@ -28,6 +28,7 @@ Gabe Westmaas Hisaharu Ishii Hisaki Ohara Ilya Alekseyev +Isaku Yamahata Jason Cannavale Jason Koelker Jay Pipes -- cgit From b6e9072a89396aaf1ab616671fd427ec059a2daa Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 11:31:35 -0500 Subject: Cleaned up pep8 errors. --- Authors | 1 - .../versions/020_set_engine_mysql_innodb.py | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Authors b/Authors index 0ce729261..b17c4f63e 100644 --- a/Authors +++ b/Authors @@ -28,7 +28,6 @@ Gabe Westmaas Hisaharu Ishii Hisaki Ohara Ilya Alekseyev -Isaku Yamahata Jason Cannavale Jason Koelker Jay Pipes diff --git a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py index be7ff5abd..32126a453 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py @@ -18,6 +18,7 @@ from sqlalchemy import MetaData, Table meta = MetaData() + def upgrade(migrate_engine): # Upgrade operations go here. Don't create your own engine; # bind migrate_engine to your metadata @@ -42,16 +43,22 @@ def upgrade(migrate_engine): migrate_engine.execute("ALTER TABLE networks Engine=InnoDB") migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_group_instance_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_group_rules Engine=InnoDB") + migrate_engine.execute("ALTER TABLE + security_group_instance_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE + security_group_rules Engine=InnoDB") migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") migrate_engine.execute("ALTER TABLE services Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_project_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_project_role_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE user_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE + user_project_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE + user_project_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE + user_role_association Engine=InnoDB") migrate_engine.execute("ALTER TABLE users Engine=InnoDB") migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") + def downgrade(migrate_engine): meta.bind = migrate_engine -- cgit From 51247c01f8ec3b89657c130935d039ae9fa776b0 Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 11:35:13 -0500 Subject: Cleaned up text conflict. --- .../migrate_repo/versions/020_set_engine_mysql_innodb.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py index 32126a453..9b565598f 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py @@ -43,18 +43,25 @@ def upgrade(migrate_engine): migrate_engine.execute("ALTER TABLE networks Engine=InnoDB") migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_group_instance_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_group_rules Engine=InnoDB") + migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") migrate_engine.execute("ALTER TABLE services Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_project_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_project_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE user_role_association Engine=InnoDB") + migrate_engine.execute("ALTER TABLE users Engine=InnoDB") migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") -- cgit From e16ac0dbe6d1ca73ef6bb8f906c2dfdf2269ab6d Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 11:43:38 -0500 Subject: Cleaned up text conflict. --- Authors | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Authors b/Authors index b17c4f63e..53b336ce1 100644 --- a/Authors +++ b/Authors @@ -1,4 +1,5 @@ Alex Meade +Andrey Brindeyev Andy Smith Andy Southgate Anne Gentle @@ -16,6 +17,7 @@ Christian Berendt Chuck Short Cory Wright Dan Prince +Dave Walker David Pravec Dean Troyer Devin Carlen @@ -28,6 +30,7 @@ Gabe Westmaas Hisaharu Ishii Hisaki Ohara Ilya Alekseyev +Isaku Yamahata Jason Cannavale Jason Koelker Jay Pipes @@ -65,6 +68,7 @@ Nachi Ueno Naveed Massjouni Nirmal Ranganathan Paul Voccio +Renuka Apte Ricardo Carrillo Cruz Rick Clark Rick Harris @@ -81,6 +85,7 @@ Trey Morris Tushar Patil Vasiliy Shlykov Vishvananda Ishaya +Vivek Y S William Wolf Yoshiaki Tamura Youcef Laribi -- cgit From 2010bd7f8c200a95496cc47e395a21fc9f4e278e Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 16:23:17 -0500 Subject: Cleaned up bug introduced after fixing ^Cp8 errors. --- .../versions/020_set_engine_mysql_innodb.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py index 9b565598f..960b04037 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py @@ -44,23 +44,23 @@ def upgrade(migrate_engine): migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") - migrate_engine.execute("ALTER TABLE - security_group_instance_association Engine=InnoDB") + migrate_engine.execute( + "ALTER TABLE security_group_instance_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE - security_group_rules Engine=InnoDB") + migrate_engine.execute( + "ALTER TABLE security_group_rules Engine=InnoDB") migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") migrate_engine.execute("ALTER TABLE services Engine=InnoDB") - migrate_engine.execute("ALTER TABLE - user_project_association Engine=InnoDB") + migrate_engine.execute( + "ALTER TABLE user_project_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE - user_project_role_association Engine=InnoDB") + migrate_engine.execute( + "ALTER TABLE user_project_role_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE - user_role_association Engine=InnoDB") + migrate_engine.execute( + "ALTER TABLE user_role_association Engine=InnoDB") migrate_engine.execute("ALTER TABLE users Engine=InnoDB") migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") -- cgit From 75cf63108befbc4dbc7f61c36862a43defb90654 Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 16:28:43 -0500 Subject: Cleaned up bug introduced after fixing pep8 errors. --- .../migrate_repo/versions/020_set_engine_mysql_innodb.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py index 960b04037..c49e37733 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py @@ -43,25 +43,18 @@ def upgrade(migrate_engine): migrate_engine.execute("ALTER TABLE networks Engine=InnoDB") migrate_engine.execute("ALTER TABLE projects Engine=InnoDB") migrate_engine.execute("ALTER TABLE quotas Engine=InnoDB") - migrate_engine.execute( "ALTER TABLE security_group_instance_association Engine=InnoDB") - migrate_engine.execute( "ALTER TABLE security_group_rules Engine=InnoDB") - migrate_engine.execute("ALTER TABLE security_groups Engine=InnoDB") migrate_engine.execute("ALTER TABLE services Engine=InnoDB") - migrate_engine.execute( "ALTER TABLE user_project_association Engine=InnoDB") - migrate_engine.execute( "ALTER TABLE user_project_role_association Engine=InnoDB") - migrate_engine.execute( "ALTER TABLE user_role_association Engine=InnoDB") - migrate_engine.execute("ALTER TABLE users Engine=InnoDB") migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") -- cgit From abeef6b6942b05469daceac4f95ac75f5b23fda5 Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 16:41:32 -0500 Subject: Added new snapshots table to InnoDB migrations. --- nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py index c49e37733..6e590479f 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/020_set_engine_mysql_innodb.py @@ -58,6 +58,7 @@ def upgrade(migrate_engine): migrate_engine.execute("ALTER TABLE users Engine=InnoDB") migrate_engine.execute("ALTER TABLE volumes Engine=InnoDB") migrate_engine.execute("ALTER TABLE zones Engine=InnoDB") + migrate_engine.execute("ALTER TABLE snapshots Engine=InnoDB") def downgrade(migrate_engine): -- cgit From 2ff20fdde84ea80d910b6a16e83135fca1aabafa Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 16:53:30 -0500 Subject: Incremented version of migration script to reflect changes in trunk. --- dist/nova-2011.3-py2.6.egg | Bin 1563180 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 dist/nova-2011.3-py2.6.egg diff --git a/dist/nova-2011.3-py2.6.egg b/dist/nova-2011.3-py2.6.egg deleted file mode 100644 index 8a8808d31..000000000 Binary files a/dist/nova-2011.3-py2.6.egg and /dev/null differ -- cgit From de7ae78561641bab3ba2d5783ec64acf67e96fb3 Mon Sep 17 00:00:00 2001 From: Jason Cannavale Date: Tue, 31 May 2011 16:59:30 -0500 Subject: Incremented version of migration script to reflect changes in trunk. --- nova.egg-info/PKG-INFO | 10 - nova.egg-info/SOURCES.txt | 641 ------------------------------------- nova.egg-info/dependency_links.txt | 1 - nova.egg-info/top_level.txt | 1 - 4 files changed, 653 deletions(-) delete mode 100644 nova.egg-info/PKG-INFO delete mode 100644 nova.egg-info/SOURCES.txt delete mode 100644 nova.egg-info/dependency_links.txt delete mode 100644 nova.egg-info/top_level.txt diff --git a/nova.egg-info/PKG-INFO b/nova.egg-info/PKG-INFO deleted file mode 100644 index 66fe27559..000000000 --- a/nova.egg-info/PKG-INFO +++ /dev/null @@ -1,10 +0,0 @@ -Metadata-Version: 1.0 -Name: nova -Version: 2011.3 -Summary: cloud computing fabric controller -Home-page: http://www.openstack.org/ -Author: OpenStack -Author-email: nova@lists.launchpad.net -License: UNKNOWN -Description: UNKNOWN -Platform: UNKNOWN diff --git a/nova.egg-info/SOURCES.txt b/nova.egg-info/SOURCES.txt deleted file mode 100644 index f45cd523a..000000000 --- a/nova.egg-info/SOURCES.txt +++ /dev/null @@ -1,641 +0,0 @@ -Authors -HACKING -LICENSE -MANIFEST.in -README -builddeb.sh -pylintrc -run_tests.py -run_tests.sh -setup.cfg -setup.py -bin/nova-ajax-console-proxy -bin/nova-api -bin/nova-compute -bin/nova-console -bin/nova-dhcpbridge -bin/nova-direct-api -bin/nova-import-canonical-imagestore -bin/nova-instancemonitor -bin/nova-logspool -bin/nova-manage -bin/nova-network -bin/nova-objectstore -bin/nova-scheduler -bin/nova-spoolsentry -bin/nova-vncproxy -bin/nova-volume -bin/stack -bzrplugins/novalog/__init__.py -contrib/nova.sh -contrib/boto_v6/__init__.py -contrib/boto_v6/ec2/__init__.py -contrib/boto_v6/ec2/connection.py -contrib/boto_v6/ec2/instance.py -doc/.autogenerated -doc/Makefile -doc/README.rst -doc/find_autodoc_modules.sh -doc/generate_autodoc_index.sh -doc/build/.placeholder -doc/build/html/.buildinfo -doc/ext/__init__.py -doc/ext/nova_autodoc.py -doc/ext/nova_todo.py -doc/source/cloud101.rst -doc/source/code.rst -doc/source/community.rst -doc/source/conf.py -doc/source/conf_back.py -doc/source/index.rst -doc/source/installer.rst -doc/source/livecd.rst -doc/source/nova.concepts.rst -doc/source/object.model.rst -doc/source/quickstart.rst -doc/source/service.architecture.rst -doc/source/vmwareapi_readme.rst -doc/source/_ga/layout.html -doc/source/_static/.placeholder -doc/source/_static/jquery.tweet.js -doc/source/_static/tweaks.css -doc/source/_templates/.placeholder -doc/source/_theme/layout.html -doc/source/_theme/theme.conf -doc/source/api/autoindex.rst -doc/source/api/nova..adminclient.rst -doc/source/api/nova..api.direct.rst -doc/source/api/nova..api.ec2.admin.rst -doc/source/api/nova..api.ec2.apirequest.rst -doc/source/api/nova..api.ec2.cloud.rst -doc/source/api/nova..api.ec2.metadatarequesthandler.rst -doc/source/api/nova..api.openstack.auth.rst -doc/source/api/nova..api.openstack.backup_schedules.rst -doc/source/api/nova..api.openstack.common.rst -doc/source/api/nova..api.openstack.consoles.rst -doc/source/api/nova..api.openstack.faults.rst -doc/source/api/nova..api.openstack.flavors.rst -doc/source/api/nova..api.openstack.images.rst -doc/source/api/nova..api.openstack.servers.rst -doc/source/api/nova..api.openstack.shared_ip_groups.rst -doc/source/api/nova..api.openstack.zones.rst -doc/source/api/nova..auth.dbdriver.rst -doc/source/api/nova..auth.fakeldap.rst -doc/source/api/nova..auth.ldapdriver.rst -doc/source/api/nova..auth.manager.rst -doc/source/api/nova..auth.signer.rst -doc/source/api/nova..cloudpipe.pipelib.rst -doc/source/api/nova..compute.api.rst -doc/source/api/nova..compute.instance_types.rst -doc/source/api/nova..compute.manager.rst -doc/source/api/nova..compute.monitor.rst -doc/source/api/nova..compute.power_state.rst -doc/source/api/nova..console.api.rst -doc/source/api/nova..console.fake.rst -doc/source/api/nova..console.manager.rst -doc/source/api/nova..console.xvp.rst -doc/source/api/nova..context.rst -doc/source/api/nova..crypto.rst -doc/source/api/nova..db.api.rst -doc/source/api/nova..db.base.rst -doc/source/api/nova..db.migration.rst -doc/source/api/nova..db.sqlalchemy.api.rst -doc/source/api/nova..db.sqlalchemy.migrate_repo.manage.rst -doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.001_austin.rst -doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.002_bexar.rst -doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.003_add_label_to_networks.rst -doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.004_add_zone_tables.rst -doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata.rst -doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes.rst -doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types.rst -doc/source/api/nova..db.sqlalchemy.migration.rst -doc/source/api/nova..db.sqlalchemy.models.rst -doc/source/api/nova..db.sqlalchemy.session.rst -doc/source/api/nova..exception.rst -doc/source/api/nova..fakememcache.rst -doc/source/api/nova..fakerabbit.rst -doc/source/api/nova..flags.rst -doc/source/api/nova..image.glance.rst -doc/source/api/nova..image.local.rst -doc/source/api/nova..image.s3.rst -doc/source/api/nova..image.service.rst -doc/source/api/nova..log.rst -doc/source/api/nova..manager.rst -doc/source/api/nova..network.api.rst -doc/source/api/nova..network.linux_net.rst -doc/source/api/nova..network.manager.rst -doc/source/api/nova..objectstore.bucket.rst -doc/source/api/nova..objectstore.handler.rst -doc/source/api/nova..objectstore.image.rst -doc/source/api/nova..objectstore.stored.rst -doc/source/api/nova..quota.rst -doc/source/api/nova..rpc.rst -doc/source/api/nova..scheduler.chance.rst -doc/source/api/nova..scheduler.driver.rst -doc/source/api/nova..scheduler.manager.rst -doc/source/api/nova..scheduler.simple.rst -doc/source/api/nova..scheduler.zone.rst -doc/source/api/nova..service.rst -doc/source/api/nova..test.rst -doc/source/api/nova..tests.api.openstack.fakes.rst -doc/source/api/nova..tests.api.openstack.test_adminapi.rst -doc/source/api/nova..tests.api.openstack.test_api.rst -doc/source/api/nova..tests.api.openstack.test_auth.rst -doc/source/api/nova..tests.api.openstack.test_common.rst -doc/source/api/nova..tests.api.openstack.test_faults.rst -doc/source/api/nova..tests.api.openstack.test_flavors.rst -doc/source/api/nova..tests.api.openstack.test_images.rst -doc/source/api/nova..tests.api.openstack.test_ratelimiting.rst -doc/source/api/nova..tests.api.openstack.test_servers.rst -doc/source/api/nova..tests.api.openstack.test_shared_ip_groups.rst -doc/source/api/nova..tests.api.openstack.test_zones.rst -doc/source/api/nova..tests.api.test_wsgi.rst -doc/source/api/nova..tests.db.fakes.rst -doc/source/api/nova..tests.declare_flags.rst -doc/source/api/nova..tests.fake_flags.rst -doc/source/api/nova..tests.glance.stubs.rst -doc/source/api/nova..tests.hyperv_unittest.rst -doc/source/api/nova..tests.objectstore_unittest.rst -doc/source/api/nova..tests.real_flags.rst -doc/source/api/nova..tests.runtime_flags.rst -doc/source/api/nova..tests.test_access.rst -doc/source/api/nova..tests.test_api.rst -doc/source/api/nova..tests.test_auth.rst -doc/source/api/nova..tests.test_cloud.rst -doc/source/api/nova..tests.test_compute.rst -doc/source/api/nova..tests.test_console.rst -doc/source/api/nova..tests.test_direct.rst -doc/source/api/nova..tests.test_flags.rst -doc/source/api/nova..tests.test_instance_types.rst -doc/source/api/nova..tests.test_localization.rst -doc/source/api/nova..tests.test_log.rst -doc/source/api/nova..tests.test_middleware.rst -doc/source/api/nova..tests.test_misc.rst -doc/source/api/nova..tests.test_network.rst -doc/source/api/nova..tests.test_quota.rst -doc/source/api/nova..tests.test_rpc.rst -doc/source/api/nova..tests.test_scheduler.rst -doc/source/api/nova..tests.test_service.rst -doc/source/api/nova..tests.test_test.rst -doc/source/api/nova..tests.test_twistd.rst -doc/source/api/nova..tests.test_utils.rst -doc/source/api/nova..tests.test_virt.rst -doc/source/api/nova..tests.test_volume.rst -doc/source/api/nova..tests.test_xenapi.rst -doc/source/api/nova..tests.xenapi.stubs.rst -doc/source/api/nova..twistd.rst -doc/source/api/nova..utils.rst -doc/source/api/nova..version.rst -doc/source/api/nova..virt.connection.rst -doc/source/api/nova..virt.disk.rst -doc/source/api/nova..virt.fake.rst -doc/source/api/nova..virt.hyperv.rst -doc/source/api/nova..virt.images.rst -doc/source/api/nova..virt.libvirt_conn.rst -doc/source/api/nova..virt.xenapi.fake.rst -doc/source/api/nova..virt.xenapi.network_utils.rst -doc/source/api/nova..virt.xenapi.vm_utils.rst -doc/source/api/nova..virt.xenapi.vmops.rst -doc/source/api/nova..virt.xenapi.volume_utils.rst -doc/source/api/nova..virt.xenapi.volumeops.rst -doc/source/api/nova..virt.xenapi_conn.rst -doc/source/api/nova..volume.api.rst -doc/source/api/nova..volume.driver.rst -doc/source/api/nova..volume.manager.rst -doc/source/api/nova..volume.san.rst -doc/source/api/nova..wsgi.rst -doc/source/devref/addmethod.openstackapi.rst -doc/source/devref/api.rst -doc/source/devref/architecture.rst -doc/source/devref/auth.rst -doc/source/devref/cloudpipe.rst -doc/source/devref/compute.rst -doc/source/devref/database.rst -doc/source/devref/development.environment.rst -doc/source/devref/down.sh -doc/source/devref/fakes.rst -doc/source/devref/glance.rst -doc/source/devref/index.rst -doc/source/devref/interfaces -doc/source/devref/modules.rst -doc/source/devref/network.rst -doc/source/devref/nova.rst -doc/source/devref/objectstore.rst -doc/source/devref/rabbit.rst -doc/source/devref/rc.local -doc/source/devref/scheduler.rst -doc/source/devref/server.conf.template -doc/source/devref/services.rst -doc/source/devref/up.sh -doc/source/devref/volume.rst -doc/source/devref/zone.rst -doc/source/images/NOVA_ARCH.png -doc/source/images/NOVA_ARCH.svg -doc/source/images/NOVA_ARCH_200dpi.png -doc/source/images/NOVA_ARCH_66dpi.png -doc/source/images/NOVA_clouds_A_B.png -doc/source/images/NOVA_clouds_A_B.svg -doc/source/images/NOVA_clouds_C1_C2.svg -doc/source/images/NOVA_clouds_C1_C2.svg.png -doc/source/images/Novadiagram.png -doc/source/images/cloudpipe.png -doc/source/images/fabric.png -doc/source/images/novascreens.png -doc/source/images/novashvirtually.png -doc/source/images/vmwareapi_blockdiagram.jpg -doc/source/images/rabbit/arch.png -doc/source/images/rabbit/arch.svg -doc/source/images/rabbit/flow1.png -doc/source/images/rabbit/flow1.svg -doc/source/images/rabbit/flow2.png -doc/source/images/rabbit/flow2.svg -doc/source/images/rabbit/rabt.png -doc/source/images/rabbit/rabt.svg -doc/source/images/rabbit/state.png -doc/source/man/novamanage.rst -doc/source/runnova/binaries.rst -doc/source/runnova/euca2ools.rst -doc/source/runnova/flags.rst -doc/source/runnova/getting.started.rst -doc/source/runnova/index.rst -doc/source/runnova/managing.images.rst -doc/source/runnova/managing.instance.types.rst -doc/source/runnova/managing.instances.rst -doc/source/runnova/managing.networks.rst -doc/source/runnova/managing.projects.rst -doc/source/runnova/managing.users.rst -doc/source/runnova/managingsecurity.rst -doc/source/runnova/monitoring.rst -doc/source/runnova/network.flat.rst -doc/source/runnova/network.vlan.rst -doc/source/runnova/nova.manage.rst -doc/source/runnova/vncconsole.rst -etc/nova/api-paste.ini -nova/__init__.py -nova/context.py -nova/crypto.py -nova/exception.py -nova/fakememcache.py -nova/fakerabbit.py -nova/flags.py -nova/log.py -nova/manager.py -nova/quota.py -nova/rpc.py -nova/service.py -nova/test.py -nova/twistd.py -nova/utils.py -nova/vcsversion.py -nova/version.py -nova/wsgi.py -nova.egg-info/PKG-INFO -nova.egg-info/SOURCES.txt -nova.egg-info/dependency_links.txt -nova.egg-info/top_level.txt -nova/CA/.gitignore -nova/CA/geninter.sh -nova/CA/genrootca.sh -nova/CA/genvpn.sh -nova/CA/openssl.cnf.tmpl -nova/CA/newcerts/.placeholder -nova/CA/private/.placeholder -nova/CA/projects/.gitignore -nova/CA/projects/.placeholder -nova/CA/reqs/.gitignore -nova/CA/reqs/.placeholder -nova/api/__init__.py -nova/api/direct.py -nova/api/ec2/__init__.py -nova/api/ec2/admin.py -nova/api/ec2/apirequest.py -nova/api/ec2/cloud.py -nova/api/ec2/ec2utils.py -nova/api/ec2/metadatarequesthandler.py -nova/api/openstack/__init__.py -nova/api/openstack/accounts.py -nova/api/openstack/auth.py -nova/api/openstack/backup_schedules.py -nova/api/openstack/common.py -nova/api/openstack/consoles.py -nova/api/openstack/extensions.py -nova/api/openstack/faults.py -nova/api/openstack/flavors.py -nova/api/openstack/image_metadata.py -nova/api/openstack/images.py -nova/api/openstack/ips.py -nova/api/openstack/limits.py -nova/api/openstack/notes.txt -nova/api/openstack/server_metadata.py -nova/api/openstack/servers.py -nova/api/openstack/shared_ip_groups.py -nova/api/openstack/users.py -nova/api/openstack/versions.py -nova/api/openstack/zones.py -nova/api/openstack/contrib/__init__.py -nova/api/openstack/contrib/volumes.py -nova/api/openstack/ratelimiting/__init__.py -nova/api/openstack/views/__init__.py -nova/api/openstack/views/addresses.py -nova/api/openstack/views/flavors.py -nova/api/openstack/views/images.py -nova/api/openstack/views/limits.py -nova/api/openstack/views/servers.py -nova/api/openstack/views/versions.py -nova/auth/__init__.py -nova/auth/dbdriver.py -nova/auth/fakeldap.py -nova/auth/ldapdriver.py -nova/auth/manager.py -nova/auth/nova_openldap.schema -nova/auth/nova_sun.schema -nova/auth/novarc.template -nova/auth/opendj.sh -nova/auth/openssh-lpk_openldap.schema -nova/auth/openssh-lpk_sun.schema -nova/auth/signer.py -nova/auth/slap.sh -nova/cloudpipe/__init__.py -nova/cloudpipe/bootscript.template -nova/cloudpipe/client.ovpn.template -nova/cloudpipe/pipelib.py -nova/compute/__init__.py -nova/compute/api.py -nova/compute/fakevirtinstance.xml -nova/compute/instance_types.py -nova/compute/manager.py -nova/compute/monitor.py -nova/compute/power_state.py -nova/console/__init__.py -nova/console/api.py -nova/console/fake.py -nova/console/manager.py -nova/console/vmrc.py -nova/console/vmrc_manager.py -nova/console/xvp.conf.template -nova/console/xvp.py -nova/db/__init__.py -nova/db/api.py -nova/db/base.py -nova/db/migration.py -nova/db/sqlalchemy/__init__.py -nova/db/sqlalchemy/api.py -nova/db/sqlalchemy/migration.py -nova/db/sqlalchemy/models.py -nova/db/sqlalchemy/session.py -nova/db/sqlalchemy/migrate_repo/README -nova/db/sqlalchemy/migrate_repo/__init__.py -nova/db/sqlalchemy/migrate_repo/manage.py -nova/db/sqlalchemy/migrate_repo/migrate.cfg -nova/db/sqlalchemy/migrate_repo/versions/001_austin.py -nova/db/sqlalchemy/migrate_repo/versions/002_bexar.py -nova/db/sqlalchemy/migrate_repo/versions/003_add_label_to_networks.py -nova/db/sqlalchemy/migrate_repo/versions/004_add_zone_tables.py -nova/db/sqlalchemy/migrate_repo/versions/005_add_instance_metadata.py -nova/db/sqlalchemy/migrate_repo/versions/006_add_provider_data_to_volumes.py -nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_to_fixed_ips.py -nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py -nova/db/sqlalchemy/migrate_repo/versions/009_add_instance_migrations.py -nova/db/sqlalchemy/migrate_repo/versions/010_add_os_type_to_instances.py -nova/db/sqlalchemy/migrate_repo/versions/011_live_migration.py -nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py -nova/db/sqlalchemy/migrate_repo/versions/013_add_flavors_to_migrations.py -nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py -nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py -nova/db/sqlalchemy/migrate_repo/versions/016_make_quotas_key_and_value.py -nova/db/sqlalchemy/migrate_repo/versions/017_make_instance_type_id_an_integer.py -nova/db/sqlalchemy/migrate_repo/versions/018_rename_server_management_url.py -nova/db/sqlalchemy/migrate_repo/versions/019_add_volume_snapshot_support.py -nova/db/sqlalchemy/migrate_repo/versions/020_add_snapshot_id_to_volumes.py -nova/db/sqlalchemy/migrate_repo/versions/021_set_engine_mysql_innodb.py -nova/db/sqlalchemy/migrate_repo/versions/__init__.py -nova/image/__init__.py -nova/image/fake.py -nova/image/glance.py -nova/image/local.py -nova/image/s3.py -nova/image/service.py -nova/ipv6/__init__.py -nova/ipv6/account_identifier.py -nova/ipv6/api.py -nova/ipv6/rfc2462.py -nova/network/__init__.py -nova/network/api.py -nova/network/linux_net.py -nova/network/manager.py -nova/network/vmwareapi_net.py -nova/network/xenapi_net.py -nova/notifier/__init__.py -nova/notifier/api.py -nova/notifier/log_notifier.py -nova/notifier/no_op_notifier.py -nova/notifier/rabbit_notifier.py -nova/objectstore/__init__.py -nova/objectstore/s3server.py -nova/scheduler/__init__.py -nova/scheduler/api.py -nova/scheduler/chance.py -nova/scheduler/driver.py -nova/scheduler/host_filter.py -nova/scheduler/manager.py -nova/scheduler/simple.py -nova/scheduler/zone.py -nova/scheduler/zone_aware_scheduler.py -nova/scheduler/zone_manager.py -nova/tests/__init__.py -nova/tests/declare_flags.py -nova/tests/fake_flags.py -nova/tests/fake_utils.py -nova/tests/hyperv_unittest.py -nova/tests/runtime_flags.py -nova/tests/test_access.py -nova/tests/test_api.py -nova/tests/test_auth.py -nova/tests/test_cloud.py -nova/tests/test_compute.py -nova/tests/test_console.py -nova/tests/test_crypto.py -nova/tests/test_direct.py -nova/tests/test_exception.py -nova/tests/test_flags.py -nova/tests/test_flat_network.py -nova/tests/test_host_filter.py -nova/tests/test_instance_types.py -nova/tests/test_ipv6.py -nova/tests/test_libvirt.py -nova/tests/test_localization.py -nova/tests/test_log.py -nova/tests/test_middleware.py -nova/tests/test_misc.py -nova/tests/test_network.py -nova/tests/test_notifier.py -nova/tests/test_objectstore.py -nova/tests/test_quota.py -nova/tests/test_rpc.py -nova/tests/test_scheduler.py -nova/tests/test_service.py -nova/tests/test_test.py -nova/tests/test_twistd.py -nova/tests/test_utils.py -nova/tests/test_vlan_network.py -nova/tests/test_vmwareapi.py -nova/tests/test_volume.py -nova/tests/test_xenapi.py -nova/tests/test_zone_aware_scheduler.py -nova/tests/test_zones.py -nova/tests/CA/cacert.pem -nova/tests/CA/private/cakey.pem -nova/tests/api/__init__.py -nova/tests/api/test_wsgi.py -nova/tests/api/openstack/__init__.py -nova/tests/api/openstack/common.py -nova/tests/api/openstack/fakes.py -nova/tests/api/openstack/test_accounts.py -nova/tests/api/openstack/test_adminapi.py -nova/tests/api/openstack/test_api.py -nova/tests/api/openstack/test_auth.py -nova/tests/api/openstack/test_common.py -nova/tests/api/openstack/test_extensions.py -nova/tests/api/openstack/test_faults.py -nova/tests/api/openstack/test_flavors.py -nova/tests/api/openstack/test_image_metadata.py -nova/tests/api/openstack/test_images.py -nova/tests/api/openstack/test_limits.py -nova/tests/api/openstack/test_server_metadata.py -nova/tests/api/openstack/test_servers.py -nova/tests/api/openstack/test_shared_ip_groups.py -nova/tests/api/openstack/test_users.py -nova/tests/api/openstack/test_versions.py -nova/tests/api/openstack/test_zones.py -nova/tests/api/openstack/extensions/__init__.py -nova/tests/api/openstack/extensions/foxinsocks.py -nova/tests/bundle/1mb.manifest.xml -nova/tests/bundle/1mb.no_kernel_or_ramdisk.manifest.xml -nova/tests/bundle/1mb.part.0 -nova/tests/bundle/1mb.part.1 -nova/tests/db/__init__.py -nova/tests/db/fakes.py -nova/tests/db/nova.austin.sqlite -nova/tests/glance/__init__.py -nova/tests/glance/stubs.py -nova/tests/image/__init__.py -nova/tests/image/test_glance.py -nova/tests/integrated/__init__.py -nova/tests/integrated/integrated_helpers.py -nova/tests/integrated/test_extensions.py -nova/tests/integrated/test_login.py -nova/tests/integrated/test_servers.py -nova/tests/integrated/test_volumes.py -nova/tests/integrated/test_xml.py -nova/tests/integrated/api/__init__.py -nova/tests/integrated/api/client.py -nova/tests/network/__init__.py -nova/tests/network/base.py -nova/tests/public_key/dummy.fingerprint -nova/tests/public_key/dummy.pub -nova/tests/vmwareapi/__init__.py -nova/tests/vmwareapi/db_fakes.py -nova/tests/vmwareapi/stubs.py -nova/tests/xenapi/__init__.py -nova/tests/xenapi/stubs.py -nova/virt/__init__.py -nova/virt/connection.py -nova/virt/cpuinfo.xml.template -nova/virt/disk.py -nova/virt/driver.py -nova/virt/fake.py -nova/virt/hyperv.py -nova/virt/images.py -nova/virt/interfaces.template -nova/virt/libvirt.xml.template -nova/virt/vmwareapi_conn.py -nova/virt/xenapi_conn.py -nova/virt/libvirt/__init__.py -nova/virt/libvirt/connection.py -nova/virt/libvirt/firewall.py -nova/virt/libvirt/netutils.py -nova/virt/vmwareapi/__init__.py -nova/virt/vmwareapi/error_util.py -nova/virt/vmwareapi/fake.py -nova/virt/vmwareapi/io_util.py -nova/virt/vmwareapi/network_utils.py -nova/virt/vmwareapi/read_write_util.py -nova/virt/vmwareapi/vim.py -nova/virt/vmwareapi/vim_util.py -nova/virt/vmwareapi/vm_util.py -nova/virt/vmwareapi/vmops.py -nova/virt/vmwareapi/vmware_images.py -nova/virt/xenapi/__init__.py -nova/virt/xenapi/fake.py -nova/virt/xenapi/network_utils.py -nova/virt/xenapi/vm_utils.py -nova/virt/xenapi/vmops.py -nova/virt/xenapi/volume_utils.py -nova/virt/xenapi/volumeops.py -nova/vnc/__init__.py -nova/vnc/auth.py -nova/vnc/proxy.py -nova/volume/__init__.py -nova/volume/api.py -nova/volume/driver.py -nova/volume/manager.py -nova/volume/san.py -plugins/xenserver/doc/networking.rst -plugins/xenserver/networking/etc/init.d/host-rules -plugins/xenserver/networking/etc/xensource/scripts/vif_5.6-fp1.patch -plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py -plugins/xenserver/xenapi/README -plugins/xenserver/xenapi/etc/xapi.d/plugins/agent -plugins/xenserver/xenapi/etc/xapi.d/plugins/glance -plugins/xenserver/xenapi/etc/xapi.d/plugins/migration -plugins/xenserver/xenapi/etc/xapi.d/plugins/objectstore -plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py -plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost -plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py -po/ast.po -po/cs.po -po/da.po -po/de.po -po/es.po -po/it.po -po/ja.po -po/nova.pot -po/pt_BR.po -po/ru.po -po/uk.po -po/zh_CN.po -smoketests/__init__.py -smoketests/base.py -smoketests/flags.py -smoketests/openwrt-x86-ext2.image -smoketests/openwrt-x86-vmlinuz -smoketests/proxy.sh -smoketests/public_network_smoketests.py -smoketests/run_tests.py -smoketests/test_admin.py -smoketests/test_netadmin.py -smoketests/test_sysadmin.py -tools/clean-vlans -tools/euca-get-ajax-console -tools/eventlet-patch -tools/install_venv.py -tools/nova-debug -tools/pip-requires -tools/setup_iptables.sh -tools/with_venv.sh -tools/ajaxterm/README.txt -tools/ajaxterm/ajaxterm.1 -tools/ajaxterm/ajaxterm.css -tools/ajaxterm/ajaxterm.html -tools/ajaxterm/ajaxterm.js -tools/ajaxterm/ajaxterm.py -tools/ajaxterm/configure -tools/ajaxterm/configure.ajaxterm.bin -tools/ajaxterm/configure.initd.debian -tools/ajaxterm/configure.initd.gentoo -tools/ajaxterm/configure.initd.redhat -tools/ajaxterm/configure.makefile -tools/ajaxterm/qweb.py -tools/ajaxterm/sarissa.js -tools/ajaxterm/sarissa_dhtml.js -tools/esx/guest_tool.py \ No newline at end of file diff --git a/nova.egg-info/dependency_links.txt b/nova.egg-info/dependency_links.txt deleted file mode 100644 index 8b1378917..000000000 --- a/nova.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/nova.egg-info/top_level.txt b/nova.egg-info/top_level.txt deleted file mode 100644 index 31c787fdd..000000000 --- a/nova.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -nova -- cgit From 5b45d5477cfff946ada581676db54fb254be6522 Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Wed, 1 Jun 2011 16:40:19 +0400 Subject: osapi: added support for header X-Auth-Project-Id --- nova/api/openstack/auth.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py index 6c6ee22a2..e220ffcc2 100644 --- a/nova/api/openstack/auth.py +++ b/nova/api/openstack/auth.py @@ -50,19 +50,21 @@ class AuthMiddleware(wsgi.Middleware): if not self.has_authentication(req): return self.authenticate(req) user = self.get_user_by_authentication(req) - accounts = self.auth.get_projects(user=user) if not user: token = req.headers["X-Auth-Token"] msg = _("%(user)s could not be found with token '%(token)s'") LOG.warn(msg % locals()) return faults.Fault(webob.exc.HTTPUnauthorized()) - if accounts: - #we are punting on this til auth is settled, - #and possibly til api v1.1 (mdragon) - account = accounts[0] - else: - return faults.Fault(webob.exc.HTTPUnauthorized()) + try: + account = req.headers["X-Auth-Project-Id"] + except KeyError: + # FIXME: It needed only for compatibility + accounts = self.auth.get_projects(user=user) + if accounts: + account = accounts[0] + else: + return faults.Fault(webob.exc.HTTPUnauthorized()) if not self.auth.is_admin(user) and \ not self.auth.is_project_member(user, account): -- cgit From a1ea80431ea46aea5ec67cf152c7a7af5fd5aeac Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Fri, 3 Jun 2011 21:13:16 +0400 Subject: fix comment --- nova/api/openstack/auth.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py index e220ffcc2..774426d58 100644 --- a/nova/api/openstack/auth.py +++ b/nova/api/openstack/auth.py @@ -59,7 +59,8 @@ class AuthMiddleware(wsgi.Middleware): try: account = req.headers["X-Auth-Project-Id"] except KeyError: - # FIXME: It needed only for compatibility + # FIXME(usrleon): It needed only for compatibility + # while osapi clients don't use this header accounts = self.auth.get_projects(user=user) if accounts: account = accounts[0] -- cgit From 727317333978ac5cf0fb1cd3f86e49e9868f1e19 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 6 Jun 2011 17:58:40 -0700 Subject: fixed up tests after trunk merge --- nova/api/openstack/zones.py | 13 ++++--------- nova/compute/api.py | 10 +++++----- nova/tests/api/openstack/test_zones.py | 3 +++ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index 330aee85f..0f83afb34 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -58,12 +58,7 @@ def check_encryption_key(func): return wrapped -class Controller(common.OpenstackController): - - _serialization_metadata = { - 'application/xml': { - "attributes": { - "zone": ["id", "api_url", "name", "capabilities"]}}} +class Controller(object): def index(self, req): """Return all zones in brief""" @@ -114,12 +109,12 @@ class Controller(common.OpenstackController): return dict(zone=_scrub_zone(zone)) @check_encryption_key - def select(self, req): + def select(self, req, body): """Returns a weighted list of costs to create instances of desired capabilities.""" ctx = req.environ['nova.context'] - json_specs = json.loads(req.body) - specs = json.loads(json_specs) + print "**** ZONES ", body + specs = json.loads(body) build_plan = api.select(ctx, specs=specs) cooked = self._scrub_build_plan(build_plan) return {"weights": cooked} diff --git a/nova/compute/api.py b/nova/compute/api.py index 24f04f226..e09127d5c 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -134,7 +134,7 @@ class API(base.Base): raise quota.QuotaError(msg, "MetadataLimitExceeded") def _check_create_parameters(self, context, instance_type, - image_id, kernel_id=None, ramdisk_id=None, + image_href, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name='', display_description='', key_name=None, key_data=None, security_group='default', @@ -300,7 +300,7 @@ class API(base.Base): "injected_files": injected_files}}) def create_all_at_once(self, context, instance_type, - image_id, kernel_id=None, ramdisk_id=None, + image_href, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name='', display_description='', key_name=None, key_data=None, security_group='default', @@ -312,7 +312,7 @@ class API(base.Base): num_instances, base_options, security_groups = \ self._check_create_parameters( context, instance_type, - image_id, kernel_id, ramdisk_id, + image_href, kernel_id, ramdisk_id, min_count, max_count, display_name, display_description, key_name, key_data, security_group, @@ -328,7 +328,7 @@ class API(base.Base): return base_options['reservation_id'] def create(self, context, instance_type, - image_id, kernel_id=None, ramdisk_id=None, + image_href, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name='', display_description='', key_name=None, key_data=None, security_group='default', @@ -346,7 +346,7 @@ class API(base.Base): num_instances, base_options, security_groups = \ self._check_create_parameters( context, instance_type, - image_id, kernel_id, ramdisk_id, + image_href, kernel_id, ramdisk_id, min_count, max_count, display_name, display_description, key_name, key_data, security_group, diff --git a/nova/tests/api/openstack/test_zones.py b/nova/tests/api/openstack/test_zones.py index e21b5ce86..fc70a1679 100644 --- a/nova/tests/api/openstack/test_zones.py +++ b/nova/tests/api/openstack/test_zones.py @@ -210,11 +210,14 @@ class ZonesTest(test.TestCase): req = webob.Request.blank('/v1.0/zones/select') req.method = 'POST' + req.headers["Content-Type"] = "application/json" # Select queries end up being JSON encoded twice. # Once to a string and again as an HTTP POST Body req.body = json.dumps(json.dumps({})) + print "********** BODY", req.body res = req.get_response(fakes.wsgi_app()) + print "********** RES", res res_dict = json.loads(res.body) self.assertEqual(res.status_int, 200) -- cgit From 225c8cb8843de17abe192b5efc7c0bd9db0b4d75 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 6 Jun 2011 19:05:31 -0700 Subject: sanity check --- nova/api/openstack/zones.py | 1 - nova/scheduler/zone_aware_scheduler.py | 1 + nova/tests/api/openstack/test_zones.py | 2 -- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index 0f83afb34..b2f7898cb 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -113,7 +113,6 @@ class Controller(object): """Returns a weighted list of costs to create instances of desired capabilities.""" ctx = req.environ['nova.context'] - print "**** ZONES ", body specs = json.loads(body) build_plan = api.select(ctx, specs=specs) cooked = self._scrub_build_plan(build_plan) diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py index c125c7436..faa969124 100644 --- a/nova/scheduler/zone_aware_scheduler.py +++ b/nova/scheduler/zone_aware_scheduler.py @@ -22,6 +22,7 @@ across zones. There are two expansion points to this class for: import operator import json + import M2Crypto import novaclient diff --git a/nova/tests/api/openstack/test_zones.py b/nova/tests/api/openstack/test_zones.py index fc70a1679..098577e4c 100644 --- a/nova/tests/api/openstack/test_zones.py +++ b/nova/tests/api/openstack/test_zones.py @@ -215,9 +215,7 @@ class ZonesTest(test.TestCase): # Once to a string and again as an HTTP POST Body req.body = json.dumps(json.dumps({})) - print "********** BODY", req.body res = req.get_response(fakes.wsgi_app()) - print "********** RES", res res_dict = json.loads(res.body) self.assertEqual(res.status_int, 200) -- cgit From f0c4767dc14f950f7d18cc02e16e4d310774435d Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Tue, 7 Jun 2011 09:56:51 -0400 Subject: Fixed type causing pylint "exception is not callable" Added param to fake_instance_create, fake objects should appear like the real object. pylint "No value passed for parameter 'values' in function call" --- nova/tests/test_vmwareapi.py | 2 +- nova/tests/vmwareapi/db_fakes.py | 2 +- nova/virt/xenapi/vmops.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/tests/test_vmwareapi.py b/nova/tests/test_vmwareapi.py index e5ebd1600..eddf01e9f 100644 --- a/nova/tests/test_vmwareapi.py +++ b/nova/tests/test_vmwareapi.py @@ -69,7 +69,7 @@ class VMWareAPIVMTestCase(test.TestCase): 'instance_type': 'm1.large', 'mac_address': 'aa:bb:cc:dd:ee:ff', } - self.instance = db.instance_create(values) + self.instance = db.instance_create(None, values) def _create_vm(self): """Create and spawn the VM.""" diff --git a/nova/tests/vmwareapi/db_fakes.py b/nova/tests/vmwareapi/db_fakes.py index 764de42d8..d4eb87daf 100644 --- a/nova/tests/vmwareapi/db_fakes.py +++ b/nova/tests/vmwareapi/db_fakes.py @@ -52,7 +52,7 @@ def stub_out_db_instance_api(stubs): else: raise NotImplementedError() - def fake_instance_create(values): + def fake_instance_create(context, values): """Stubs out the db.instance_create method.""" type_data = INSTANCE_TYPES[values['instance_type']] diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 32dae97c2..c6d2b0936 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -101,7 +101,7 @@ class VMOps(object): if not vm_ref: vm_ref = VMHelper.lookup(self._session, instance.name) if vm_ref is None: - raise exception(_('Attempted to power on non-existent instance' + raise Exception(_('Attempted to power on non-existent instance' ' bad instance id %s') % instance.id) LOG.debug(_("Starting instance %s"), instance.name) self._session.call_xenapi('VM.start', vm_ref, False, False) -- cgit From c680176d11edb46a28ba065f0548e18cbf1297d5 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Tue, 7 Jun 2011 13:32:53 -0400 Subject: Fixed incorrect error message Added missing import Fixed Typo (pylint "undefined variable NoneV") --- nova/compute/instance_types.py | 2 +- nova/compute/monitor.py | 1 + nova/console/vmrc.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 1275a6fdd..1d246e445 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -114,7 +114,7 @@ def get_instance_type(id): ctxt = context.get_admin_context() return db.instance_type_get_by_id(ctxt, id) except exception.DBError: - raise exception.ApiError(_("Unknown instance type: %s") % name) + raise exception.ApiError(_("Unknown instance type: %s") % id) def get_instance_type_by_name(name): diff --git a/nova/compute/monitor.py b/nova/compute/monitor.py index 613734bef..9d8e2a25d 100644 --- a/nova/compute/monitor.py +++ b/nova/compute/monitor.py @@ -36,6 +36,7 @@ from twisted.application import service from nova import flags from nova import log as logging +from nova import utils from nova.virt import connection as virt_connection diff --git a/nova/console/vmrc.py b/nova/console/vmrc.py index cc8b0cdf5..fa805e019 100644 --- a/nova/console/vmrc.py +++ b/nova/console/vmrc.py @@ -119,7 +119,7 @@ class VMRCSessionConsole(VMRCConsole): """ vms = vim_session._call_method(vim_util, 'get_objects', 'VirtualMachine', ['name']) - vm_ref = NoneV + vm_ref = None for vm in vms: if vm.propSet[0].val == instance_name: vm_ref = vm.obj -- cgit From d920e7f53e59b1def67f7528dd6b6bcf35ba96b4 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Tue, 7 Jun 2011 14:33:01 -0400 Subject: Disabled pylint complaining about no 'self' parameter in a decorator function --- nova/auth/ldapdriver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/auth/ldapdriver.py b/nova/auth/ldapdriver.py index 183f7a985..7bcaa34b5 100644 --- a/nova/auth/ldapdriver.py +++ b/nova/auth/ldapdriver.py @@ -139,7 +139,7 @@ class LdapDriver(object): self.__cache = None return False - def __local_cache(key_fmt): + def __local_cache(key_fmt): #pylint: disable=E0213 """Wrap function to cache it's result in self.__cache. Works only with functions with one fixed argument. """ -- cgit From b7556544d222741c9bc0d312ae75ab5f84b4cd2d Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Tue, 7 Jun 2011 14:48:13 -0400 Subject: Removed use of super --- nova/api/openstack/versions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/versions.py b/nova/api/openstack/versions.py index 9db160102..4c682302f 100644 --- a/nova/api/openstack/versions.py +++ b/nova/api/openstack/versions.py @@ -35,7 +35,7 @@ class Versions(wsgi.Resource): 'application/xml': wsgi.XMLDictSerializer(metadata=metadata), } - super(Versions, self).__init__(None, serializers=serializers) + wsgi.Resource.__init__(self, None, serializers=serializers) def dispatch(self, request, *args): """Respond to a request for all OpenStack API versions.""" -- cgit From 49dcee9ac6a4f78cb021181d5310541d9a42fafd Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Wed, 8 Jun 2011 13:49:00 +0400 Subject: fix fake driver for using string project --- nova/tests/api/openstack/fakes.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py index 8e0156afa..ce24bd860 100644 --- a/nova/tests/api/openstack/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -328,6 +328,11 @@ class FakeAuthManager(object): return user.admin def is_project_member(self, user, project): + if not isinstance(project, Project): + try: + project = self.get_project(project) + except: + raise webob.exc.HTTPUnauthorized() return ((user.id in project.member_ids) or (user.id == project.project_manager_id)) -- cgit From f93717c7d74b24311c04f66b9e710322510d0ed2 Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Wed, 8 Jun 2011 13:50:33 +0400 Subject: added tests for X-Auth-Project-Id header --- nova/tests/api/openstack/test_auth.py | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/nova/tests/api/openstack/test_auth.py b/nova/tests/api/openstack/test_auth.py index 8f189c744..04ce78880 100644 --- a/nova/tests/api/openstack/test_auth.py +++ b/nova/tests/api/openstack/test_auth.py @@ -114,6 +114,28 @@ class Test(test.TestCase): self.assertEqual(result.status, '401 Unauthorized') self.assertEqual(self.destroy_called, True) + def test_authorize_project(self): + f = fakes.FakeAuthManager() + user = nova.auth.manager.User('id1', 'user1', 'user1_key', None, None) + f.add_user(user) + f.create_project('user1_project', user) + f.create_project('user2_project', user) + + req = webob.Request.blank('/v1.0/', {'HTTP_HOST': 'foo'}) + req.headers['X-Auth-User'] = 'user1' + req.headers['X-Auth-Key'] = 'user1_key' + result = req.get_response(fakes.wsgi_app()) + self.assertEqual(result.status, '204 No Content') + + token = result.headers['X-Auth-Token'] + self.stubs.Set(nova.api.openstack, 'APIRouterV10', fakes.FakeRouter) + req = webob.Request.blank('/v1.0/fake') + req.headers['X-Auth-Token'] = token + req.headers['X-Auth-Project-Id'] = 'user2_project' + result = req.get_response(fakes.wsgi_app()) + self.assertEqual(result.status, '200 OK') + self.assertEqual(result.headers['X-Test-Success'], 'True') + def test_bad_user_bad_key(self): req = webob.Request.blank('/v1.0/') req.headers['X-Auth-User'] = 'unknown_user' @@ -143,6 +165,48 @@ class Test(test.TestCase): result = req.get_response(fakes.wsgi_app()) self.assertEqual(result.status, '401 Unauthorized') + def test_bad_project(self): + f = fakes.FakeAuthManager() + user1 = nova.auth.manager.User('id1', 'user1', 'user1_key', None, None) + user2 = nova.auth.manager.User('id2', 'user2', 'user2_key', None, None) + f.add_user(user1) + f.add_user(user2) + f.create_project('user1_project', user1) + f.create_project('user2_project', user2) + + req = webob.Request.blank('/v1.0/', {'HTTP_HOST': 'foo'}) + req.headers['X-Auth-User'] = 'user1' + req.headers['X-Auth-Key'] = 'user1_key' + result = req.get_response(fakes.wsgi_app()) + self.assertEqual(result.status, '204 No Content') + + token = result.headers['X-Auth-Token'] + self.stubs.Set(nova.api.openstack, 'APIRouterV10', fakes.FakeRouter) + req = webob.Request.blank('/v1.0/fake') + req.headers['X-Auth-Token'] = token + req.headers['X-Auth-Project-Id'] = 'user2_project' + result = req.get_response(fakes.wsgi_app()) + self.assertEqual(result.status, '401 Unauthorized') + + def test_not_existing_project(self): + f = fakes.FakeAuthManager() + user1 = nova.auth.manager.User('id1', 'user1', 'user1_key', None, None) + f.add_user(user1) + f.create_project('user1_project', user1) + + req = webob.Request.blank('/v1.0/', {'HTTP_HOST': 'foo'}) + req.headers['X-Auth-User'] = 'user1' + req.headers['X-Auth-Key'] = 'user1_key' + result = req.get_response(fakes.wsgi_app()) + self.assertEqual(result.status, '204 No Content') + + token = result.headers['X-Auth-Token'] + self.stubs.Set(nova.api.openstack, 'APIRouterV10', fakes.FakeRouter) + req = webob.Request.blank('/v1.0/fake') + req.headers['X-Auth-Token'] = token + req.headers['X-Auth-Project-Id'] = 'unknown_project' + result = req.get_response(fakes.wsgi_app()) + self.assertEqual(result.status, '401 Unauthorized') class TestFunctional(test.TestCase): def test_token_expiry(self): -- cgit From 03ef0d1091cc1b6d9c3049b1d7b8cfae0019631e Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Wed, 8 Jun 2011 13:52:02 +0400 Subject: added field NOVA_PROJECT_ID to template for future using --- nova/auth/novarc.template | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/auth/novarc.template b/nova/auth/novarc.template index 8170fcafe..28a3696a2 100644 --- a/nova/auth/novarc.template +++ b/nova/auth/novarc.template @@ -12,4 +12,5 @@ alias ec2-bundle-image="ec2-bundle-image --cert ${EC2_CERT} --privatekey ${EC2_P alias ec2-upload-bundle="ec2-upload-bundle -a ${EC2_ACCESS_KEY} -s ${EC2_SECRET_KEY} --url ${S3_URL} --ec2cert ${NOVA_CERT}" export NOVA_API_KEY="%(access)s" export NOVA_USERNAME="%(user)s" +export NOVA_PROJECT_ID="%(project)s" export NOVA_URL="%(os)s" -- cgit From a605905c11d8898e8cc15e830c17de3ce8c80fda Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Wed, 8 Jun 2011 09:21:38 -0400 Subject: pep8 --- nova/auth/ldapdriver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/auth/ldapdriver.py b/nova/auth/ldapdriver.py index 7bcaa34b5..e9532473d 100644 --- a/nova/auth/ldapdriver.py +++ b/nova/auth/ldapdriver.py @@ -139,7 +139,7 @@ class LdapDriver(object): self.__cache = None return False - def __local_cache(key_fmt): #pylint: disable=E0213 + def __local_cache(key_fmt): # pylint: disable=E0213 """Wrap function to cache it's result in self.__cache. Works only with functions with one fixed argument. """ -- cgit From dcb0d38aa829e1e2492defffaf6ad393b809289b Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 8 Jun 2011 08:13:23 -0700 Subject: removed straggler code --- nova/compute/api.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index e09127d5c..b0949a729 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -55,11 +55,6 @@ def generate_default_hostname(instance_id): class API(base.Base): """API for interacting with the compute manager.""" - # Should we create instances all-at-once or as single-shot requests. - # Different schedulers use different approaches. - # This is cached across all API instances. - should_create_all_at_once = None # None implies uninitialized. - def __init__(self, image_service=None, network_api=None, volume_api=None, hostname_factory=generate_default_hostname, **kwargs): -- cgit From 3da61c0b225f824025f617f0a88f72c00e31b83e Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Wed, 8 Jun 2011 21:03:52 +0400 Subject: fix exception type catched --- nova/tests/api/openstack/fakes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py index ce24bd860..8a17f0374 100644 --- a/nova/tests/api/openstack/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -331,7 +331,7 @@ class FakeAuthManager(object): if not isinstance(project, Project): try: project = self.get_project(project) - except: + except exc.NotFound: raise webob.exc.HTTPUnauthorized() return ((user.id in project.member_ids) or (user.id == project.project_manager_id)) -- cgit From f786c112ce4753dfc1838eecbfc5a20314a5e35d Mon Sep 17 00:00:00 2001 From: Yuriy Taraday Date: Wed, 8 Jun 2011 21:58:59 +0400 Subject: PEP8 fix. --- nova/tests/api/openstack/test_auth.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/tests/api/openstack/test_auth.py b/nova/tests/api/openstack/test_auth.py index 04ce78880..af3478c7d 100644 --- a/nova/tests/api/openstack/test_auth.py +++ b/nova/tests/api/openstack/test_auth.py @@ -208,6 +208,7 @@ class Test(test.TestCase): result = req.get_response(fakes.wsgi_app()) self.assertEqual(result.status, '401 Unauthorized') + class TestFunctional(test.TestCase): def test_token_expiry(self): ctx = context.get_admin_context() -- cgit