Description
The docs say:
A unit’s relation settings persist beyond its own departure from the relation
[...]
During a relation-departed hook, relation settings can still be read (with relation-get) [...] All units will still be able to see all other units
However, it's not possible (without using a private attribute) to access remote data from ops.
This pair of example charms demonstrate the issue:
- 'provider-charm' puts some example data into the local unit relation databag on
relation-joined
and does nothing else. - 'require-charm' logs that data on
relation-changed
(just to show it's accessible normally) and attempts to log that data onrelation-departed
. However, that will fail, unless we get the data with manually creating aRelationDataContent
object, which requires usingmodel._backend
.
To use the charms:
charmcraft pack
each charm, andjuju deploy
them into a model (I used k8s but I believe this will be the case for machine as well)juju integrate
the two charms together- Wait for everything to settle down (you'll see that the data is in the relation databag from the
relation-changed
debug-log output) - Use
juju remove-relation
to remove the integration between the applications - You should see
departed: foo
anddeparted (using private): foo
injuju debug-log
, but instead will seedeparted: COULD NOT GET IT.
anddeparted (using private): foo
.
The reason for this is that Relation.units
is populated by running Juju's relation-list
, which doesn't have the departing relation in the relation-departed
event. Relation.data
is a RelationData
object, and the ._data
attribute (which __getitem__
exposes) is populated with (a) data for the local unit, (b) data for the local app, and (c) data for each unit in the relation's .units
. In (e.g.) relation-changed
, this means that the remote unit's data will be there, but in relation-departed
it will not.
Juju's relation-get
will still provide access to the data, and this is meant to be available (according to the docs linked above and also the Juju team). However, the only method ops provides to use relation-get
is via the RelationDataContent
class (which needs the backend passed to instantiate an object) or RelationData
(which needs the unit to be in relation-list
as described above).
It seems like we should make this data available. It seems cleanest for it to be available in Relation.data
like it would be outside of relation-departed
- the departed unit is available in the environment and in the event
object, so there would need to be a bit of work to get it into Relation.data
without passing too much context around, but it's certainly feasible.