cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3343
Views
51
Helpful
3
Comments
Rodolphe Trujillo
Cisco Employee
Cisco Employee

When I started at Cisco I wrote a blog post "How to Debug NSO Services and Action with Pycharm" which remain actual even 3 years later, a customer recently said to me that he is not using Pycharm but it would be nice to have the same article with VsCode .

So here it is :

On the python which is running the NSO python package, you want to debug :

pip install debugpy

This is a Microsoft library who wraps the well-known pydevd library to make it compatible with VsCode.

 

We will do remote debugging, debugpy will create a debug server on the NSO side and VsCode will connect to it, then the debug server will send all debug infos to VsCode.

 

On this demo I will debug on a local install of NSO but the debug can be done on a distant server (don't forget to open the port)

If you click on the Run and Debug icon of VsCode you will see something like this :

run-and-debug.png

Click on "create a launch.json file" this will open the launch.json file.

Copy and paste the following section in the brackets :

 

{
            "name": "Python: NSO Action",
            "type": "python",
            "request": "attach",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": true,
            "port": 5678,
            "host": "localhost",
  }

 

You should see something like that :

json-nso-action.png

 

Save the file and you should have a "Python NSO action" debug setting with a run button at the top left.

run-debug.png

 

In the main.py file, class Main, method setup(), of your NSO package put the line  :

 

 

debugpy.listen(5678)

 

 

debugpy-listen.png

 

This will open the port of the debug server after a package reload or a package redeploy. Don't forget to remove it after debugging
It's also possible to change the ip address of the debug server by providing a tuple (ip_adress,port) for example:

 

 

debugpy.listen(('0.0.0.0', 5678))

 

Now we must put a breakpoint, I didn't manage to make the graphical red breakpoint (in screenshot below it's at line 17) it don't work I don't know why.
UPDATE feb 2023 : now we know why, as always it's a mapping problem ! It's now resolved by @atreyulovesyou in this comment below .

Another method to get breakpoint works it to use the programmatic breakpoint

 

debugpy.breakpoint()

 

In the screenshot it is at line 19.

different-breakpoint.png

 

Ok so you can do a package reload to run the debug server and to take the breakpoint into account.

To connect to the debug server click on the green triangle.

run-debug.png

A list appears in the "Call Stack" section in the UI :

call-stack.png

If you launch your action, you'll see the arrow on the next instruction to be executed in the code.( you can raise the value of the timeout of the NSO service or action if you want )


UPDATE feb 2023 : with NSO if you want a lot of time to debug there is a global setting to raise: service-callback-timeout 

 

set services global-settings service-callback-timeout 300

 

debug-running.png

That's it ,now you're able to debug with VsCode.

Don't forget to remove the "debugpy.listen(5678)" on your production code , the breakpoint is more easy to remember as your service/action will be stuck , but the debug server can be a big security hole if you let it run. <= Very important don't miss this.

3 Comments
atreyulovesyou
Level 1
Level 1

Q: a running NSO will halt a service if you attach a debugger after 2m it seems, thinking it's a hung process and is all right and good for nso system health, but prevents reasonable debug in an IDE.

Can you tell us how to instruct it to stop / raise the timeout on nso server, please?

In hunting I find transaction timeouts, but not service side timeouts for following example above - i want to stop a running nso service call, by hold in a remote debugger.  nso is unaware this is happening (it is happening in the python spawned process), and is only aware that the spawned process for a service being debugged is taking a long time. we need nso to not kill that process after n minutes, by making n large.

please, be super explicit, for the slow and illed of barrier as woe.

---

for fulness in this explain article, you'll need a tuple based argument to debugpy, or otherwise to have access to 127.0.0.1 on remote nso machine from where ide running, as debugpy default bind is loopback if a port is all that is provided.

atreyulovesyou
Level 1
Level 1

you couldn't place a breakpoint (it went grey and said in breakpoint window that you couldnt find file?) because you lacked path mappings, more than likely. the ide must find source that matches on local machine as well as remote being debugged.

I like to run my vscode Workspace from nso rundir. the below presumes connecting over the remote-ssh extension, as the 'localpath' corresponds to a file path from perspective of the remote nso system.

in the below, I point to the resolved current directory where packages exist, but could likely get away with the 'rundir/packages' as remote root.  as to why current directory equivalent of rundir/packages? no clue... I found a fragment of a 1000usd cisco training document which stated this...

the dev guide is not good for explaining nso runtime directories, or how files get moved about or staged when packages are reloaded. in fact, piecing together much of effectively working to code against nso is quite painful. 

regardless, for config of path mappings, this can be configured in launch.json.

below presumes your Workspace in vscode is nso rundir over remote-ssh, as stated prior:

{...rest of file...

"pathMappings": [

    {

      "localRoot": "${workspaceFolder}"/packages,

      "remoteRoot": "/path/to/rundir/symlink/place/ends/cur/1"

    }

...rest of file...}

atreyulovesyou
Level 1
Level 1

thanks to @Rodolphe Trujillo ! -- 

from the ncs_cli, in configure:

set services global-settings service-callback-timeout 7200

^ give yourself 2 hours, instead of 2 minutes. 

tested stepping through code until control is returned to nso and the python process exits OK - again, this works if you set 'just my code' to false in launch.json, and you've setup the debug listener in setup(), as Rodolphe describes.

my launch.json looks like this:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Remote Attach",
            "type": "python",
            "request": "attach",
            "connect": {
                "host": "10.1.2.3",  //nso server IP
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/packages",
                    "remoteRoot": "/your/nso/run/dir/state/packages-in-use.cur/1"
                }
            ],
            "justMyCode": false
        }
    ]
}

 

Again, thanks for the assist @Rodolphe Trujillo !
Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the NSO Developer community: