Juju debug-code - use a debugger for your hooks

Juju debug-code

(added in Juju 2.8)

Maybe this is just a section of Debugging charm hooks

Many of our charms are written in python, which has nice facilities for live debugging of code pdb. For the Operator Framework, we wanted to provide a nice way to not just get a shell where you can run the hook from bash, but actually drop you all the way into a pdb shell.

For charmers, the main difference between juju debug-hooks and juju debug-code is that once the tmux session is established, it executes the hook as normal, but with the environment variable JUJU_DEBUG_AT set. Charms can look for that environment variable and chose to drop into a debugger based on the value.

Hook names

Like juju debug-hooks, juju debug-code takes a list of hooks to debug, and will run all other hooks as normal. (eg, if you just want to debug config-changed, you can specify juju debug-code unit/0 config-changed.) This helps developers avoid having to manually interact with all the other hooks that Juju might fire before running the one they are interested in debugging.

JUJU_DEBUG_AT

The Charm is responsible for interpreting the meaning of the environment variable JUJU_DEBUG_AT. The default set by juju is "all". Users can set a different value by supplying juju debug-code --at LOCATION.

Operator Framework

For Operator Framework charms, the framework interprets the string as a comma separated list of named breakpoints, with reserved keywords for all and hook. Charm developers can create their own breakpoints by calling self.framework.breakpoint(name=None), passing an optional name.

For the default value of all, the python interpreter will drop into pdb for each handler of a hook, and for the all named and unnamed breakpoints that are encountered while running the code.

If the value is set to hook, then only the handlers for a given Juju hook will trigger a breakpoint. Unnamed and named breakpoints will be skipped.

Hi @jameinel

Is there a way that debug-code use ipdb instead of pdb?

debug-code just causes Juju to run the hooks as normal with the env variable JUJU_DEBUG_AT set. Operator Framework then interprets that to call breakpoint at the appropriate times. I don’t know the specifics of how to use ipdb instead of pdb its probably something you could do inside your charm, but it is a bunch of dependencies, etc that would need to be available during hook execution, so likely needs to be built into your charm dependencies. You might also ask @rwcarlsen or @pengale what it might take to have support for that in the Operator Framework (at the very least to make it easily pluggable).

Right now we just directly call pdb in ops framework when we fire off hooks here. There isn’t a way to swap it out for other debuggers right now. You could just manually invoke ipdb in your charm code triggering off of JUJU_DEBUG_AT like @jameinel mentioned.

I don’t think that I see us adding ipdb as a dependency. One of the tenets of the OF is to be as close to zero dependencies outside of the Python standard lib as possible. Ipdb is wonderful, but pdb is fit for purpose, and comes built in.

Feel free to import and invoke it in your charm, though. I’d even say that monkey patching ops.framework.pdb isn’t the worst idea. You’d be able to piggy back on the code that drops you into a debugger as soon as a hook executes, without too much risk that you’ll break something relevant for production.

1 Like