I’m using this description of Juju state machine , which has helped me alot understanding how juju works from a charming perspective.
It was provided to me by @Dmitrii some time ago, but I have looked for something like this more official, and also perhaps more up to date? (I fear its even not the same today).
Does someone know if there is some official, up-to-date and documented version of this except the one I already have?
As you can see here in what I think is the “best” source, Event Cycle the documentation lacks many parts and examples. Its missing visualization, it doesn’t provide examples for hooks frameworks (only reactive), missing both basic documentation but also examples from the operator framework etc.
I’m going to try to create some sort of tutorial here, but I struggle here since the official documentation I would like to reference is so bad on this topic and the quality of the sources are also weak.
I’ll try draft up a tutorial during the coming week and see there it goes.
2 Likes
… I’m seeing this for example now when I’m exploring this:
2020-09-06 12:20:00 INFO juju.worker.uniter.operation runhook.go:145 skipped "master-relation-created" hook (missing)
The above tells me that a hook named “relation-created” is fired which I can’t find the docs…
This tells me that the state-diagram I have can’t be up-to-date and that the event-cycle looks different than I thought and I’m not sure where this hooks is called and when etc.
Dmitrii
(Dmitrii Shcherbakov)
13 September 2020 19:03
3
Hi Erik,
The <relation-name>-relation-created
hook family was added in Juju 2.8 to address some stateful application initialization uses-cases. I think the event lifecycle docs haven’t been updated yet (ping @juju-developers ).
The Juju team is proud to release Juju 2.8.0. We aim to be your preferred tool for writing operators, software that manages software, whether your hosting infrastructure is Kubernetes, in the cloud or on-premise.
2.8 Highlights
New Features
Juju 2.8.0 includes extra features for people using Juju as well as those writing charms for Juju.
OpenStack models now have multi-NIC support
The new Juju Dashboard replaces the Juju GUI.
A new hook family, *-relation-created, has been introduced to not…
juju:develop
← achilleasa:dev-fire-relation-created-hooks
opened 06:31PM - 20 Mar 20 UTC
## Description of change
This PR enables the uniter to trigger a new hook typ… e called `xyz-relation-created` which:
- fires **after** `install` and **before** `xyz-relation-joined`
- is allowed to fire **before** any of the remote units come online.
The new hook is **guaranteed** to fire **before** any leadership hook for **peer** relations and for any **non-peer relation already established at that point**. For non-peer relations established at a later point in time, the hook will fire once the relation has been established.
In order to implement the above semantics, a new resolver had to be created and invoked prior to the leadership-hook resolver. This proved to be a non-trivial task since the new resolver needs to share internal state with the original relation resolver. In particular, the original relation resolver was nothing more than a proxy to a pluggable interface called `Relations` which was actually responsible for implementing the hook triggering logic. The same interface also provides the relation-specific implementation for the `PrepareHook` and `CommitHook` calls that the resolver callbacks invoke.
The solution followed by this PR is to effectively refactor (for more details see the commit log for a73d509) the interface to only handle state-related tasks and move the hook logic back to the resolver. To make the code easier to follow, the `Relations` interface (in `worker/uniter/relation`) has been renamed to `StateTracker` to better convey its purpose.
The `relation-created` hook provides information about the remote application that was related (note that local == remote for peer relations). For symmetry, the `relation-broken` hook has been updated to also include the same information (this information was lost prior to this PR so it was not made available).
## QA steps
**Important**: before running the following steps, make sure you have dialed up the logging level on your model by running:
```
juju model-config logging-config='<root>=ERROR;juju.worker.uniter.operation=DEBUG'
```
### Scenario 1: pre-established non-peer relations
```console
$ juju deploy -n2 wordpress && juju deploy mysql && juju add-relation wordpress mysql
# Wait for everything to settle and check the logs:
# (for the leader wordpress unit)
$ juju debug-log --replay --include unit-wordpress-0 | grep 'committing operation' | cut -d '"' -f2
install cs:wordpress-0
run install hook
run relation-created (0; app: wordpress) hook <-- new (peer)
run relation-created (2; app: mysql) hook <-- new (non-peer)
accept leadership
run leader-elected hook <-- xxx-created before leader-elected
run config-changed hook
run start hook
run relation-joined (0; unit: wordpress/1) hook
run relation-changed (0; unit: wordpress/1) hook
run relation-joined (2; unit: mysql/0) hook
run relation-changed (2; unit: mysql/0) hook
run update-status hook
# (for the non-leader wordpress unit)
$ juju debug-log --replay --include unit-wordpress-1 | grep 'committing operation' | cut -d '"' -f2
install cs:wordpress-0
run install hook
run relation-created (0; app: wordpress) hook <-- new (peer)
run relation-created (2; app: mysql) hook <-- new (non-peer)
run leader-settings-changed hook
run config-changed hook
run start hook
run relation-joined (0; unit: wordpress/0) hook
run relation-changed (0; unit: wordpress/0) hook
run relation-joined (2; unit: mysql/0) hook
run relation-changed (2; unit: mysql/0) hook
run update-status hook
# (for mysql unit)
$ juju debug-log --replay --include unit-mysql-0 | grep 'committing operation' | cut -d '"' -f2
install cs:mysql-58
run install hook
run relation-created (1; app: mysql) hook <-- new (peer)
run relation-created (2; app: wordpress) hook <-- new (non-peer)
accept leadership
run leader-elected hook
run config-changed hook
run start hook
run relation-joined (2; unit: wordpress/0) hook
run relation-changed (2; unit: wordpress/0) hook
run relation-joined (2; unit: wordpress/1) hook
run relation-changed (2; unit: wordpress/1) hook
run update-status hook
run update-status hook
```
### Scenario 2: establishing peer relations for already-deployed units
```console
$ juju deploy wordpress && juju deploy mysql
# Wait for them to become ready and *then* relate them
$ juju add-relation wordpress mysql
# Wait a bit and then remove relation
$ juju remove-relation wordpress mysql
# Check the logs
$ juju debug-log --replay --include unit-wordpress-0 | grep 'committing operation' | cut -d '"' -f2
install cs:wordpress-0
run install hook
run relation-created (0; app: wordpress) hook <-- new peer
accept leadership
run leader-elected hook
run config-changed hook
run start hook
run relation-created (2; app: mysql) hook <-- late-added relation
run relation-joined (2; unit: mysql/0) hook
run relation-changed (2; unit: mysql/0) hook
run relation-changed (2; unit: mysql/0) hook
run update-status hook
run relation-departed (2; unit: mysql/0) hook
run relation-broken (2; app: mysql) hook
$ juju debug-log --replay --include unit-mysql-0 | grep 'committing operation' | cut -d '"' -f2
install cs:mysql-58
run install hook
run relation-created (1; app: mysql) hook <-- peer relation
accept leadership
run leader-elected hook
run config-changed hook
run start hook
run relation-created (2; app: wordpress) hook <- late-added relation
run relation-joined (2; unit: wordpress/0) hook
run relation-changed (2; unit: wordpress/0) hook
run update-status hook
run relation-departed (2; unit: wordpress/0) hook
run relation-broken (2; app: wordpress) hook
```
### Scenario 3: relation with no units
```console
$ juju deploy wordpress && juju deploy mysql
$ juju remove-unit mysql/0
# Wait for things to settle until juju status looks like this:
$ juju status
App Version Status Scale Charm Store Rev OS Notes
mysql waiting 0 mysql jujucharms 58 ubuntu
wordpress active 1 wordpress jujucharms 0 ubuntu
Unit Workload Agent Machine Public address Ports Message
wordpress/0* active idle 1 10.241.88.191 80/tcp
# Create a relation and check the logs
$ juju add-relation wordpress mysql
$ juju debug-log --replay --include unit-wordpress-0 | grep 'committing operation' | cut -d '"' -f2
install cs:wordpress-0
run install hook
run relation-created (0; app: wordpress) hook <-- peer relation
accept leadership
run leader-elected hook
run config-changed hook
run start hook
run relation-created (2; app: mysql) hook <- non-peer relation with no remote units
```
### Scenario 4: leader sets peer relation data in relation-created hook
```console
$ echo '#!/bin/sh
echo $0
is_leader=`is-leader`
if [ "${is_leader}" = "True" ]; then
echo "setting app databag for peer relation as the leader"
relation-set --app answer=42
fi' > testcharms/charm-repo/quantal/all-hooks/hooks/self-relation-created
$ juju deploy ./testcharms/charm-repo/quantal/all-hooks -n 2
# Wait for things to settle and check peer relation data and check the peer app databag
$ juju run --unit all-hooks/0 'relation-get -r 0 --app=True - all-hooks'
answer: "42"
$ juju run --unit all-hooks/1 'relation-get -r 0 --app=True - all-hooks'
answer: "42"
```
## Documentation changes
We need to update our 2.8 docs to indicate the order of relation-created hooks.
## Bug reference
https://bugs.launchpad.net/juju/+bug/1859769
relation-created
is particularly useful in a scenario where you want to use application relation data (introduced in 2.7.0) on a peer relation which is supposed to replace leader data - bug Bug #1859769 “[2.7.1] peer relation (and its app relation data) ...” : Bugs : Canonical Juju has some particularities as to why that was introduced.
Operator Framework does not even expose leader data and expects that developers use app relation data with peer relations.
I think the diagram is quite useful for understanding main loop-like semantics of how units operate. Looking at it now, I think it could be enhanced by adding some information about sources of events and the context available in them.
Event objects in the framework do a better job at exposing the context than what was available before:
https://ops.readthedocs.io/en/latest/index.html#ops.charm.RelationCreatedEvent
https://ops.readthedocs.io/en/latest/index.html#ops.charm.ActionEvent
1 Like
Thanx @Dmitrii - the diagram you provided has been fundamental to my understanding of the event-loop of juju and critical to understanding juju. For me at least.
I would love to see this material more part of the official documentation, rather than an image in my github repo and hidden away in a beginner level tutorial.
I don’t know what I would do without it really.
1 Like
@juju-developers @Dmitrii - any chance of getting a new shiny state-machine-diagram published with information related to how its traversed, context etc?
I’m in the process of writing up a tutorial covering relations and it feels wrong not to be able to reference quality material from the upstream project for this purpose.
I hate to have to use my own =D
1 Like
We would love to get something put together. As well as the event cycle doc referenced the the first post, there’s also
An application unit’s direct action is entirely defined by its charm’s hooks. Hooks are executable files in a charm’s hooks directory; hooks with particular names (see below) will be invoked by the juju unit agent at particular times, and thereby cause changes to the world.
Whenever a hook-worthy event takes place, the unit agent first checks whether that hook is being debugged , and if so hands over control to the user. Otherwise, it tries to find a hook with precisely the right name. If the ho…
But it doesn’t yet reference the relation created hook so there’s some significant work required to get things updated. It’s definitely something we need to deal with.
1 Like
Getting juju core documentation in place, in perfect shape is of course of critical importance in every possible way. I’d love to see this happening.
“A painting will never be better, than the work you put down in its foundation.”
jameinel
(John A Meinel)
24 September 2020 13:44
8
Documentation is definitely a focus for us at the end of this cycle and going forward through next cycle. We’re currently focused on a tutorial series for initial user experience.
1 Like
I love to hear that! I think this is likely the most significant thing you can do to grow juju and get people on board.
I’m also working on a tutorial on relations which I would love to get out there once I have completed it.
I can share a preview code with you @jameinel to get some initial feedback?
jameinel
(John A Meinel)
24 September 2020 14:19
10
Certainly. I look forward to seeing it.
1 Like
There is a fresh version out there somewhere now… In some github repo I can’t find @tmihoc … do you know where?