Configuring Remote Python Debugging in VSCode - uyuni-project/uyuni GitHub Wiki
This document expects you have a provisioned Uyuni or MLM containerized server. If you do not, see for example Sumaform.
To set up remote debugging in VSCode for Python parts of Uyuni:
- Expose debug port for the server container.
- Install
debugpy
in the server container. - Configure file mapping in VSCode.
- Modify the Python script we want to debug.
[!IMPORTANT] In this document, we are modifying the Uyuni server container's ephemeral filesystem layer. Reprovisioning/restarting the container undoes the modifications.
Expose Container Debug Port
Use the port 5678
for establishing remote connections to the container. By default, the container does not expose such port. To expose the port, modify the /etc/systemd/system/uyuni-server.service
file:
# Make file writable
chmod +w /etc/systemd/system/uyuni-server.service
# Open the file, e.g. in vim
vim /etc/systemd/system/uyuni-server.service
When editing the file, add the 5678:5678
port:
...file omitted...
-p [::]:8002:8002 \
-p 5678:5678 \
-v var-cobbler:/var/lib/cobbler
...file omitted...
Save the file, then restart the Uyuni server:
systemctl daemon-reload
systemctl restart uyuni-server.service
You can verify that the port is now exposed:
podman ps | grep 5678
Installing Debugpy
First, ssh to your server and execute mgrctl term
to gain access to the container.
The easiest way to install debugpy
is to use zypper:
zypper in python3-debugpy
However, frequently, this is not possible, e.g. the server container has no access to external repositories that have the python3-debugpy
package. In that case, we can use pip
in a virtual environment to install debugpy:
# Create a new virtual environment
python3 -m venv venv
# Install debugpy into the venv
venv/bin/pip install debugpy
# Move the debugpy from the venv into the system's site packages
cp -r venv/lib/python3.6/site-packages/debugpy* /usr/lib/python3.6/site-packages/
# Verify you can import debugpy from python
python3 -c 'import debugpy' && echo "success"
[!IMPORTANT] If you are debugging the Salt Bundle, you can use
pip
directly from the bundle. For example,/usr/lib/venv-salt-minion/bin/pip install debugpy
. After that, you can verify the debugpy import by executing/usr/lib/venv-salt-minion/bin/python3 -c 'import debugpy' && echo "success"
.
Configuring VSCode
Before you connect to the remote Python code, you must configure path mapping in VSCode.
VSCode must know that, for example, when you clone the uyuni
repository and open the python
directory in VSCode, i.e. cd uyuni && code python/
, then the contents of ${workspaceFolder}/spacewalk
(which corresponds to the spacewalk directory) exists on the remote server as /usr/lib/python3.6/site-packages/spacewalk
.
Note that:
- Without correct path mapping, VSCode will not be able to pause remote script execution.
- The local and remote file contents must be identical. Otherwise, VSCode might not be able to pause remote script execution, or it will show different lines from the lines that are actually executed remotely.
To configure the path mapping in VSCode, open the python
directory in VSCode:
git clone https://github.com/uyuni-project/uyuni.git
cd uyuni
code python/
[!NOTE] If you open the whole Uyuni project in VSCode, for example
code uyuni
, the following path mapping is incorrect. In such case, you must adapt the path mapping.
Then, press ctrl+shift+d
, click create a launch.json file -> python debugger -> remote attach.
Enter the hostname or IP address of the host machine that runs the server container, and select port 5678.
In the launch.json
file, add "justMyCode": false,
. Failure to do so will prevent VSCode from pausing the remote execution.
Then, add the path mapping of files you want to debug. For example, consider want to debug the reposync.py
file.
In the container, this file exists in the /usr/lib/python3.6/site-packages/spacewalk/satellite_tools/reposync.py
location. This reveals that we need to map the remote /usr/lib/python3.6/site-packages/spacewalk
directory to the local ${workspaceFolder}/spacewalk
directory.
The full JSON file might look as such:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Remote Attach",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "192.127.5.5",
"port": 5678
},
"justMyCode": false,
"pathMappings": [
{
"localRoot": "${workspaceFolder}/spacewalk",
"remoteRoot": "/usr/lib/python3.6/site-packages/spacewalk"
}
]
}
]
}
Modifying the remote Python script
Continuing with the assumption that we want to debug reposync.py
, in the server container, we must modify the file, for example vim /usr/lib/python3.6/site-packages/spacewalk/satellite_tools/reposync.py
.
Then, add the following lines into the script:
# ...file omitted...
# Add debugpy
import debugpy
debugpy.listen(("0.0.0.0", 5678))
debugpy.wait_for_client()
# ...rest of the file...
import base64
import configparser
...
This pauses the execution until you connect your remote VSCode debugger to the local script.
Because you modified the remote file, you must modify the local file (in VSCode) to be identical to the remote file. In VSCode, open reposync.py
and add the same code on the same location. You must not add or remove any spaces before or after the added text.
[!NOTE] It might be easier to copy the modified file from the Uyuni server into your local development environment.
Finally, add a debug point in VSCode where you want the execution to stop, for example note the red dot on line 629:
Script execution
In the case of reposync.py
, we can execute the file by using the spacewalk-repo-sync
command, for example:
/usr/bin/spacewalk-repo-sync --channel sl-micro-6.1-pool-x86_64 --type yum --non-interactive
After executing the command, you see no output. This is because the script has paused execution until you connect to it from your VSCode.
In VSCode, press F5 to start the remote execution. If you configured everything correctly, you'll see paused execution in your VSCode: