diff options
| author | Sandy Walsh <sandy.walsh@rackspace.com> | 2011-01-10 21:29:45 +0000 |
|---|---|---|
| committer | Tarmac <> | 2011-01-10 21:29:45 +0000 |
| commit | 9d5ef60e4126f3c5f742d24d4e6a617a7cff20eb (patch) | |
| tree | 8795fec45781f574dfd615ff431ecb35a8b3cc38 | |
| parent | 16c420ee156f8c7716c7e84b66af35cbccf5090c (diff) | |
| parent | 72e9f0819837da68c52f5604e83385037fdcdfb2 (diff) | |
xenapi_conn was not terminating utils/LoopingCall when an exception was occurring. This was causing the eventlet Event to have send_exception() called more than once (a no-no).
This would have affected more than just pause/unpause, but any XenApi call that raised an exception.
| -rw-r--r-- | nova/tests/xenapi/stubs.py | 24 | ||||
| -rw-r--r-- | nova/virt/xenapi_conn.py | 16 |
2 files changed, 36 insertions, 4 deletions
diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 55f751f11..292bd9ba9 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -41,9 +41,33 @@ def stubout_instance_snapshot(stubs): rv = done.wait() return rv + def fake_loop(self): + pass + stubs.Set(xenapi_conn.XenAPISession, 'wait_for_task', fake_wait_for_task) + stubs.Set(xenapi_conn.XenAPISession, '_stop_loop', fake_loop) + + from nova.virt.xenapi.fake import create_vdi + name_label = "instance-%s" % instance_id + #TODO: create fake SR record + sr_ref = "fakesr" + vdi_ref = create_vdi(name_label=name_label, read_only=False, + sr_ref=sr_ref, sharable=False) + vdi_rec = session.get_xenapi().VDI.get_record(vdi_ref) + vdi_uuid = vdi_rec['uuid'] + return vdi_uuid + + stubs.Set(vm_utils.VMHelper, 'fetch_image', fake_fetch_image) + + def fake_parse_xmlrpc_value(val): + return val + + stubs.Set(xenapi_conn, '_parse_xmlrpc_value', fake_parse_xmlrpc_value) + + def fake_wait_for_vhd_coalesce(session, instance_id, sr_ref, vdi_ref, + original_parent_uuid): from nova.virt.xenapi.fake import create_vdi name_label = "instance-%s" % instance_id #TODO: create fake SR record diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 3aaaf09ed..b8ab9245f 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -198,6 +198,7 @@ class XenAPISession(object): self.XenAPI = self.get_imported_xenapi() self._session = self._create_session(url) self._session.login_with_password(user, pw) + self.loop = None def get_imported_xenapi(self): """Stubout point. This can be replaced with a mock xenapi module.""" @@ -234,14 +235,20 @@ class XenAPISession(object): def wait_for_task(self, id, task): """Return the result of the given task. The task is polled - until it completes.""" + until it completes. Not re-entrant.""" done = event.Event() - loop = utils.LoopingCall(self._poll_task, id, task, done) - loop.start(FLAGS.xenapi_task_poll_interval, now=True) + self.loop = utils.LoopingCall(self._poll_task, id, task, done) + self.loop.start(FLAGS.xenapi_task_poll_interval, now=True) rv = done.wait() - loop.stop() + self.loop.stop() return rv + def _stop_loop(self): + """Stop polling for task to finish.""" + #NOTE(sandy-walsh) Had to break this call out to support unit tests. + if self.loop: + self.loop.stop() + def _create_session(self, url): """Stubout point. This can be replaced with a mock session.""" return self.XenAPI.Session(url) @@ -278,6 +285,7 @@ class XenAPISession(object): except self.XenAPI.Failure, exc: LOG.warn(exc) done.send_exception(*sys.exc_info()) + self._stop_loop() def _unwrap_plugin_exceptions(self, func, *args, **kwargs): """Parse exception details""" |
