The <container>-pebble-ready event is emitted once the sidecar container has started and a Unix socket is available for Pebble. There is one <container>-pebble-ready event for each container defined in charmcraft.yaml. This event allows the charm to configure how services should be launched.
This event is specific to Kubernetes sidecar charms and is only ever fired on Kubernetes deployments.
The pebble-ready event doesnât guarantee the workload container is still up. For example, if you manually kubectl patch during (for example) install, then you may receive this event after the old workload is down but before the new one is up.
For this reason itâs essential, even in pebble-ready event handlers, to catch ConnectionError when using Pebble to make container changes. There is a Container.can_connect() method, but note that this is a point-in-time check, so just because can_connect() returns True doesnât mean it will still return True moments later. So, code defensively to avoid race conditions.
Moreover, as pod churn can occur at any moment, pebble-ready events can be received throughout any phase of a charmâs lifecycle. Each container could churn multiple times, and they all can do so independently from one another. In short, the charm should make no assumptions at all about the moment in time at which it may or may not receive pebble-ready events, or how often that can occur. The fact that the charm receives a pebble-ready event indicates that the container has just become ready (for the first time, or again, after pod churn), therefore you typically will need to reconfigure your workload from scratch every single time.
We should probably mention explicitly that pebble-ready can be emitted before/after any of config-changed/start.
We should probably mention that wait_for_idle may return before the workload is ready, and a block_until the service, e.g. via HTTP API, returns a âreadyâ status, would probably be needed.
What I did is to add 1 minute sleeps to the upgrade-charm, config-changed and start handlers.
I kill the pod with kctl delete pod <pod name> -n <model name>. After the new container has been replaced and the new agent is in place, I connect to the pod with kctl exec . . . -c <workload> -n <model> -- /bin/bash
At this point, I can see that pebble is already running with a ps aux, and the charm code is still on the sleep for upgrade-charm. I would think that pebble, being ready well before config-changed or start, would trigger the event. But no, those events will trigger (with the sleeps) and only after that, <container>-pebble-event happens.
Is there something Iâm missing here?
PS: I agree on the wait_for_idle comments. Very useful information Iâll add that
pebble-ready fires once the other container has pebble actually up and running. It shouldnât be guaranteed before/after start (and certainly could happen post start if the primary container restarts at any point)
Juju has fairly implicit ordering of hooks, although not strictly defined, pebble-ready hooks fire just before an action or command could be run.
It is fairly guarenteed after install/upgrade, config-changed and start. There is some guarantee that pebble-ready will happen after relation-created and leadership hooks, only if those are already ready to run.
If there is a need for it, we could add another hook that fires as early as possible, e.g. pebble-early-ready, but we would need to understand your use case further to see when this should run, as pebble is likely to always be ready before the juju uniter has even downloaded the charm.
Iâm just trying to understand why even after I add long sleep in config-changed and upgrade-charm, I still see pebble-ready fire only after all of them.
Just to rephrase what Harry was saying. pebble-ready-event always fires after âstartâ. (Start is the point where a Unit agent starts to join its relations and can respond to things like juju run.) I had probably given bad information originally saying that it could fire at any time. Harry had actually done the work to not trigger pebble-ready before start (but it has been that way for all of 2.9).
I added a bunch of sleeps and when the charm is first deployed I consistently see pebble-ready after leader-elected but before config-changed and start.
Container.can_connect() is a point-in-time check, so try-except is technically still needed for the same reason (i.e. can-connect = True doesnât mean that 1 millisecond after can-connect is still true).
I also think we should more clearly separate juju from ops in these kind of docs. I.e. I would try to avoid mentioning ops under the emission sequence section.