Skip to content

Commit

Permalink
docs: use noun relation and verb integrate (#1574)
Browse files Browse the repository at this point in the history
Update documentation, mostly the content that used to be on Discourse,
to use the noun form relation and the verb integrate.

---------

Co-authored-by: Tony Meyer <[email protected]>
  • Loading branch information
james-garner-canonical and tonyandrewmeyer authored Feb 13, 2025
1 parent 0b23b6f commit 8f25088
Show file tree
Hide file tree
Showing 22 changed files with 51 additions and 51 deletions.
9 changes: 4 additions & 5 deletions docs/explanation/charm-relation-interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

> See also: {ref}`manage-interfaces`
[`charm-relation-interfaces`](https://github.com/canonical/charm-relation-interfaces) is a repository containing specifications, databag schemas and interface tests for Juju relation interfaces. In other words, it is the source of truth for data and behavior of providers and requirers of integrations.
[`charm-relation-interfaces`](https://github.com/canonical/charm-relation-interfaces) is a repository containing specifications, databag schemas and interface tests for Juju relation interfaces. In other words, it is the source of truth for data and behavior of providers and requirers of relations.

The purpose of this project is to provide uniformity in the landscape of all possible integrations and promote charm interoperability.
The purpose of this project is to provide uniformity in the landscape of all possible relations and promote charm interoperability.

Juju interfaces are untyped, which means that for juju to think two charms can be integrated all it looks at is whether the interface names of the two endpoints you're trying to connect are the same string. But it might be that the two charms have different, incompatible implementations of two different integrations that happen to have the same name.
Juju interfaces are untyped, which means that for juju to think two charms can be integrated all it looks at is whether the interface names of the two endpoints you're trying to connect are the same string. But it might be that the two charms have different, incompatible implementations of two different relations that happen to have the same name.

In order to prevent two separate charms from rolling their own integration with the same name, and prevent a sprawl of many subtly different interfaces with similar semantics and similar purposes, we introduced `charm-relation-interfaces`.
In order to prevent two separate charms from rolling their own relation with the same name, and prevent a sprawl of many subtly different interfaces with similar semantics and similar purposes, we introduced `charm-relation-interfaces`.

## Using `charm-relation-interfaces`

Expand Down Expand Up @@ -37,7 +37,6 @@ For each interface, the charm-relation-interfaces repository hosts:


## Charm relation interfaces in Charmhub
In the future, Charmhub will have a searchable collection of integration interfaces.
Charmhub will, for all charms using the interface, verify that they implement it correctly (regardless of whether they use the 'official' implementation or they roll their own) in order to give the charm a happy checkmark on `charmhub.io`. In order to do that it will need to fetch the specification (from `charm-relation-interfaces`) *and* the charm repo, because we can't know what implementation they are using: we need the source code.


Expand Down
2 changes: 1 addition & 1 deletion docs/explanation/interface-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Interface tests are tests that verify the compliance of a charm with an interface specification.
Interface specifications, stored in {ref}`charm-relation-interfaces <charm-relation-interfaces>`, are contract definitions that mandate how a charm should behave when integrated with another charm over a registered interface.

Interface tests will allow `charmhub` to validate the integrations of a charm and verify that your charm indeeed supports "the" `ingress` interface and not just an interface called "ingress", which happens to be the same name as "the official `ingress` interface v2" as registered in charm-relation-interfaces (see [here](https://github.com/canonical/charm-relation-interfaces/tree/main/interfaces/ingress/v2)).
Interface tests will allow `charmhub` to validate the relations of a charm and verify that your charm indeeed supports "the" `ingress` interface and not just an interface called "ingress", which happens to be the same name as "the official `ingress` interface v2" as registered in charm-relation-interfaces (see [here](https://github.com/canonical/charm-relation-interfaces/tree/main/interfaces/ingress/v2)).

Also, they allow alternative implementations of an interface to validate themselves against the contractual specification stored in charm-relation-interfaces, and they help verify compliance with multiple versions of an interface.

Expand Down
2 changes: 1 addition & 1 deletion docs/explanation/storedstate-uses-limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def some_event_handler(event):
return
```

In the other cases where state is needed, authors ideally want to relate a charm to a database, attach storage (see Juju storage), or simply be opinionated, and hard code the single "correct" state into the charm. (Perhaps `ExampleBlog` should always be run in `production` mode when deployed as a charm?)
In the other cases where state is needed, authors ideally want to integrate a charm with a database, attach storage (see Juju storage), or simply be opinionated, and hard code the single "correct" state into the charm. (Perhaps `ExampleBlog` should always be run in `production` mode when deployed as a charm?)

> See more: {external+juju:ref}`Juju Storage <manage-storage>`

Expand Down
2 changes: 1 addition & 1 deletion docs/explanation/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Integration tests typically take significantly longer to run than unit tests.
**Coverage.**

* Charm actions
* Charm integrations
* Charm relations
* Charm configurations
* That the workload is up and running, and responsive
* Upgrade sequence
Expand Down
8 changes: 4 additions & 4 deletions docs/howto/get-started-with-charm-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ The "inputs" of a charm run are therefore:
- integration (relation) data
- stored state

Only the event context is guaranteed to be present. The other input sources are optional, but typically a charm will have at least some config and a few integrations adding to its inputs.
Only the event context is guaranteed to be present. The other input sources are optional, but typically a charm will have at least some config and a few relations adding to its inputs.

The charm code executes and typically produces side-effects aimed at its workload (for example: it writes files to a disk, runs commands on a system, or reconfigures a process) or at other charms it integrates with (for example: it writes relation data). We call this 'operating' a workload, and that is what a charm is meant to do. The ways in which a charm operates can be roughly categorised as:

Expand Down Expand Up @@ -115,7 +115,7 @@ When you instantiate `Context` and `State` objects, the charm instance does not
The `Context` provides methods for all the Juju events. For example:

- the cloud admin changes the charm config: `ctx.on.config_changed()`
- the cloud admin relates this charm to some other: `ctx.on.relation_created(relation)`
- the cloud admin integrates this charm with some other: `ctx.on.relation_created(relation)`
- a remote unit joins in a relation (for example, because the cloud admin has scaled up a remote charm): `ctx.on.relation_joined(relation)`
- a remote unit touches its relation data: `ctx.on.relation_changed(relation)`
- a cloud admin removes a relation: `ctx.on.relation_departed(relation)`
Expand Down Expand Up @@ -177,7 +177,7 @@ Things you typically want to test with integration tests:
- The charm can be deployed (i.e. `juju deploy ./packed_charm.charm` deploys an application that reaches `active` or `waiting` within a reasonable time frame)

These are 'smoke tests' that should always be present, and are provided for you when using `charmcraft init`. The following are non-smokey, proper integration tests.
- The charm can be related to other applications without erroring
- The charm can be integrated with other applications without erroring
- and the relation has the expected effect on the charm's operation logic
- The charm can be configured
- and the config has the expected effect on the charm's operation logic
Expand Down Expand Up @@ -208,7 +208,7 @@ async def test_operation(ops_test: OpsTest):
app: Application = ops_test.model.applications.get("tester")
await app.set_config({"my-key": "my-value"})

# Add another charm and relate them:
# Add another charm and integrate them:
await ops_test.model.deploy('other-app')
await ops_test.model.relate('tester:endpoint1', 'other-charm:endpoint2')

Expand Down
2 changes: 1 addition & 1 deletion docs/howto/manage-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def test_my_object_data(context, endpoint, n_relations):

Fetch the library.

In your `src/charm.py`, observe the custom events it puts at your disposal. For example, a database library may have provided a `database_relation_ready` event -- a high-level wrapper around the relevant `juju` relation events -- so you use it to manage the database integration in your charm as below:
In your `src/charm.py`, observe the custom events it puts at your disposal. For example, a database library may have provided a `database_relation_ready` event -- a high-level wrapper around the relevant `juju` relation events -- so you use it to manage the database relation in your charm as below:

```python

Expand Down
4 changes: 2 additions & 2 deletions docs/howto/manage-relations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# How to manage relations
> See first: {external+juju:ref}`Juju | Relation <relation>`, {external+juju:ref}`Juju | Manage relations <manage-relations>`, {external+charmcraft:ref}`Charmcraft | Manage relations <manage-relations>`
To add integration capabilities to a charm, you’ll have to define the relation in your charm’s charmcraft.yaml file and then add relation event handlers in your charm’s `src/charm.py` file.
To add relation capabilities to a charm, you’ll have to define the relation in your charm’s charmcraft.yaml file and then add relation event handlers in your charm’s `src/charm.py` file.

## Implement the feature

Expand Down Expand Up @@ -65,7 +65,7 @@ Other than this, implement a subordinate relation in the same way as any other r

#### Using a charm library

For most integrations, you will now want to progress with using the charm library recommended by the charm that you are integrating with. Read the documentation for the other charm on Charmhub and follow the instructions, which will typically involve adding a requirer object in your charm’s `__init__` and then observing custom events.
For most relations, you will now want to progress with using the charm library recommended by the charm that you are integrating with. Read the documentation for the other charm on Charmhub and follow the instructions, which will typically involve adding a requirer object in your charm’s `__init__` and then observing custom events.

In most cases, the charm library will handle observing the Juju relation events, and your charm will only need to interact with the library’s custom API. Come back to this guide when you are ready to add tests.

Expand Down
2 changes: 1 addition & 1 deletion docs/howto/write-integration-tests-for-a-charm.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ For `oci-images` you can reference an image registry.

### Test a relation

To test an integration between two applications, you can just integrate them through
To test a relation between two applications, integrate them through
the model. Both applications have to be deployed beforehand.

```
Expand Down
2 changes: 1 addition & 1 deletion docs/howto/write-unit-tests-for-a-charm.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ harness.charm.unit.status = BlockedStatus("Testing")
Any of your charm’s properties and methods (including event callbacks) can be accessed using
`harness.charm`. You can check out the [harness API
docs](ops_testing_harness) for more ways to use the
harness to trigger other events and to test your charm (e.g. triggering leadership-related events,
harness to trigger other events and to test your charm (e.g. triggering events regarding leadership,
testing pebble events and sidecar container interactions, etc.).


Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The library provides:
- {ref}`ops_testing`, the recommended API for unit testing charms
- {ref}`ops_testing_harness`, the deprecated API for unit testing charms

You can structure your charm however you like, but with the `ops` library, you get a framework that promotes consistency and readability by following best practices. It also helps you organise your code better by separating different aspects of the charm, such as managing the application's state, handling integrations with other services, and making the charm easier to test.
You can structure your charm however you like, but with the `ops` library, you get a framework that promotes consistency and readability by following best practices. It also helps you organise your code better by separating different aspects of the charm, such as managing the application's state, handling integrating with other services, and making the charm easier to test.


---------
Expand Down
6 changes: 3 additions & 3 deletions docs/reference/ops-testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Juju state all at once, define the Juju context against which to test the charm,
and fire a single event on the charm to execute its logic. The tests can then
assert that the Juju state has changed as expected.

A very simple test, where the charm has no config, no integrations, the unit
A very simple test, where the charm has no config, no relations, the unit
is the leader, and has a `start` handler that sets the status to active might
look like this:

Expand All @@ -38,8 +38,8 @@ Writing these tests should nudge you into thinking of a charm as a black-box
'input to output' function. The inputs are:

- Event: why am I, the charm, being executed
- State: am I the leader? what is my integration data? what is my config?
- Context: what integrations can I have? what containers can I have?
- State: am I the leader? what is my relation data? what is my config?
- Context: what relations can I have? what containers can I have?

The output is another `State`: the state after
the charm has interacted with the mocked Juju model.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ title: |
demo-fastapi-k8s
description: |
This is a demo charm built on top of a small Python FastAPI server.
This charm could be related to PostgreSQL charm and COS Lite bundle (Canonical Observability Stack).
This charm could be integrated with the PostgreSQL charm and COS Lite bundle (Canonical Observability Stack).
summary: |
FastAPI Demo charm for Kubernetes
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Well done, you've got everything you need to set up a database relation!
## Define the charm relation interface

<!--
Charm integration interfaces are described in the `charmcraft.yaml` file. To connect to the PostgreSQL charm, we will need to find out the name of the interface that PostgreSQL exposes so other charms can connect to it and then update our `charmcraft.yaml` file.
Charm relation interfaces are described in the `charmcraft.yaml` file. To connect to the PostgreSQL charm, we will need to find out the name of the interface that PostgreSQL exposes so other charms can connect to it and then update our `charmcraft.yaml` file.
-->

Now, time to define the charm relation interface.
Expand Down Expand Up @@ -243,12 +243,12 @@ def _on_database_created(self, event: DatabaseCreatedEvent) -> None:
self._update_layer_and_restart()
```

The diagram below illustrates the workflow for the case where the database integration exists and for the case where it does not:
The diagram below illustrates the workflow for the case where the database relation exists and for the case where it does not:

![Integrate your charm with PostgreSQL](../../resources/integrate_your_charm_with_postgresql.png)


## Update the unit status to reflect the integration state
## Update the unit status to reflect the relation state

Now that the charm is getting more complex, there are many more cases where the unit status needs to be set. It's often convenient to do this in a more declarative fashion, which is where the collect-status event can be used.

Expand Down Expand Up @@ -322,7 +322,7 @@ Now, integrate our charm with the newly deployed `postgresql-k8s` charm:
juju integrate postgresql-k8s demo-api-charm
```

> Read more: [Integration](https://juju.is/docs/olm/integration), [`juju integrate`](https://juju.is/docs/olm/juju-integrate)
> Read more: {external+juju:ref}`Juju | Relation (integration) <relation>`, [`juju integrate`](inv:juju:std:label#command-juju-integrate)


Finally, run:
Expand Down Expand Up @@ -379,7 +379,7 @@ This should produce something similar to the output below (of course, with the n
{"names":{"1":"maksim","2":"simon"}}
```

Congratulations, your integration with PostgreSQL is functional!
Congratulations, your relation with PostgreSQL is functional!

## Review the final code

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Note: When you rebuild your charm with `charmcraft pack`, Charmcraft will copy t

### Define the Prometheus relation interface

In your `charmcraft.yaml` file, before the `peers` block, add a `provides` endpoint with relation name `metrics-endpoint` and interface name `prometheus_scrape`, as below. This declares that your charm can offer services to other charms over the `prometheus-scrape` interface. In short, that your charm is open to integrations with, for example, the official Prometheus charm. (Note: `metrics-endpoint` is the default relation name recommended by the `prometheus_scrape` interface library.)
In your `charmcraft.yaml` file, before the `peers` block, add a `provides` endpoint with relation name `metrics-endpoint` and interface name `prometheus_scrape`, as below. This declares that your charm can offer services to other charms over the `prometheus-scrape` interface. In short, that your charm is open to integrating with, for example, the official Prometheus charm. (Note: `metrics-endpoint` is the default relation name recommended by the `prometheus_scrape` interface library.)

```yaml
provides:
Expand Down Expand Up @@ -139,7 +139,7 @@ Note: When you rebuild your charm with `charmcraft pack`, Charmcraft will copy t

### Define the Loki relation interface

In your `charmcraft.yaml` file, beneath your existing `requires` endpoint, add another `requires` endpoint with relation name `log-proxy` and interface name `loki_push_api`. This declares that your charm can optionally make use of services from other charms over the `loki_push_api` interface. In short, that your charm is open to integrations with, for example, the official Loki charm. (Note: `log-proxy` is the default relation name recommended by the `loki_push_api` interface library.)
In your `charmcraft.yaml` file, beneath your existing `requires` endpoint, add another `requires` endpoint with relation name `log-proxy` and interface name `loki_push_api`. This declares that your charm can optionally make use of services from other charms over the `loki_push_api` interface. In short, that your charm is open to integrating with, for example, the official Loki charm. (Note: `log-proxy` is the default relation name recommended by the `loki_push_api` interface library.)


```yaml
Expand Down Expand Up @@ -203,7 +203,7 @@ Note: The `grafana_dashboard` library also depends on the [`juju_topology`](htt

### Define the Grafana relation interface

In your `charmcraft.yaml` file, add another `provides` endpoint with relation name `grafana-dashboard` and interface name `grafana_dashboard`, as below. This declares that your charm can offer services to other charms over the `grafana-dashboard` interface. In short, that your charm is open to integrations with, for example, the official Grafana charm. (Note: Here `grafana-dashboard` endpoint is the default relation name recommended by the `grafana_dashboard` library.)
In your `charmcraft.yaml` file, add another `provides` endpoint with relation name `grafana-dashboard` and interface name `grafana_dashboard`, as below. This declares that your charm can offer services to other charms over the `grafana-dashboard` interface. In short, that your charm is open to integrating with, for example, the official Grafana charm. (Note: Here `grafana-dashboard` endpoint is the default relation name recommended by the `grafana_dashboard` library.)

```yaml
provides:
Expand Down Expand Up @@ -287,9 +287,9 @@ juju deploy cos-lite --trust
```


### Expose the application integration endpoints
### Expose the application relation endpoints

Once all the COS Lite applications are deployed and settled down (you can monitor this by using `juju status --watch 2s`), expose the integration points you are interested in for your charm -- `loki:logging`, `grafana-dashboard`, and `metrics-endpoint` -- as below.
Once all the COS Lite applications are deployed and settled down (you can monitor this by using `juju status --watch 2s`), expose the relation points you are interested in for your charm -- `loki:logging`, `grafana-dashboard`, and `metrics-endpoint` -- as below.

```text
juju offer prometheus:metrics-endpoint
Expand Down
Loading

0 comments on commit 8f25088

Please sign in to comment.