From 6b67b2f391830da52dea5cd84bd564bab692f365 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 31 Aug 2011 11:54:30 -0700 Subject: zone_add fixed to support zone name --- nova/api/openstack/zones.py | 2 +- nova/db/sqlalchemy/models.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index a2bf267ed..998498e82 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -46,7 +46,7 @@ def _filter_keys(item, keys): def _exclude_keys(item, keys): - return dict((k, v) for k, v in item.iteritems() if k not in keys) + return dict((k, v) for k, v in item.iteritems() if k and (k not in keys)) def _scrub_zone(zone): diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index f8feb0b4f..dd447457b 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -847,6 +847,7 @@ class Zone(BASE, NovaBase): """Represents a child zone of this zone.""" __tablename__ = 'zones' id = Column(Integer, primary_key=True) + name = Column(String(255)) api_url = Column(String(255)) username = Column(String(255)) password = Column(String(255)) -- cgit From 75c355b42f6c24723c57228d8acfad64fd4ec7d0 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 2 Sep 2011 07:38:22 -0700 Subject: missing migration --- .../migrate_repo/versions/044_add_zone_name.py | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/044_add_zone_name.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/044_add_zone_name.py b/nova/db/sqlalchemy/migrate_repo/versions/044_add_zone_name.py new file mode 100644 index 000000000..3198e48a9 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/044_add_zone_name.py @@ -0,0 +1,35 @@ +# 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 Column, Integer, MetaData, String, Table + +meta = MetaData() + +zones = Table('zones', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +name = Column('name', String(255)) + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + + zones.create_column(name) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + zones.drop_column(name) -- cgit From 9bfdf239df25496e5ff13fbe3cf086f4cd1d4df2 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 6 Sep 2011 05:00:18 -0700 Subject: zone name not overwritten --- nova/scheduler/zone_manager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/scheduler/zone_manager.py b/nova/scheduler/zone_manager.py index 9d05ea42e..d3cf57639 100644 --- a/nova/scheduler/zone_manager.py +++ b/nova/scheduler/zone_manager.py @@ -60,7 +60,6 @@ class ZoneState(object): child zone.""" self.last_seen = utils.utcnow() self.attempt = 0 - self.name = zone_metadata.get("name", "n/a") self.capabilities = ", ".join(["%s=%s" % (k, v) for k, v in zone_metadata.iteritems() if k != 'name']) self.is_active = True @@ -91,7 +90,7 @@ class ZoneState(object): def _call_novaclient(zone): """Call novaclient. Broken out for testing purposes.""" client = novaclient.Client(zone.username, zone.password, None, - zone.api_url) + zone.api_url, service_name = zone.name) return client.zones.info()._info -- cgit From 41086f811b3e65077dd9222db98406af59fde30f Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 9 Sep 2011 12:54:22 -0700 Subject: adding auth tokens to child zone calls --- nova/scheduler/api.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 55cea5f8f..00e0eeb63 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -110,11 +110,12 @@ def _wrap_method(function, self): return _wrap -def _process(func, zone): +def _process(func, context, zone): """Worker stub for green thread pool. Give the worker - an authenticated nova client and zone info.""" + an authenticated nova client and zone info. This call + is done on behalf of the user.""" nova = novaclient.Client(zone.username, zone.password, None, - zone.api_url) + zone.api_url, token=context.auth_token) nova.authenticate() return func(nova, zone) @@ -133,13 +134,15 @@ def call_zone_method(context, method_name, errors_to_ignore=None, zones = db.zone_get_all(context) for zone in zones: try: + # Do this on behalf of the user ... nova = novaclient.Client(zone.username, zone.password, None, - zone.api_url) + zone.api_url, token = context.auth_token) nova.authenticate() except novaclient_exceptions.BadRequest, e: url = zone.api_url - LOG.warn(_("Failed request to zone; URL=%(url)s: %(e)s") - % locals()) + name = zone.name + LOG.warn(_("Authentication failed to zone " + "'%(name)s' URL=%(url)s: %(e)s") % locals()) #TODO (dabo) - add logic for failure counts per zone, # with escalation after a given number of failures. continue @@ -160,7 +163,7 @@ def call_zone_method(context, method_name, errors_to_ignore=None, return [(zone.id, res.wait()) for zone, res in results] -def child_zone_helper(zone_list, func): +def child_zone_helper(context, zone_list, func): """Fire off a command to each zone in the list. The return is [novaclient return objects] from each child zone. For example, if you are calling server.pause(), the list will @@ -168,7 +171,7 @@ def child_zone_helper(zone_list, func): per child zone called.""" green_pool = greenpool.GreenPool() return [result for result in green_pool.imap( - _wrap_method(_process, func), zone_list)] + _wrap_method(_process, context, func), zone_list)] def _issue_novaclient_command(nova, zone, collection, @@ -266,7 +269,7 @@ class reroute_compute(object): # Ask the children to provide an answer ... LOG.debug(_("Asking child zones ...")) - result = self._call_child_zones(zones, + result = self._call_child_zones(context, zones, wrap_novaclient_function(_issue_novaclient_command, collection, self.method_name, item_uuid)) # Scrub the results and raise another exception @@ -306,10 +309,10 @@ class reroute_compute(object): return wrapped_f - def _call_child_zones(self, zones, function): + def _call_child_zones(self, context, zones, function): """Ask the child zones to perform this operation. Broken out for testing.""" - return child_zone_helper(zones, function) + return child_zone_helper(context, zones, function) def get_collection_context_and_id(self, args, kwargs): """Returns a tuple of (novaclient collection name, security -- cgit From a27aa5dce2788560b29fd33b4805acf0190a27e3 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 12 Sep 2011 04:58:39 -0700 Subject: tweaks --- nova/scheduler/abstract_scheduler.py | 3 ++- nova/scheduler/zone_manager.py | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/nova/scheduler/abstract_scheduler.py b/nova/scheduler/abstract_scheduler.py index e5ea0f4e4..657ac1483 100644 --- a/nova/scheduler/abstract_scheduler.py +++ b/nova/scheduler/abstract_scheduler.py @@ -118,7 +118,8 @@ class AbstractScheduler(driver.Scheduler): ". ReservationID=%(reservation_id)s") % locals()) nova = None try: - nova = novaclient.Client(zone.username, zone.password, None, url) + nova = novaclient.Client(zone.username, zone.password, None, url, + token=context.auth_token) nova.authenticate() except novaclient_exceptions.BadRequest, e: raise exception.NotAuthorized(_("Bad credentials attempting " diff --git a/nova/scheduler/zone_manager.py b/nova/scheduler/zone_manager.py index df78411cb..16b4c7faf 100644 --- a/nova/scheduler/zone_manager.py +++ b/nova/scheduler/zone_manager.py @@ -92,7 +92,9 @@ class ZoneState(object): def _call_novaclient(zone): - """Call novaclient. Broken out for testing purposes.""" + """Call novaclient. Broken out for testing purposes. Note that + we have to use the admin credentials for this since there is no + available context.""" client = novaclient.Client(zone.username, zone.password, None, zone.api_url, region_name=zone.name) return client.zones.info()._info -- cgit From bb6374dfeb81f020d82161c28a6b31be636fbc01 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 12 Sep 2011 04:59:58 -0700 Subject: region name --- nova/scheduler/zone_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/scheduler/zone_manager.py b/nova/scheduler/zone_manager.py index d3cf57639..a15228182 100644 --- a/nova/scheduler/zone_manager.py +++ b/nova/scheduler/zone_manager.py @@ -90,7 +90,7 @@ class ZoneState(object): def _call_novaclient(zone): """Call novaclient. Broken out for testing purposes.""" client = novaclient.Client(zone.username, zone.password, None, - zone.api_url, service_name = zone.name) + zone.api_url, region_name = zone.name) return client.zones.info()._info -- cgit From 5de08f3ac11d936979a3c08c27b3b19b72d58373 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 12 Sep 2011 07:37:02 -0700 Subject: migration move --- .../migrate_repo/versions/045_add_zone_name.py | 35 ---------------------- .../migrate_repo/versions/046_add_zone_name.py | 35 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 35 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/045_add_zone_name.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_add_zone_name.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/045_add_zone_name.py b/nova/db/sqlalchemy/migrate_repo/versions/045_add_zone_name.py deleted file mode 100644 index 3198e48a9..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/045_add_zone_name.py +++ /dev/null @@ -1,35 +0,0 @@ -# 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 Column, Integer, MetaData, String, Table - -meta = MetaData() - -zones = Table('zones', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - -name = Column('name', String(255)) - - -def upgrade(migrate_engine): - meta.bind = migrate_engine - - zones.create_column(name) - - -def downgrade(migrate_engine): - meta.bind = migrate_engine - - zones.drop_column(name) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_add_zone_name.py b/nova/db/sqlalchemy/migrate_repo/versions/046_add_zone_name.py new file mode 100644 index 000000000..3198e48a9 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/046_add_zone_name.py @@ -0,0 +1,35 @@ +# 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 Column, Integer, MetaData, String, Table + +meta = MetaData() + +zones = Table('zones', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +name = Column('name', String(255)) + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + + zones.create_column(name) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + zones.drop_column(name) -- cgit From c0c046ef7d30787fe72b8de6c290a4b72cb207fb Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 12 Sep 2011 15:22:30 -0700 Subject: working on getting tests back --- nova/db/sqlalchemy/api.py | 2 +- nova/rpc/impl_kombu.py | 1 - nova/scheduler/api.py | 2 +- nova/scheduler/zone_manager.py | 4 +++- nova/tests/scheduler/test_scheduler.py | 32 ++++++++++++++++++++------------ nova/tests/test_zones.py | 22 ++++++++++++++-------- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 40e2ca167..e5a661c7f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -672,7 +672,7 @@ def floating_ip_update(context, address, values): def fixed_ip_associate(context, address, instance_id, network_id=None, reserved=False): """Keyword arguments: - reserved -- should be a boolean value(True or False), exact value will be + reserved -- should be a boolean value(True or False), exact value will be used to filter on the fixed ip address """ session = get_session() diff --git a/nova/rpc/impl_kombu.py b/nova/rpc/impl_kombu.py index b994a6a10..e7fc491ea 100644 --- a/nova/rpc/impl_kombu.py +++ b/nova/rpc/impl_kombu.py @@ -728,7 +728,6 @@ def multicall(context, topic, msg): wait_msg = MulticallWaiter(conn) conn.declare_direct_consumer(msg_id, wait_msg) conn.topic_send(topic, msg) - return wait_msg diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 3d92d902a..418ebe5e2 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -120,7 +120,7 @@ def call_zone_method(context, method_name, errors_to_ignore=None, # Do this on behalf of the user ... nova = novaclient.Client(zone.username, zone.password, None, zone.api_url, region_name=zone.name, - token = context.auth_token) + token=context.auth_token) nova.authenticate() except novaclient_exceptions.BadRequest, e: url = zone.api_url diff --git a/nova/scheduler/zone_manager.py b/nova/scheduler/zone_manager.py index 16b4c7faf..c61ff7b77 100644 --- a/nova/scheduler/zone_manager.py +++ b/nova/scheduler/zone_manager.py @@ -102,7 +102,9 @@ def _call_novaclient(zone): def _poll_zone(zone): """Eventlet worker to poll a zone.""" - logging.debug(_("Polling zone: %s @ %s") % (zone.name, zone.api_url)) + name = zone.name + url = zone.api_url + logging.debug(_("Polling zone: %(name)s @ %(url)s") % locals()) try: zone.update_metadata(_call_novaclient(zone)) except Exception, e: diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py index 890348192..c880a9005 100644 --- a/nova/tests/scheduler/test_scheduler.py +++ b/nova/tests/scheduler/test_scheduler.py @@ -53,6 +53,10 @@ FAKE_UUID_NOT_FOUND = 'ffffffff-ffff-ffff-ffff-ffffffffffff' FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' +class FakeContext(object): + auth_token = None + + class TestDriver(driver.Scheduler): """Scheduler Driver for Tests""" def schedule(context, topic, *args, **kwargs): @@ -956,11 +960,12 @@ class MultiDriverTestCase(SimpleDriverTestCase): class FakeZone(object): - def __init__(self, id, api_url, username, password): + def __init__(self, id, api_url, username, password, name='child'): self.id = id self.api_url = api_url self.username = username self.password = password + self.name = name ZONE_API_URL1 = "http://1.example.com" @@ -986,7 +991,7 @@ class FakeRerouteCompute(api.reroute_compute): super(FakeRerouteCompute, self).__init__(method_name) self.id_to_return = id_to_return - def _call_child_zones(self, zones, function): + def _call_child_zones(self, context, zones, function): return [] def get_collection_context_and_id(self, args, kwargs): @@ -1092,7 +1097,8 @@ class ZoneRedirectTest(test.TestCase): return None class FakeNovaClientWithFailure(object): - def __init__(self, username, password, method, api_url): + def __init__(self, username, password, method, api_url, + token=None, region_name=None): self.api_url = api_url def authenticate(self): @@ -1108,7 +1114,7 @@ class ZoneRedirectTest(test.TestCase): pass self.assertRaises(exception.ZoneRequestError, - do_get, None, {}, FAKE_UUID) + do_get, None, FakeContext(), FAKE_UUID) def test_one_zone_down_got_instance(self): @@ -1120,7 +1126,8 @@ class ZoneRedirectTest(test.TestCase): return FakeServer() class FakeNovaClientWithFailure(object): - def __init__(self, username, password, method, api_url): + def __init__(self, username, password, method, api_url, + token=None, region_name=None): self.api_url = api_url def authenticate(self): @@ -1136,14 +1143,14 @@ class ZoneRedirectTest(test.TestCase): pass try: - do_get(None, {}, FAKE_UUID) + do_get(None, FakeContext(), FAKE_UUID) except api.RedirectResult, e: results = e.results self.assertIn('server', results) self.assertEqual(results['server']['id'], FAKE_UUID) self.assertEqual(results['server']['test'], '1234') except Exception, e: - self.fail(_("RedirectResult should have been raised")) + self.fail(_("RedirectResult should have been raised: %s" % e)) else: self.fail(_("RedirectResult should have been raised")) @@ -1153,7 +1160,8 @@ class ZoneRedirectTest(test.TestCase): return None class FakeNovaClientNoFailure(object): - def __init__(self, username, password, method, api_url): + def __init__(self, username, password, method, api_url, + token=None, region_name=None): pass def authenticate(self): @@ -1168,7 +1176,7 @@ class ZoneRedirectTest(test.TestCase): pass self.assertRaises(exception.InstanceNotFound, - do_get, None, {}, FAKE_UUID) + do_get, None, FakeContext(), FAKE_UUID) class FakeServerCollection(object): @@ -1250,7 +1258,7 @@ class CallZoneMethodTest(test.TestCase): super(CallZoneMethodTest, self).tearDown() def test_call_zone_method(self): - context = {} + context = FakeContext() method = 'do_something' results = api.call_zone_method(context, method) self.assertEqual(len(results), 2) @@ -1258,12 +1266,12 @@ class CallZoneMethodTest(test.TestCase): self.assertIn((2, 42), results) def test_call_zone_method_not_present(self): - context = {} + context = FakeContext() method = 'not_present' self.assertRaises(AttributeError, api.call_zone_method, context, method) def test_call_zone_method_generates_exception(self): - context = {} + context = FakeContext() method = 'raises_exception' self.assertRaises(Exception, api.call_zone_method, context, method) diff --git a/nova/tests/test_zones.py b/nova/tests/test_zones.py index 9efa23015..3ffc9371d 100644 --- a/nova/tests/test_zones.py +++ b/nova/tests/test_zones.py @@ -63,7 +63,7 @@ class ZoneManagerTestCase(test.TestCase): self.mox.StubOutWithMock(db, 'zone_get_all') db.zone_get_all(mox.IgnoreArg()).AndReturn([ FakeZone(id=1, api_url='http://foo.com', username='user1', - password='pass1'), + password='pass1', name='child'), ]) self.assertEquals(len(zm.zone_states), 0) @@ -107,13 +107,15 @@ class ZoneManagerTestCase(test.TestCase): zm = zone_manager.ZoneManager() zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com', - username='user1', password='pass1')) + username='user1', password='pass1', name='child', + weight_offset=0.0, weight_scale=1.0)) zm.zone_states[1] = zone_state self.mox.StubOutWithMock(db, 'zone_get_all') db.zone_get_all(mox.IgnoreArg()).AndReturn([ FakeZone(id=1, api_url='http://foo.com', username='user2', - password='pass2'), + password='pass2', name='child', + weight_offset=0.0, weight_scale=1.0), ]) self.assertEquals(len(zm.zone_states), 1) @@ -129,7 +131,8 @@ class ZoneManagerTestCase(test.TestCase): zm = zone_manager.ZoneManager() zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com', - username='user1', password='pass1')) + username='user1', password='pass1', name='child', + weight_offset=0.0, weight_scale=1.0)) zm.zone_states[1] = zone_state self.mox.StubOutWithMock(db, 'zone_get_all') @@ -147,14 +150,15 @@ class ZoneManagerTestCase(test.TestCase): zm = zone_manager.ZoneManager() zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com', - username='user1', password='pass1')) + username='user1', password='pass1', name='child', + weight_offset=0.0, weight_scale=1.0)) zm.zone_states[1] = zone_state self.mox.StubOutWithMock(db, 'zone_get_all') db.zone_get_all(mox.IgnoreArg()).AndReturn([ FakeZone(id=2, api_url='http://foo.com', username='user2', - password='pass2'), + password='pass2', name='child'), ]) self.assertEquals(len(zm.zone_states), 1) @@ -173,7 +177,8 @@ class ZoneManagerTestCase(test.TestCase): zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=2, api_url='http://foo.com', username='user2', - password='pass2')) + password='pass2', name='child', + weight_offset=0.0, weight_scale=1.0)) zone_state.attempt = 1 self.mox.ReplayAll() @@ -188,7 +193,8 @@ class ZoneManagerTestCase(test.TestCase): zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=2, api_url='http://foo.com', username='user2', - password='pass2')) + password='pass2', name='child', + weight_offset=0.0, weight_scale=1.0)) zone_state.attempt = FLAGS.zone_failures_to_offline - 1 self.mox.ReplayAll() -- cgit From 9ccefcaa44062f5aa2e562dd126e22d06a06c392 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 12 Sep 2011 15:36:18 -0700 Subject: zone manager tests working --- nova/tests/test_zones.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/nova/tests/test_zones.py b/nova/tests/test_zones.py index 3ffc9371d..9b5b9b24a 100644 --- a/nova/tests/test_zones.py +++ b/nova/tests/test_zones.py @@ -63,7 +63,8 @@ class ZoneManagerTestCase(test.TestCase): self.mox.StubOutWithMock(db, 'zone_get_all') db.zone_get_all(mox.IgnoreArg()).AndReturn([ FakeZone(id=1, api_url='http://foo.com', username='user1', - password='pass1', name='child'), + password='pass1', name='child', weight_offset=0.0, + weight_scale=1.0), ]) self.assertEquals(len(zm.zone_states), 0) @@ -151,14 +152,15 @@ class ZoneManagerTestCase(test.TestCase): zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com', username='user1', password='pass1', name='child', - weight_offset=0.0, weight_scale=1.0)) + weight_offset=2.0, weight_scale=3.0)) zm.zone_states[1] = zone_state self.mox.StubOutWithMock(db, 'zone_get_all') db.zone_get_all(mox.IgnoreArg()).AndReturn([ FakeZone(id=2, api_url='http://foo.com', username='user2', - password='pass2', name='child'), + password='pass2', name='child', weight_offset=2.0, + weight_scale=3.0), ]) self.assertEquals(len(zm.zone_states), 1) @@ -172,7 +174,7 @@ class ZoneManagerTestCase(test.TestCase): def test_poll_zone(self): self.mox.StubOutWithMock(zone_manager, '_call_novaclient') zone_manager._call_novaclient(mox.IgnoreArg()).AndReturn( - dict(name='zohan', capabilities='hairdresser')) + dict(name='child', capabilities='hairdresser')) zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=2, @@ -185,7 +187,7 @@ class ZoneManagerTestCase(test.TestCase): zone_manager._poll_zone(zone_state) self.mox.VerifyAll() self.assertEquals(zone_state.attempt, 0) - self.assertEquals(zone_state.name, 'zohan') + self.assertEquals(zone_state.name, 'child') def test_poll_zone_fails(self): self.stubs.Set(zone_manager, "_call_novaclient", exploding_novaclient) @@ -202,7 +204,6 @@ class ZoneManagerTestCase(test.TestCase): self.mox.VerifyAll() self.assertEquals(zone_state.attempt, 3) self.assertFalse(zone_state.is_active) - self.assertEquals(zone_state.name, None) def test_host_service_caps_stale_no_stale_service(self): zm = zone_manager.ZoneManager() -- cgit From fba1d427a941f1eb6971611cf1b016274ed19baa Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 14 Sep 2011 19:55:51 -0700 Subject: tests are back --- .../migrate_repo/versions/046_add_zone_name.py | 35 ------------------- .../migrate_repo/versions/047_add_zone_name.py | 35 +++++++++++++++++++ nova/scheduler/api.py | 28 ++++++++++++---- nova/tests/scheduler/test_scheduler.py | 39 +++++++++++++--------- 4 files changed, 80 insertions(+), 57 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_add_zone_name.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/047_add_zone_name.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_add_zone_name.py b/nova/db/sqlalchemy/migrate_repo/versions/046_add_zone_name.py deleted file mode 100644 index 3198e48a9..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/046_add_zone_name.py +++ /dev/null @@ -1,35 +0,0 @@ -# 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 Column, Integer, MetaData, String, Table - -meta = MetaData() - -zones = Table('zones', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - -name = Column('name', String(255)) - - -def upgrade(migrate_engine): - meta.bind = migrate_engine - - zones.create_column(name) - - -def downgrade(migrate_engine): - meta.bind = migrate_engine - - zones.drop_column(name) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_add_zone_name.py b/nova/db/sqlalchemy/migrate_repo/versions/047_add_zone_name.py new file mode 100644 index 000000000..3198e48a9 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_add_zone_name.py @@ -0,0 +1,35 @@ +# 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 Column, Integer, MetaData, String, Table + +meta = MetaData() + +zones = Table('zones', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +name = Column('name', String(255)) + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + + zones.create_column(name) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + zones.drop_column(name) diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 418ebe5e2..df07026d7 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -178,7 +178,13 @@ def child_zone_helper(context, zone_list, func): # there if no other zones had a response. return exception.ZoneRequestError() else: - return func(nova, zone) + try: + answer = func(nova, zone) + LOG.debug("***** GOT %s FROM CHILD" % answer) + return answer + except Exception, e: + LOG.debug("***** GOT EXCEPTION %s FROM CHILD" % e) + return e green_pool = greenpool.GreenPool() return [result for result in green_pool.imap( @@ -215,11 +221,11 @@ def _issue_novaclient_command(nova, zone, collection, item = args.pop(0) try: result = manager.get(item) - except novaclient_exceptions.NotFound: + except novaclient_exceptions.NotFound, e: url = zone.api_url LOG.debug(_("%(collection)s '%(item)s' not found on '%(url)s'" % locals())) - return None + raise e if method_name.lower() != 'get': # if we're doing something other than 'get', call it passing args. @@ -360,6 +366,7 @@ class reroute_compute(object): reduced_response = [] found_exception = None for zone_response in zone_responses: + LOG.debug("****** ZONE RESPONSE %s" % zone_response) if not zone_response: continue if isinstance(zone_response, BaseException): @@ -373,17 +380,26 @@ class reroute_compute(object): del server[k] reduced_response.append(dict(server=server)) + + # Boil the responses down to a single response. + # + # If we get a happy response use that, ignore all the + # complaint repsonses ... if reduced_response: return reduced_response[0] # first for now. elif found_exception: - raise found_exception - raise exception.InstanceNotFound(instance_id=self.item_uuid) - + LOG.debug("****** FOUND EXCEPTION %s" % found_exception) + return found_exception + LOG.debug("****** COULD NOT FIND INSTANCE") + return exception.InstanceNotFound(instance_id=self.item_uuid) def redirect_handler(f): def new_f(*args, **kwargs): try: return f(*args, **kwargs) except RedirectResult, e: + LOG.debug("****** REDIRECT HANDLER %s" % e.results) + if isinstance(e.results, BaseException): + raise e.results return e.results return new_f diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py index c880a9005..022d93bcf 100644 --- a/nova/tests/scheduler/test_scheduler.py +++ b/nova/tests/scheduler/test_scheduler.py @@ -1076,8 +1076,7 @@ class ZoneRedirectTest(test.TestCase): def test_unmarshal_single_server(self): decorator = api.reroute_compute("foo") decorator.item_uuid = 'fake_uuid' - self.assertRaises(exception.InstanceNotFound, - decorator.unmarshall_result, []) + self.assertTrue(isinstance(decorator.unmarshall_result([]), exception.InstanceNotFound)) self.assertEquals(decorator.unmarshall_result( [FakeResource(dict(a=1, b=2)), ]), dict(server=dict(a=1, b=2))) @@ -1113,8 +1112,11 @@ class ZoneRedirectTest(test.TestCase): def do_get(self, context, uuid): pass - self.assertRaises(exception.ZoneRequestError, - do_get, None, FakeContext(), FAKE_UUID) + try: + do_get(None, FakeContext(), FAKE_UUID) + self.fail("Should have got redirect exception.") + except api.RedirectResult, e: + self.assertTrue(isinstance(e.results, exception.ZoneRequestError)) def test_one_zone_down_got_instance(self): @@ -1175,8 +1177,11 @@ class ZoneRedirectTest(test.TestCase): def do_get(self, context, uuid): pass - self.assertRaises(exception.InstanceNotFound, - do_get, None, FakeContext(), FAKE_UUID) + try: + do_get(None, FakeContext(), FAKE_UUID) + self.fail("Expected redirect exception") + except api.RedirectResult, e: + self.assertTrue(isinstance(e.results, exception.InstanceNotFound)) class FakeServerCollection(object): @@ -1217,17 +1222,19 @@ class DynamicNovaClientTest(test.TestCase): def test_issue_novaclient_command_not_found(self): zone = FakeZone(1, 'http://example.com', 'bob', 'xxx') - self.assertEquals(api._issue_novaclient_command( - FakeNovaClient(FakeEmptyServerCollection()), - zone, "servers", "get", 100), None) - - self.assertEquals(api._issue_novaclient_command( - FakeNovaClient(FakeEmptyServerCollection()), - zone, "servers", "find", name="test"), None) + try: + api._issue_novaclient_command(FakeNovaClient( + FakeEmptyServerCollection()), zone, "servers", "get", 100) + self.fail("Expected NotFound exception") + except novaclient_exceptions.NotFound, e: + pass - self.assertEquals(api._issue_novaclient_command( - FakeNovaClient(FakeEmptyServerCollection()), - zone, "servers", "any", "name"), None) + try: + api._issue_novaclient_command(FakeNovaClient( + FakeEmptyServerCollection()), zone, "servers", "any", "name") + self.fail("Expected NotFound exception") + except novaclient_exceptions.NotFound, e: + pass class FakeZonesProxy(object): -- cgit From 65e3f8201d88f231dfbd7934f5b920ae3b1d8e31 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 15 Sep 2011 04:54:01 -0700 Subject: pep8 --- nova/scheduler/api.py | 1 + nova/tests/scheduler/test_scheduler.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index df07026d7..d8315f007 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -393,6 +393,7 @@ class reroute_compute(object): LOG.debug("****** COULD NOT FIND INSTANCE") return exception.InstanceNotFound(instance_id=self.item_uuid) + def redirect_handler(f): def new_f(*args, **kwargs): try: diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py index 022d93bcf..3acb91f72 100644 --- a/nova/tests/scheduler/test_scheduler.py +++ b/nova/tests/scheduler/test_scheduler.py @@ -1076,7 +1076,8 @@ class ZoneRedirectTest(test.TestCase): def test_unmarshal_single_server(self): decorator = api.reroute_compute("foo") decorator.item_uuid = 'fake_uuid' - self.assertTrue(isinstance(decorator.unmarshall_result([]), exception.InstanceNotFound)) + self.assertTrue(isinstance(decorator.unmarshall_result([]), + exception.InstanceNotFound)) self.assertEquals(decorator.unmarshall_result( [FakeResource(dict(a=1, b=2)), ]), dict(server=dict(a=1, b=2))) -- cgit From 97f28ec95ce1c6a1d3cb9c896b4ac2b4b51589e2 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 15 Sep 2011 13:00:21 -0700 Subject: exceptions properly passed around now --- nova/api/openstack/servers.py | 44 +++++++++++++++++++++++++++++++++++++++++++ nova/scheduler/api.py | 14 +++++++++++--- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 5affd1f33..6dc168203 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -17,6 +17,7 @@ import base64 import os import traceback +from novaclient import exceptions as novaclient_exceptions from lxml import etree from webob import exc import webob @@ -45,6 +46,29 @@ LOG = logging.getLogger('nova.api.openstack.servers') FLAGS = flags.FLAGS +class ConvertedException(exc.WSGIHTTPException): + def __init__(self, code, title, explaination): + self.code = code + self.title = title + self.explaination = explaination + super(ConvertedException, self).__init__() + + +def novaclient_exception_converter(f): + """Convert novaclient ClientException HTTP codes to webob exceptions. + """ + def new_f(*args, **kwargs): + try: + LOG.debug("**** NOVACLIENT EXCEPTION CONVERTER >>>>") + ret = f(*args, **kwargs) + LOG.debug("**** NOVACLIENT EXCEPTION CONVERTER <<<<") + return ret + except novaclient_exceptions.ClientException, e: + LOG.debug("**** NOVACLIENT EXCEPTION CONVERTER- RERAISING") + raise ConvertedException(e.code, e.message, e.details) + return new_f + + class Controller(object): """ The Server API base controller class for the OpenStack API """ @@ -135,6 +159,7 @@ class Controller(object): return dict(servers=servers) + @novaclient_exception_converter @scheduler_api.redirect_handler def show(self, req, id): """ Returns server details by server id """ @@ -169,6 +194,7 @@ class Controller(object): server['server']['adminPass'] = extra_values['password'] return server + @novaclient_exception_converter @scheduler_api.redirect_handler def update(self, req, id, body): """Update server then pass on to version-specific controller""" @@ -204,6 +230,7 @@ class Controller(object): def _update(self, context, req, id, inst_dict): return exc.HTTPNotImplemented() + @novaclient_exception_converter @scheduler_api.redirect_handler def action(self, req, id, body): """Multi-purpose method used to take actions on a server""" @@ -342,6 +369,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def lock(self, req, id): """ @@ -358,6 +386,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def unlock(self, req, id): """ @@ -374,6 +403,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def get_lock(self, req, id): """ @@ -389,6 +419,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def reset_network(self, req, id): """ @@ -404,6 +435,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def inject_network_info(self, req, id): """ @@ -419,6 +451,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def pause(self, req, id): """ Permit Admins to Pause the server. """ @@ -431,6 +464,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def unpause(self, req, id): """ Permit Admins to Unpause the server. """ @@ -443,6 +477,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def suspend(self, req, id): """permit admins to suspend the server""" @@ -455,6 +490,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def resume(self, req, id): """permit admins to resume the server from suspend""" @@ -467,6 +503,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def migrate(self, req, id): try: @@ -476,6 +513,7 @@ class Controller(object): raise exc.HTTPBadRequest() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def rescue(self, req, id): """Permit users to rescue the server.""" @@ -488,6 +526,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def unrescue(self, req, id): """Permit users to unrescue the server.""" @@ -500,6 +539,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def get_ajax_console(self, req, id): """Returns a url to an instance's ajaxterm console.""" @@ -510,6 +550,7 @@ class Controller(object): raise exc.HTTPNotFound() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def get_vnc_console(self, req, id): """Returns a url to an instance's ajaxterm console.""" @@ -520,6 +561,7 @@ class Controller(object): raise exc.HTTPNotFound() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def diagnostics(self, req, id): """Permit Admins to retrieve server diagnostics.""" @@ -562,6 +604,7 @@ class Controller(object): class ControllerV10(Controller): """v1.0 OpenStack API controller""" + @novaclient_exception_converter @scheduler_api.redirect_handler def delete(self, req, id): """ Destroys a server """ @@ -640,6 +683,7 @@ class ControllerV10(Controller): class ControllerV11(Controller): """v1.1 OpenStack API controller""" + @novaclient_exception_converter @scheduler_api.redirect_handler def delete(self, req, id): """ Destroys a server """ diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index d8315f007..2bf60cc70 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -17,6 +17,8 @@ Handles all requests relating to schedulers. """ +import webob + from novaclient import v1_1 as novaclient from novaclient import exceptions as novaclient_exceptions @@ -321,6 +323,7 @@ class reroute_compute(object): self.replace_uuid_with_id(args, kwargs, item_id) if attempt_reroute: + LOG.debug("***** REROUTING TO ASK CHILDREN") return self._route_to_child_zones(context, collection, item_uuid) else: @@ -391,16 +394,21 @@ class reroute_compute(object): LOG.debug("****** FOUND EXCEPTION %s" % found_exception) return found_exception LOG.debug("****** COULD NOT FIND INSTANCE") - return exception.InstanceNotFound(instance_id=self.item_uuid) + #return exception.InstanceNotFound(instance_id=self.item_uuid) + return None def redirect_handler(f): def new_f(*args, **kwargs): try: - return f(*args, **kwargs) + LOG.debug("****** REDIRECT HANDLER >>>>") + ret = f(*args, **kwargs) + LOG.debug("****** REDIRECT HANDLER <<<<") + return ret except RedirectResult, e: - LOG.debug("****** REDIRECT HANDLER %s" % e.results) + LOG.debug("****** REDIRECT HANDLER %s" % e.results.__class__) if isinstance(e.results, BaseException): + LOG.debug("****** REDIRECT HANDLER - RAISING %s" % e.results.__class__) raise e.results return e.results return new_f -- cgit From 2fd55ddfdf065a8792fdd0e3f3e97b5e56e4a4a3 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 15 Sep 2011 13:42:30 -0700 Subject: tests working again --- nova/api/openstack/servers.py | 1 + nova/tests/scheduler/test_scheduler.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 6dc168203..80f367199 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -56,6 +56,7 @@ class ConvertedException(exc.WSGIHTTPException): def novaclient_exception_converter(f): """Convert novaclient ClientException HTTP codes to webob exceptions. + Has to be the outer-most decorator. """ def new_f(*args, **kwargs): try: diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py index 3acb91f72..0b51792a0 100644 --- a/nova/tests/scheduler/test_scheduler.py +++ b/nova/tests/scheduler/test_scheduler.py @@ -1076,8 +1076,8 @@ class ZoneRedirectTest(test.TestCase): def test_unmarshal_single_server(self): decorator = api.reroute_compute("foo") decorator.item_uuid = 'fake_uuid' - self.assertTrue(isinstance(decorator.unmarshall_result([]), - exception.InstanceNotFound)) + result = decorator.unmarshall_result([]) + self.assertEquals(decorator.unmarshall_result([]), None) self.assertEquals(decorator.unmarshall_result( [FakeResource(dict(a=1, b=2)), ]), dict(server=dict(a=1, b=2))) @@ -1182,7 +1182,7 @@ class ZoneRedirectTest(test.TestCase): do_get(None, FakeContext(), FAKE_UUID) self.fail("Expected redirect exception") except api.RedirectResult, e: - self.assertTrue(isinstance(e.results, exception.InstanceNotFound)) + self.assertEquals(e.results, None) class FakeServerCollection(object): -- cgit From 41c642ce4abef72c79cb6443ce575d8398b1f452 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 15 Sep 2011 18:10:04 -0700 Subject: remove debugging --- nova/api/openstack/servers.py | 3 --- nova/scheduler/api.py | 16 +++++----------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 80f367199..002535e34 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -60,12 +60,9 @@ def novaclient_exception_converter(f): """ def new_f(*args, **kwargs): try: - LOG.debug("**** NOVACLIENT EXCEPTION CONVERTER >>>>") ret = f(*args, **kwargs) - LOG.debug("**** NOVACLIENT EXCEPTION CONVERTER <<<<") return ret except novaclient_exceptions.ClientException, e: - LOG.debug("**** NOVACLIENT EXCEPTION CONVERTER- RERAISING") raise ConvertedException(e.code, e.message, e.details) return new_f diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 2bf60cc70..7d711aa42 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -182,10 +182,8 @@ def child_zone_helper(context, zone_list, func): else: try: answer = func(nova, zone) - LOG.debug("***** GOT %s FROM CHILD" % answer) return answer except Exception, e: - LOG.debug("***** GOT EXCEPTION %s FROM CHILD" % e) return e green_pool = greenpool.GreenPool() @@ -323,7 +321,6 @@ class reroute_compute(object): self.replace_uuid_with_id(args, kwargs, item_id) if attempt_reroute: - LOG.debug("***** REROUTING TO ASK CHILDREN") return self._route_to_child_zones(context, collection, item_uuid) else: @@ -369,7 +366,6 @@ class reroute_compute(object): reduced_response = [] found_exception = None for zone_response in zone_responses: - LOG.debug("****** ZONE RESPONSE %s" % zone_response) if not zone_response: continue if isinstance(zone_response, BaseException): @@ -391,24 +387,22 @@ class reroute_compute(object): if reduced_response: return reduced_response[0] # first for now. elif found_exception: - LOG.debug("****** FOUND EXCEPTION %s" % found_exception) return found_exception - LOG.debug("****** COULD NOT FIND INSTANCE") - #return exception.InstanceNotFound(instance_id=self.item_uuid) + + # Some operations, like delete(), don't send back any results + # on success. We'll do the same. return None def redirect_handler(f): def new_f(*args, **kwargs): try: - LOG.debug("****** REDIRECT HANDLER >>>>") ret = f(*args, **kwargs) - LOG.debug("****** REDIRECT HANDLER <<<<") return ret except RedirectResult, e: - LOG.debug("****** REDIRECT HANDLER %s" % e.results.__class__) + # Remember: exceptions are returned, not thrown, in the decorator. + # At this point it's safe to throw it. if isinstance(e.results, BaseException): - LOG.debug("****** REDIRECT HANDLER - RAISING %s" % e.results.__class__) raise e.results return e.results return new_f -- cgit From 1b18dca93ddd232d14599c39201b459160490fb4 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 15 Sep 2011 18:20:35 -0700 Subject: cleaned up --- tools/pip-requires | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pip-requires b/tools/pip-requires index a4af326dc..f47d6130c 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -11,7 +11,7 @@ eventlet kombu lockfile==0.8 lxml==2.3 -python-novaclient==2.6.0 +python-novaclient==2.6.5 python-daemon==1.5.5 python-gflags==1.3 redis==2.0.0 -- cgit From c77c080d0aa0e5a93caa1e6c92ff6aca9464ee1f Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 16 Sep 2011 14:54:21 -0300 Subject: removed unused import --- nova/scheduler/api.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 7d711aa42..820643054 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -17,8 +17,6 @@ Handles all requests relating to schedulers. """ -import webob - from novaclient import v1_1 as novaclient from novaclient import exceptions as novaclient_exceptions -- cgit From ed4d1733c5308d6591587471cacf6b09bbb99f10 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 21 Sep 2011 05:03:37 -0700 Subject: clean up based on cerberus review --- nova/api/openstack/servers.py | 2 +- nova/scheduler/api.py | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 002535e34..b2d192c99 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -50,7 +50,7 @@ class ConvertedException(exc.WSGIHTTPException): def __init__(self, code, title, explaination): self.code = code self.title = title - self.explaination = explaination + self.explanation = explanation super(ConvertedException, self).__init__() diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 7d711aa42..8a96e7830 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -18,6 +18,7 @@ Handles all requests relating to schedulers. """ import webob +import functools from novaclient import v1_1 as novaclient from novaclient import exceptions as novaclient_exceptions @@ -156,12 +157,6 @@ def child_zone_helper(context, zone_list, func): be whatever the response from server.pause() is. One entry per child zone called.""" - def _wrap_method(function, arg1, arg2): - """Wrap method to supply an argument.""" - def _wrap(*args, **kwargs): - return function(arg1, arg2, *args, **kwargs) - return _wrap - def _process(func, context, zone): """Worker stub for green thread pool. Give the worker an authenticated nova client and zone info.""" @@ -188,7 +183,7 @@ def child_zone_helper(context, zone_list, func): green_pool = greenpool.GreenPool() return [result for result in green_pool.imap( - _wrap_method(_process, func, context), zone_list)] + functools.partial(_process, func, context), zone_list)] def _issue_novaclient_command(nova, zone, collection, @@ -397,8 +392,7 @@ class reroute_compute(object): def redirect_handler(f): def new_f(*args, **kwargs): try: - ret = f(*args, **kwargs) - return ret + return f(*args, **kwargs) except RedirectResult, e: # Remember: exceptions are returned, not thrown, in the decorator. # At this point it's safe to throw it. -- cgit From 9dc59398a2278034be1c391f460406365a808bb7 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 21 Sep 2011 05:07:17 -0700 Subject: migration conflict fixed --- .../migrate_repo/versions/047_add_zone_name.py | 35 ---------------------- .../migrate_repo/versions/048_add_zone_name.py | 35 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 35 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/047_add_zone_name.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/048_add_zone_name.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_add_zone_name.py b/nova/db/sqlalchemy/migrate_repo/versions/047_add_zone_name.py deleted file mode 100644 index 3198e48a9..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/047_add_zone_name.py +++ /dev/null @@ -1,35 +0,0 @@ -# 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 Column, Integer, MetaData, String, Table - -meta = MetaData() - -zones = Table('zones', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - -name = Column('name', String(255)) - - -def upgrade(migrate_engine): - meta.bind = migrate_engine - - zones.create_column(name) - - -def downgrade(migrate_engine): - meta.bind = migrate_engine - - zones.drop_column(name) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/048_add_zone_name.py b/nova/db/sqlalchemy/migrate_repo/versions/048_add_zone_name.py new file mode 100644 index 000000000..3198e48a9 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/048_add_zone_name.py @@ -0,0 +1,35 @@ +# 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 Column, Integer, MetaData, String, Table + +meta = MetaData() + +zones = Table('zones', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +name = Column('name', String(255)) + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + + zones.create_column(name) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + zones.drop_column(name) -- cgit