generated from canonical/template-operator
-
Notifications
You must be signed in to change notification settings - Fork 5
charm.py
Andreia Velasco edited this page Sep 27, 2024
·
1 revision
The charm.py
file is the entry point for the charm. It contains functions for its basic operation, including its major hooks and file management.
The following charts detail the expected flow of events for the pgbouncer-k8s
charm. For more information on charm lifecycles, see A Charm's Life.
Relation events can be fired at any time during startup, but they're generally expected by the charm to run after start
and pebble_ready
hooks. The "golden path" in the flowchart below is shown by the bold lines.
flowchart TD
start([Start Charm]) ==> start_hook
start --> peer_relation_created
start_hook[Run start hook. Defers until the workload container is available, and the leader unit has generated config, which is then written to the container filesystem and shared to other units via peer databag.]
start_hook ==> pebble_ready[Run pgbouncer-pebble-ready hook. Defers until config has been written to container filesystem. Writes pebble config and TLS certs to pgbouncer container, which in turn starts pgbouncer services.]
pebble_ready -. deferral .-> start_hook
pebble_ready ==> begin([Begin charm operation])
pebble_ready --> backend_database_relation_created
pebble_ready --> client_relation_created
backend_database_relation_created[Backend relation can be created, but won't be initialised unil pgbouncer services are running]
backend_database_relation_created -. deferral .-> pebble_ready
peer_relation_created[Peer relation created by default on startup. Defers config upload until config exists, and defers auth file upload until backend relation exists]
peer_relation_created -. deferral .-> start_hook
peer_relation_created -. deferral .-> backend_database_relation_created
client_relation_created[Client relations can be created, but won't be initialised until pgbouncer services are running and backend database is initialised]
client_relation_created -. deferral .-> backend_database_relation_created
client_relation_created -. deferral .-> pebble_ready
flowchart TD
exists([Charm is running]) --> config_changed[Charm config is changed, firing Config-changed hook]
exists --> relation_changed[Backend or client relation updates, triggering changes in pgbouncer config] --> update_cfg
config_changed --> update_cfg[Leader updates config locally and in peer databag, causing a peer-relation-changed event]
update_cfg --> peer_changed[Follower units update config from peer databag]
update_cfg --> reload_pgb[Reload pgbouncer]
peer_changed --> reload_pgb
reload_pgb --> continue([Charm continues running])
flowchart TD
exists([Charm is running])--> leader_deleted[Leader unit is deleted]
leader_deleted --> relation_remove_leader[All relations add unit-departing flag to unit databag, and update connection information]
relation_remove_leader -.-> leader_elected[leader_elected hook fires after an indeterminate amount of time]
leader_elected --> update_leader[Update leader address in peer databag, and update connection information in relation databags]
update_leader --> continue([Continue normal charm operation])
These flowcharts detail the control flow of individual hook handlers in this program. Unless otherwise stated, a hook deferral is always followed by a return.
flowchart TD
hook_fired([start Hook]) --> is_container{ Is container available? }
is_container -- no --> defer> defer ]
is_container -- yes --> is_cfg{ Is pgbouncer config available in container or peer databag? }
is_cfg -- no --> is_leader{ Is the current unit Leader? }
is_cfg -- yes --> make_dirs[Create directory structure for charm]
is_leader -- no --> defer_wait> defer: wait for leader unit to generate config and upload to peer databag ]
is_leader -- yes --> gen_cfg[ generate new config ]
gen_cfg --> make_dirs
make_dirs --> render_cfg[ render config, update relations if available ]
render_cfg --> rtn(( return ))
flowchart TD
hook_fired([pgbouncer-pebble-ready Hook]) --> is_cfg{Is pgbouncer config available?}
is_cfg -- no --> defer>defer]
is_cfg -- yes --> gen_cfg[Generate pebble config and start pgbouncer services]
gen_cfg --> verify[Verify pgbouncer services are running, and set charm status accordingly]
verify --> rtn([return])
flowchart TD
hook_fired([config-changed Hook]) --> is_leader{Is current unit leader?}
is_leader -- no --> rtn([return])
is_leader -- yes --> is_cfg{Is pgbouncer config available?}
is_cfg -- no --> defer>defer]
is_cfg -- yes --> match_cfg[Modify pgbouncer config to match charm config]
match_cfg --> render_cfg[Render config & reload pgbouncer]
render_cfg --> rtn2([return])
flowchart TD
hook_fired([update-status Hook]) --> is_backend_ready{Is backend database ready?}
is_backend_ready -- no --> set_blocked[Set Blocked status]
is_backend_ready -- yes --> is_running{Is pgbouncer running?}
is_running -- yes --> set_active[Set Active Status]
is_running -- no --> set_waiting[Set Waiting Status]
set_blocked --> update_leader[Update leader in Peer Relation Databag.]