Writing a JUJU Charm

  • SHARE

Writing a JUJU Charm

OSS Education

6 Minute read, Published: 26th February 2018

  • SHARE

How to Write a Charm for Juju

In the previous article we knew what juju and a charm is and how to use juju for charm deployments. Let us discuss how we write a custom charm to deploy on juju.

A charm is a collection of YAML files and hook files. The yaml files contain the configurations, configurable variables, and the meta data about your charm. And the hooks files contain the scripts which actually perform the action behind the scene. These hook files can be written in any programming language which can be run through the terminal like pear, python, bash etc. There are some additional files such as README, copyright and icon files to further support your charm.

Directory Structure for charm

You need to maintain a proper directory structure for writing a charm.

sudo apt-get install charm-tools
cd ~
mkdir -p charms/precise
cd charms/precise

Now the charm tools plugin comes in handy and creates a dummy charm for you with all the requisite files (with dummy content)

charm-create example-charm

you can see the file structure by using the tree command. The output generated is

-- example
    |-- config.yaml
    |-- hooks
    |   |-- config-changed
    |   |-- install
    |   |-- relation-name-relation-broken
    |   |-- relation-name-relation-changed
    |   |-- relation-name-relation-departed
    |   |-- relation-name-relation-joined
    |   |-- start
    |   |-- stop
    |   `-- upgrade-charm
    |-- icon.svg
    |-- metadata.yaml
    |-- README.ex

Lets have a look at each of these files separately.

1. metadata.yaml

This file contains the information about your charm. It will be pretty clear from the content of the file itself.

name: example
summary: <Fill in summary here>
maintainer: root <root@saurabh-oVirt-Node>
description: |
  <Multi-line description here>
categories:
  - misc
subordinate: false
provides:
  provides-relation:
    interface: interface-name
requires:
  requires-relation:
    interface: interface-name
peers:
  peer-relation:
    interface: interface-name

You can remove the parameters which are not required for your purpose.

categories

You need to define any one category with correspondence to what your charm does/provides. These are categories considered by juju:

  • databases – MySQL, PostgreSQL, CouchDB, etc.
  • file-servers – storage apps such as Ceph
  • applications -applications like MediaWiki, WordPress
  • cache-proxy – services such as HAProxy and Varnish.
  • app-servers – infrastructure services like Apache  Tomcat and Jboss
  • miscellaneous – anything which doesn’t neatly fit anywhere above.

2. config.yaml

This file contains the configurable variables. The author can set the default values. But once the charm is deployed the user has the capability to override the defaults which are configured in this file.

Generally User-names, Passwords, ports are defined in this file. You can define as many variables as you want to be configurable by the user.

sample content of this file:

options:
  string-option:
    type: string
    default: "Default Value"
    description: "A short description of the configuration option"
  boolean-option:
    type: boolean
    default: False
    description: "A short description of the configuration option"
  int-option:
    type: int
    default: 9001
    description: "A short description of the configuration option"

Hook files explained

Each and every hook file must have the execute permission. when ever you create a hook file add the execute permission to that hook.

 chmod +x hook_name

Each and every hook should be idempotent to each other. In a simpler word every file should be independent from each other so that executing one file should not corrupt the configuration done by any other hook files.

3. install hook

When a charm is deployed the install hook is the first file that is executed by juju. This file contains the script which are run with a privilege of root user. The aim of this script file is to download and configure the application that your juju is intended to deliver. It is highly recommended that you install the applications using the “apt”. If the application is not available in apt repository. You can modify your install hook to download the application from internet but you need to cryptographically verify that the file is not damaged or tampered.

4. config-changed hook

This is the second hook file that is executed by juju There are various instances when this file is run

  • Right after the install hook. When install hook is run the state of your charm changes hence this file is run.
  • when the variables in config.yaml are set by user
  • when any config change happens such as upgrade or when any relation is broken.

5. start hook

This is a very simple file, it is run third in the sequence by juju when any charm is deployed. This hook contains the script to start the installed application.

sample content would be like

 
#!/bin/bash

set -e

/etc/init.d/service-daemon start

6. relation-joined hook

This hook is run when some other charm service has joined your charm service. The relation to be joined must be defined in the metadata.yaml file.

7. relation-changed hook

It is always run once, after -joined, and will subsequently be run whenever that remote unit changes its settings for the relation. It should be the only hook that relies upon remote relation settings from relation-get, and it should not error if the settings are incomplete: you can guarantee that when the remote unit changes its settings, the hook will be run again. This hook is run after the relation is joined and when the relation is destroyed. So the configuration done in this file must be idempotent and should not affect the application apart from the relation change.

8. relation-departed hook

It is run once only, when the remote unit is known to be leaving the relation; it will only run once at least one -changed has been run, and after -departed has run, no further -changes will be run. This should be used to remove all references to the remote unit, because there’s no guarantee that it’s still part of the system; it’s perfectly probable (although not guaranteed) that the system running that unit has already shut down.

9. relation-broken hook

indicates that the current relation is no longer valid, and that the charm’s software must be configured as though the relation had never existed. It will only be called after every necessary -departed hook has been run; if it’s being executed, you can be sure that no remote units are currently known locally.

10. stop hook

This hook runs when a unit is destroyed or stopped. This file contains the script to stop the service which is deployed by the charm.

Conclusion:

We hope this post was able to explain Juju to an understandable extent, still if we left something or you want us to cover something extra please post your suggestions in the comment and we will surely take them in our consideration.

Similar articles