Writing actions with base/reactive

Hey folks, I haven’t written actions with reactive before and would like to know how to do the following:

  • Use single file for both charm code and actions.
    • I tried using symlinking actions/name-of-action to reactive/charm-code.py, but no success.
  • Manipulate flags (clear a flag for example) after an action has run.
    • I tried importing from charms.reactive.flags import clear_flag, but that didn’t go so well. I see there is an issue covering something in this area, but I’m having a bit of a hard time figuring out the solution.

Does anyone have some examples so I can hold it correctly?

Out of curiosity, why the need to mix them in the same module?

Because I only want to run a function or two, it’s a small charm where the main module and action would share a lot of code/deps and feels out of place to split up.

I see. I’ve taken resort to hooks-only charms for small charms lately because if the overhead I get from python modules and the reactive/charm-helpers adds.

Also, since I use centos for SLURM this simplifies for me alot.

Too bad I can’t help you here.

I’m going to be unhelpful in that I’m not sure what’s specific the reactive bits to get that to work but I will say it’s interesting you bring this up as the new framework design includes a new “dispatch” file that allows one to use the same code path for charms and actions as you’re describing.

Thanks for the input guys!

Anyone else got an idea? I’d like a hard no if it is not possible with Juju/charms, so I don’t sit on the fence for ever.

I believe in most reactive charms the hook isn’t just symlinked but a python call to the reactive code. e.g.

https://api.jujucharms.com/charmstore/v5/aodh-36/archive/hooks/config-changed

So I don’t think the symlink will be enough.

The thing there is that then the paths need adjusting because you’re trying to reach up a dir from the actions vs hooks directory.

All that said, the other thing is once reactive has its hold on your code path you’ll need it to get triggered and I don’t think reactive has any sort of @when…event handler to catch your action and run with it. So I’m going to suggest it’s not possible but I defer to @cory_fu to correct me if I’m totally missing the obvious path forward.

Because the intent differs between actions and hooks, actions generally don’t use the reactive dispatch mechanism. Specifically, actions are an explicit call by the Juju user to request a single, specific set of work to be done, while hooks are Juju informing the charm that some aspect of the model relevant to the charm has changed, which may lead to a change in the state of the charm.

That said, you can do some or all of the things that the hook.template does, and if you call charms.reactive.main() then all of the normal handler dispatch mechanisms will be invoked. Note, however, that there are no decorators for handling actions, so you probably want to do the action-specific work within the action file itself or at least set some action-specific flags so that you can have your handlers dispatched accordingly.

In general, though, I would instead recommend factoring your shared code out into a lib/charms/layer/{charm_name}.py file that you can include and call from both actions and reactive handlers.