Guillaume Boutry 822bfb0f50 Fix documentation typos
Change-Id: I6abc64755bff428543fdb22bd04ad217b1fa5ee9
2023-02-15 10:34:56 +01:00

128 lines
5.4 KiB
ReStructuredText

===================================
Sunbeam OpenStack OPS Charm Anatomy
===================================
Overview
--------
Sunbeam OpenStack is designed to help with writing charms that use the
`Charmed Operator Framework <https://juju.is/docs/sdk>`__ and are
deployed on Kubernetes. For the rest of this document when a charm is referred
to it is implied that it is a Charmed Operator framework charm on Kubernetes.
In general a charm interacts with relations, renders configuration files and
manages services. Sunbeam Ops gives a charm a consistent way of doing this by
implementing Container handlers and Relation handlers.
Relation Handlers
-----------------
The job of a relation handler is to sit between a charm and an interface. This
allows the charm to have a consistent way of interacting with an interface
even if the charms interfaces vary widely in the way they are implemented. For
example the handlers have a `ready` property which indicates whether all
required data has been received. They also have a `context` method which
takes any data from the interface and creates a dictionary with this data
and any additional derived settings.
The relation handlers also setup event observers allowing them execute any
common procedures when events are raised by the interface. When the charm
initialises the interface it provides a callback function. The handler method
set by the observer first processes the event and then calls the charms
callback method passing the event as an argument.
Required Side Relation Handlers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The handler should be initialised with any information that will need to be
sent to the provider charm. Ideally the relation and the handler should not
interact directly with the instance of the charm class other than to run the
callback method. A required side relation handler should pass the charms
`configure_charm` method as the callback method.
Provider Side Relation Handlers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These are likely to be lightweight as there main purpose is probably to
process incoming requests from other charms. The charm should provide a
callback method which can process these incoming request.
Container Handlers
------------------
The job of a container handler is to sit between a charm and a pebble
container. This is particularly useful when a set have charms use very
similar containers such as a container that provides a WSGI service via
Apache.
The Container handler manages writing configuration files to the container
and restarting services. The charm can also query the handler to find the
state of the container, configuration within the container and the status
of services within the container.
When a Container handler is initialised the charm passes it a list of
`ContainerConfigFile`. These objects instruct the handler which containers
a configuration file should be pushed to, the path to the configuration file
and the permission the file should have. The charm instructs the handler to
write the configuration files by calling the `init_service` method along with
a `OPSCharmContexts` object.
Contexts
--------
ASO supports two different types of context. `ConfigContext` and context from
relation handlers. These are all collected together in a single
`OPSCharmContexts`. The contexts from relation handlers are in a namespace
corresponding to the relation name. `ConfigContext` objects are in a namespace
explicitly named when the `ConfigContext` is created.
Relation Handler Context
~~~~~~~~~~~~~~~~~~~~~~~~
This context is provided by `RelationHandler.context()`. These context includes
all properties from the underlying interface and additional derived settings
added by the handler.
Configuration Context
~~~~~~~~~~~~~~~~~~~~~
These context do not relate directly to relations and are mainly a method of
sharing common transformations of charm configuration options to configuration
file entries. For example a WSGI configuration context might take a charm
configuration option, inspect the runtime environment and from the two derive
a third setting which is needed in a configuration file.
Interfaces
----------
An interface should live directly in a charm and be shared via `charmcraft`
the only exception to this is the peer relation. ASO provides a base peer
interface and peer interface handler. This exposes methods which allow the lead
unit of an application to share data with its peers. It also allows a leader to
inform its peers when it is ready.
Templating
----------
Currently templates should be placed in `src/templates/`. If the charm is an
OpenStack charm the template file can be placed in the subdirectory relating to
the relevant OpenStack release and the correct template will be selected.
Charms
------
ASO currently provides two base classes to choose from when writing a charm.
The first is `OSBaseOperatorCharm` and the second, which is derived from the
first, `OSBaseOperatorAPICharm`.
The base classes setup a default set of relation handlers (based on what
relations are present in the charm metadata) and default container handlers.
These can easily be overridden by the charm if needed. The callback function
passed to the relation handlers is `configure_charm`. The `configure_charm`
method calculates whether the charm has all the prerequisites needed to render
configuration and start container services.
The `OSBaseOperatorAPICharm` class assumes that a WSGI service is being
configured and so adds the required container handler and configuration needed
for this.