Add support to the Python Visual Studio Debugger
Change-Id: I1051656d61709c2f418e2fabdee2d16c889b7efd
This commit is contained in:
parent
ab413f971e
commit
31741aa474
@ -16,7 +16,7 @@ Debugging Octavia code
|
|||||||
======================
|
======================
|
||||||
|
|
||||||
This document describes how to setup and debug Octavia code using your favorite
|
This document describes how to setup and debug Octavia code using your favorite
|
||||||
IDE (e.g. PyCharm).
|
IDE (e.g. PyCharm, Visual Studio Code).
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
=============
|
=============
|
||||||
@ -27,8 +27,10 @@ Prerequisites
|
|||||||
Setup
|
Setup
|
||||||
=====
|
=====
|
||||||
|
|
||||||
Ensure your OpenStack and IDE environments have the PyDev library installed. If
|
Ensure your OpenStack and IDE environments have the PyDev or ptvsd library
|
||||||
you're using PyCharm, you can find it in
|
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.egg* (Python 2) and
|
||||||
*/path/to/pycharm/debug-eggs/pycharm-debug-py3k.egg* (Python 3). Copy that file
|
*/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:
|
into your OpenStack host and install the library in your Python path:
|
||||||
@ -37,6 +39,11 @@ into your OpenStack host and install the library in your Python path:
|
|||||||
|
|
||||||
$ sudo easy_install pycharm-debug.egg
|
$ sudo easy_install pycharm-debug.egg
|
||||||
|
|
||||||
|
If using Visual Studio Code, simply install ptvsd in both environments:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ pip install ptvsd
|
||||||
|
|
||||||
Create a remote debugging configuration in your IDE. In PyCharm, go to *Run ->
|
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
|
Edit Configurations -> Python Remote Debug*. The local host name refers to the
|
||||||
@ -48,23 +55,25 @@ a path mapping in the remote debug configuration.
|
|||||||
Invoke the debug configuration (*Run -> Debug... -> (config name)*). PyCharm
|
Invoke the debug configuration (*Run -> Debug... -> (config name)*). PyCharm
|
||||||
will begin listening on the specified host and port.
|
will begin listening on the specified host and port.
|
||||||
|
|
||||||
Export *PYDEV_DEBUG_HOST* and *PYDEV_DEBUG_PORT* (host and port of the system
|
Export *DEBUGGER_TYPE*, *DEBUGGER_HOST* and *DEBUGGER_PORT* (host and port of
|
||||||
running the IDE, respectively), and start the Octavia service you want to
|
the system running the IDE, respectively), and start the Octavia service you
|
||||||
debug. It is recommended to run only one uWSGI process/controller worker.
|
want to debug. It is recommended to run only one uWSGI process/controller
|
||||||
For example, to debug the Octavia Worker service:
|
worker. For example, to debug the Octavia Worker service:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$ export PYDEV_DEBUG_HOST=192.168.121.1
|
$ export DEBUGGER_TYPE=pydev
|
||||||
$ export PYDEV_DEBUG_PORT=5678
|
$ export DEBUGGER_HOST=192.168.121.1
|
||||||
|
$ export DEBUGGER_PORT=5678
|
||||||
$ /usr/bin/octavia-worker --config-file /etc/octavia/octavia.conf
|
$ /usr/bin/octavia-worker --config-file /etc/octavia/octavia.conf
|
||||||
|
|
||||||
Another example is the Octavia API service:
|
Another example is debugging the Octavia API service with the ptvsd debugger:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$ export PYDEV_DEBUG_HOST=192.168.121.1
|
$ export DEBUGGER_TYPE=ptvsd
|
||||||
$ export PYDEV_DEBUG_PORT=5678
|
$ export DEBUGGER_HOST=192.168.121.1
|
||||||
|
$ export DEBUGGER_PORT=5678
|
||||||
$ /usr/bin/uwsgi --ini /etc/octavia/octavia-uwsgi.ini -p 1
|
$ /usr/bin/uwsgi --ini /etc/octavia/octavia-uwsgi.ini -p 1
|
||||||
|
|
||||||
The service will connect to your IDE, at which point remote debugging is
|
The service will connect to your IDE, at which point remote debugging is
|
||||||
|
@ -676,7 +676,7 @@ def init(args, **kwargs):
|
|||||||
version='%%prog %s' % version.version_info.release_string(),
|
version='%%prog %s' % version.version_info.release_string(),
|
||||||
**kwargs)
|
**kwargs)
|
||||||
handle_deprecation_compatibility()
|
handle_deprecation_compatibility()
|
||||||
setup_remote_pydev_debug()
|
setup_remote_debugger()
|
||||||
|
|
||||||
|
|
||||||
def setup_logging(conf):
|
def setup_logging(conf):
|
||||||
@ -708,32 +708,54 @@ def handle_deprecation_compatibility():
|
|||||||
group='health_manager')
|
group='health_manager')
|
||||||
|
|
||||||
|
|
||||||
def setup_remote_pydev_debug():
|
def _enable_pydev(debugger_host, debugger_port):
|
||||||
|
try:
|
||||||
|
from pydev import pydevd
|
||||||
|
except ImportError:
|
||||||
|
import pydevd
|
||||||
|
|
||||||
|
pydevd.settrace(debugger_host,
|
||||||
|
port=int(debugger_port),
|
||||||
|
stdoutToServer=True,
|
||||||
|
stderrToServer=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _enable_ptvsd(debuggger_host, debugger_port):
|
||||||
|
import ptvsd
|
||||||
|
|
||||||
|
# Allow other computers to attach to ptvsd at this IP address and port.
|
||||||
|
ptvsd.enable_attach(address=(debuggger_host, debugger_port),
|
||||||
|
redirect_output=True)
|
||||||
|
|
||||||
|
# Pause the program until a remote debugger is attached
|
||||||
|
ptvsd.wait_for_attach()
|
||||||
|
|
||||||
|
|
||||||
|
def setup_remote_debugger():
|
||||||
"""Required setup for remote debugging."""
|
"""Required setup for remote debugging."""
|
||||||
|
|
||||||
pydev_debug_host = os.environ.get('PYDEV_DEBUG_HOST')
|
debugger_type = os.environ.get('DEBUGGER_TYPE', 'pydev')
|
||||||
pydev_debug_port = os.environ.get('PYDEV_DEBUG_PORT')
|
debugger_host = os.environ.get('DEBUGGER_HOST')
|
||||||
|
debugger_port = os.environ.get('DEBUGGER_PORT')
|
||||||
|
|
||||||
if not pydev_debug_host or not pydev_debug_port:
|
if not debugger_type or not debugger_host or not debugger_port:
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
|
||||||
from pydev import pydevd
|
|
||||||
except ImportError:
|
|
||||||
import pydevd
|
|
||||||
|
|
||||||
LOG.warning("Connecting to remote debugger. Once connected, resume "
|
LOG.warning("Connecting to remote debugger. Once connected, resume "
|
||||||
"the program on the debugger to continue with the "
|
"the program on the debugger to continue with the "
|
||||||
"initialization of the service.")
|
"initialization of the service.")
|
||||||
pydevd.settrace(pydev_debug_host,
|
if debugger_type == 'pydev':
|
||||||
port=int(pydev_debug_port),
|
_enable_pydev(debugger_host, debugger_port)
|
||||||
stdoutToServer=True,
|
elif debugger_type == 'ptvsd':
|
||||||
stderrToServer=True)
|
_enable_ptvsd(debugger_host, debugger_port)
|
||||||
|
else:
|
||||||
|
LOG.exception('Debugger %(debugger)s is not supported',
|
||||||
|
debugger_type)
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.exception('Unable to join debugger, please make sure that the '
|
LOG.exception('Unable to join debugger, please make sure that the '
|
||||||
'debugger processes is listening on debug-host '
|
'debugger processes is listening on debug-host '
|
||||||
'\'%(debug-host)s\' debug-port \'%(debug-port)s\'.',
|
'\'%(debug-host)s\' debug-port \'%(debug-port)s\'.',
|
||||||
{'debug-host': pydev_debug_host,
|
{'debug-host': debugger_host,
|
||||||
'debug-port': pydev_debug_port})
|
'debug-port': debugger_port})
|
||||||
raise
|
raise
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added support to debug with the Python Visual Studio Debugger engine
|
||||||
|
(ptvsd).
|
Loading…
Reference in New Issue
Block a user