forked from canonical/operator
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d54a26a
commit 2fca48c
Showing
5 changed files
with
170 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
(how-to-manage-charms)= | ||
# How to manage charms | ||
|
||
> See first: {external+juju:ref}`Juju | How to manage charms or bundles <manage-charms>` | ||
The primary programming language charms are written in is Python, and the | ||
primary framework for developing charms is the Python Operator Framework, or | ||
`ops`. | ||
|
||
`charmcraft init` provides you with a `src/charm.py` file that demonstrates the | ||
basis of using the library. | ||
|
||
```python | ||
# Import ops and use names from there. | ||
import ops | ||
|
||
# Charms always have a class that inherits from ops.CharmBase that define the | ||
# charm's functionality. | ||
class MyCharm(ops.CharmBase): | ||
# There's always an __init__ method that sets up observers. | ||
def __init__(self, framework: ops.Framework): | ||
super().__init__(framework) | ||
framework.observe(...) | ||
|
||
# There will always be one or more event handlers that will be called in | ||
# response to a Juju, ops, or custom event. | ||
# Note that this has a leading underscore. These methods should only be | ||
# called by the ops framework, so should not be public. | ||
def _my_event_handler(self, event: ops.EventBase): # or a more specific type | ||
... | ||
self.unit.status = ops.ActiveStatus() | ||
|
||
# Finally, the charm.py file always ends with a call to ops.main, passing in the | ||
# charm class. | ||
if __name__ == "__main__": | ||
ops.main(MyCharm) | ||
``` | ||
|
||
## Interacting with the workload | ||
|
||
For simple interactions with an application or service or when a high quality | ||
Python binding is not available, subprocess or API calls should be used to | ||
perform the required operations on the application or service. | ||
|
||
TODO: Create a `src/{workload}.py` file for each workload or service that your charm | ||
is managing, and ... For example: | ||
|
||
```python | ||
import subprocess | ||
|
||
try: | ||
# Comment to explain why subprocess is used. | ||
result = subprocess.run( | ||
# Array based execution. | ||
["/usr/bin/echo", "hello world"], | ||
capture_output=True, | ||
check=True, | ||
) | ||
logger.debug("Command output: %s", result.stdout) | ||
except subprocess.CalledProcessError as err: | ||
logger.error("Command failed with code %i: %s", err.returncode, err.stderr) | ||
raise | ||
``` | ||
|
||
```{admonition} Best Practice | ||
:class: hint | ||
Limit the use of shell scripts and commands as much as possible in favour of | ||
writing Python for charm code. Examples where it could be reasonable to use a | ||
script include: extracting data from a machine or container which can't be | ||
obtained through Python; or issuing commands to applications that do not have | ||
Python bindings (such as starting a process on a machine). | ||
``` | ||
|
||
## Base / Python | ||
|
||
Charms have access to the default Python version in the Ubuntu release defined | ||
as the base. | ||
|
||
Your code should be compatible with the operating system and Juju versions it | ||
will be executed on. For example, if your charm is to be deployed with Juju 3.6, | ||
its Python code should be compatible with Python 3.8. | ||
|
||
TODO: put in the relevant bits in pyproject.toml to have tools recognise this. | ||
|
||
TODO: can we be more detailed, or link to something here that says which Ubuntu | ||
has which Python, and which base you should support? | ||
|
||
## Dependencies | ||
|
||
TODO: put in instructions for dependencies from the spec (pyproject, generate requirements.txt) | ||
|
||
TODO: instructions on putting libs in charmcraft.yaml and running fetch-libs and then keeping that updated. | ||
|
||
> See more: charmcraft.yaml, charmcraft fetch-libs | ||
```{admonition} Best Practice | ||
:class: hint | ||
Including an external dependency in a charm is a significant choice. It can help | ||
with reducing the complexity and development cost. However, every additional | ||
dependency increases the risk for supply chain security issues, the maintenance | ||
burden of having to manage the dependencies, and makes it more difficult to | ||
completely understand all of the code involved in the charm. | ||
``` | ||
|
||
> See more: [The software dependency issue](https://research.swtch.com/deps) | ||
TODO: is that still the article we want to link to? There are a lot on this problem. | ||
|
||
## Events | ||
|
||
TODO: There are Juju events, ops events, and custom events. A bit more about how to | ||
respond to each of these, probably mostly linking out. | ||
|
||
> See also: Juju events, something about the ops events. | ||
```{admonition} Best Practice | ||
:class: hint | ||
Custom events are defined and emitted by charm libraries. Charms should never | ||
define or emit custom events themselves. | ||
``` | ||
|
||
> See more: manage libraries | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters