This guide covers three main topics for the when writing a charm: preparing the environment, the code and being able to develop it iteratively.
To ease the development, we suggest you to setup a microk8s environment by running:
snap install juju --classic snap install microk8s --classic microk8s enable dns hostpath-storage juju bootstrap microk8s micro juju add-model my-charm-model
At this point you have a controller named “micro” in the “microk8s” cloud. This cloud is actually your local machine, how neat! In Juju, you interact with the client (the juju command on your local machine). It connects to a controller. The controller is hosted on a cloud and controls models.
To get you started with the actual first lines of your charm charmcraft has a
init command, so run:
sudo snap install charmcraft --classic mkdir mycharm cd mycharm charmcraft init --name=mycharm
From here on consider that you are in the
mycharm directory. At this point this charm although simple is fully functional. The core of the charm code is in
src/charm.py. You can build and deploy it on your microk8s cloud as following:
charmcraft pack juju deploy ./mycharm_ubuntu-20.04-amd64.charm --resource httpbin-image=kennethreitz/httpbin
It may take a while to have the deployment finished, in the meantime you can check the status by running:
You just made a change on the source code of your
charm.py. In order to apply it, rebuild and upgrade the charm:
charmcraft pack juju upgrade-charm --path="./mycharm.charm" my-charm-model --force-units
Or, if for some reason you want to start from scratch, you can clean up things on different levels, application, model, and controller:
# "mycharm" is the name of the application in the next command, # which is in "name: mycharm" tag inside metadata.yaml juju remove-application mycharm --force --no-wait juju destroy-model my-charm-model --destroy-storage --force --no-wait juju destroy-controller micro --destroy-all-models
After applying those changes you want to see their effect. Juju logs are handy. First, enable them so that you can see if something fails and a stacktrace is shown or if you add custom log messages. In order to enable
TRACE level at the unit to make everything shows:
juju model-config logging-config="<root>=WARNING;unit=TRACE"
To show the logs for a specific mode:
juju debug-log -m my-charm-model
To show the logs for all the units in the model:
microk8s kubectl get all --namespace=my-charm-model
To see the logs for a specific pod:
microk8s kubectl --namespace=my-charm-model logs mycharm-0
If you are curious on how other existing operators are implemented refer to the source code of the MongoDB and Elasticsearch operators for inspiration on other topics such as relation, replication and lifecycle management.
If still in doubt you can ask questions about the operator framework. There are multiple communication channels.