diff --git a/doc/source/contributor/guides/remote-debugger.rst b/doc/source/contributor/guides/remote-debugger.rst new file mode 100644 index 0000000000..8de56b8623 --- /dev/null +++ b/doc/source/contributor/guides/remote-debugger.rst @@ -0,0 +1,73 @@ +.. + 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. + +====================== +Debugging Octavia code +====================== + +This document describes how to setup and debug Octavia code using your favorite +IDE (e.g. PyCharm). + +Prerequisites +============= + +* Octavia installed. +* IDE installed and Octavia added as project. + +Setup +===== + +Ensure your OpenStack and IDE environments have the PyDev library installed. If +you're using PyCharm, you can find it in +*/path/to/pycharm/debug-eggs/pycharm-debug.egg* (Python 2) and +*/path/to/pycharm/debug-eggs/pycharm-debug-py3k.egg* (Python 3). Copy that file +into your OpenStack host and install the library in your Python path: + +:: + + $ sudo easy_install pycharm-debug.egg + + +Create a remote debugging configuration in your IDE. In PyCharm, go to *Run -> +Edit Configurations -> Python Remote Debug*. The local host name refers to the +local machine you're running your IDE from and it must be one reachable by your +OpenStack environment. The port can be any available port (e.g. 5678). If the +code on the OpenStack and PyCharm hosts is on different paths (likely), define +a path mapping in the remote debug configuration. + +Invoke the debug configuration (*Run -> Debug... -> (config name)*). PyCharm +will begin listening on the specified host and port. + +Export *PYDEV_DEBUG_HOST* and *PYDEV_DEBUG_PORT* (host and port of the system +running the IDE, respectively), and start the Octavia service you want to +debug. It is recommended to run only one uWSGI process/controller worker. +For example, to debug the Octavia Worker service: + +:: + + $ export PYDEV_DEBUG_HOST=192.168.121.1 + $ export PYDEV_DEBUG_PORT=5678 + $ /usr/bin/octavia-worker --config-file /etc/octavia/octavia.conf + +Another example is the Octavia API service: + +:: + + $ export PYDEV_DEBUG_HOST=192.168.121.1 + $ export PYDEV_DEBUG_PORT=5678 + $ /usr/bin/uwsgi --ini /etc/octavia/octavia-uwsgi.ini -p 1 + +The service will connect to your IDE, at which point remote debugging is +active. Resume the program on the debugger to continue with the initialization +of the service. At this point, the service should be operational and you can +start debugging. diff --git a/octavia/common/config.py b/octavia/common/config.py index 23d08d4c63..7ad0e0130f 100644 --- a/octavia/common/config.py +++ b/octavia/common/config.py @@ -17,6 +17,7 @@ Routines for configuring Octavia """ +import os import sys from keystoneauth1 import loading as ks_loading @@ -634,6 +635,7 @@ def init(args, **kwargs): version='%%prog %s' % version.version_info.release_string(), **kwargs) handle_deprecation_compatibility() + setup_remote_pydev_debug() def setup_logging(conf): @@ -663,3 +665,34 @@ def handle_deprecation_compatibility(): cfg.CONF.set_default('stats_update_threads', cfg.CONF.health_manager.status_update_threads, group='health_manager') + + +def setup_remote_pydev_debug(): + """Required setup for remote debugging.""" + + pydev_debug_host = os.environ.get('PYDEV_DEBUG_HOST') + pydev_debug_port = os.environ.get('PYDEV_DEBUG_PORT') + + if not pydev_debug_host or not pydev_debug_port: + return + + try: + try: + from pydev import pydevd + except ImportError: + import pydevd + + LOG.warning("Connecting to remote debugger. Once connected, resume " + "the program on the debugger to continue with the " + "initialization of the service.") + pydevd.settrace(pydev_debug_host, + port=int(pydev_debug_port), + stdoutToServer=True, + stderrToServer=True) + except Exception: + LOG.exception('Unable to join debugger, please make sure that the ' + 'debugger processes is listening on debug-host ' + '\'%(debug-host)s\' debug-port \'%(debug-port)s\'.', + {'debug-host': pydev_debug_host, + 'debug-port': pydev_debug_port}) + raise diff --git a/releasenotes/notes/support-remote-debugging-fcb52df4a59c1467.yaml b/releasenotes/notes/support-remote-debugging-fcb52df4a59c1467.yaml new file mode 100644 index 0000000000..c19d6d06bd --- /dev/null +++ b/releasenotes/notes/support-remote-debugging-fcb52df4a59c1467.yaml @@ -0,0 +1,4 @@ +--- +features: + - Support remote debugging with PyDev. Please refer to the Contributor + documentation section to find more details.