The example below will walk through the creation of a basic API charm for the Openstack Congress service. The charm will use prewritten Openstack layers and interfaces. Once the charm is written it will be composed using charm tools. For more details of the internal of a charm see Charm Anatomy.
Before writing a new charm the charm author needs to have a clear idea of what applications the charm is going to need to relate to, what files and services the charm is going to manage and possibly what files or services do other charms manage that need updating.
The Congress service needs to register endpoints with Keystone. It needs a service username and password and it also needs a MySQL backend to store its schema.
The charm-tools package and charm-templates-openstack python module are both needed to construct the charm from a template and to build the resulting charm.
sudo apt-get install charm-tools python-jinja2
mkdir ~/congress-charm
cd ~/congress-charm
git clone git@github.com:openstack-charmers/charm-templates-openstack.git
cd charm-templates-openstack
sudo ./setup.py install
Charm tools provides a utility for building an initial charm from a template. The charm can be thought of as the top layer, the OpenStack layers sit beneath it and the reactive base layer is at the bottom.
During the charm generation charm tools asks a few questions about the charm.
cd ~/congress-charm
charm-create -t openstack-api congress
All the questions are optional, below are the responses for Congress.
What port does the primary service listen on ? 1789
What is the name of the api service? congress-server
What type of service is this (used for keystone registration)? congress
What is the earliest OpenStack release this charm is compatible with? mitaka
Where command is used to sync the database? congress-db-manage --config-file /etc/congress/congress.conf upgrade head
What packages should this charm install (space seperated list)? congress-server congress-common python-antlr3 python-pymysql
List of config files managed by this charm (space seperated) /etc/congress/congress.conf
What is the name of the init script which controls the primary service congress-server
The charm code searches through the templates directories looking for a directory corresponding to the OpenStack release being installed or earlier. Since Mitaka is the earliest release the charm is supporting a directory called mitaka will house the templates and files.
A template for congress.conf is needed which will have have connection information for MySQL and Keystone as well as user controllable config options. Create ~/congress-charm/congress/src/templates/mitaka/congress.conf with the following contents:
[DEFAULT]
bind_host = {{ options.service_listen_info.congress_server.ip }}
bind_port = {{ options.service_listen_info.congress_server.port }}
auth_strategy = keystone
drivers = congress.datasources.neutronv2_driver.NeutronV2Driver,congress.datasources.glancev2_driver.GlanceV2Driver,congress.datasources.nova_driver.NovaDriver,congress.datasources.keystone_driver.KeystoneDriver,congress.datasources.ceilometer_driver.CeilometerDriver,congress.datasources.cinder_driver.CinderDriver,congress.datasources.swift_driver.SwiftDriver,congress.datasources.plexxi_driver.PlexxiDriver,congress.datasources.vCenter_driver.VCenterDriver,congress.datasources.murano_driver.MuranoDriver,congress.datasources.ironic_driver.IronicDriver
[database]
connection = {{ shared_db.uri }}
{% include "parts/section-keystone-authtoken" %}
The charm now needs to be built to pull down all the interfaces and layers the charm depends on and rolled into the built charm which can be deployed.
cd ~/congress-charm/congress
charm build -o build src
Asumming that an OpenStack cloud is already deployed, add the new Congress charm.
juju deploy ~/congress-charm/congress/build/builds/congress
juju add-relation congress keystone
juju add-relation congress rabbitmq-server
juju add-relation congress mysql
juju status will show the deployment as it proceeds.
$ openstack catalog show congress
+-----------+---------------------------------------+
| Field | Value |
+-----------+---------------------------------------+
| endpoints | RegionOne |
| | publicURL: http://10.5.3.128:1789 |
| | internalURL: http://10.5.3.128:1789 |
| | adminURL: http://10.5.3.128:1789 |
| | |
| name | congress |
| type | policy |
+-----------+---------------------------------------+
$ openstack congress policy list
+--------------------------------------+----------------+----------+--------------+-----------------------+
| id | name | owner_id | kind | description |
+--------------------------------------+----------------+----------+--------------+-----------------------+
| 0801bffe-acd0-4644-adab-12321efa0aaf | classification | user | nonrecursive | default policy |
| 38e375ec-b769-45e6-89ad-9eb62da85c57 | action | user | action | default action policy |
+--------------------------------------+----------------+----------+--------------+-----------------------+
Another unit can be added to the application to share the workload.
juju add-unit congress
Juju now shows two units of the Congress application.
$ juju status congress --format=oneline
- congress/1: 10.5.3.128 (agent:idle, workload:active)
- congress/2: 10.5.3.129 (agent:idle, workload:active)
The charm configures an instance of haproxy on each unit of the application. Haproxy has all the backends registered within it and load balances traffic across them.
$ juju ssh congress/1 "tail -11 /etc/haproxy/haproxy.cfg"
frontend tcp-in_congress-server_admin
bind \*:1789
acl net_10.5.3.128 dst 10.5.3.128/255.255.0.0
use_backend congress-server_admin_10.5.3.128 if net_10.5.3.128
default_backend congress-server_admin_10.5.3.128
backend congress-server_admin_10.5.3.128
balance leastconn
server congress-2 10.5.3.129:1779 check
server congress-1 10.5.3.128:1779 check
However, the congress endpoint registered in Keystone is still 10.5.3.128, so if congress/1 dies clients will fail to connect unless they explicitly set congress url. To fix this a Congress VIP can be registered in Keystone and the VIP floated across the Congress units using the hacluster charm.
The hacluster charm can manage a VIP which is registered with keystone. In the event of a unit failure the VIP fails over to another application unit and clients can continue without having to amend their clients.
The congress charm exposes a vip and vip_cidr config options which it passes to the hacluster charm when the two are joined.
juju deploy hacluster
juju set-config congress vip=10.5.100.1 vip_cidr=24
juju add-relation hacluster congress
Juju status now reflects the new charms
$ juju status congress --format=oneline
- congress/1: 10.5.3.128 (agent:idle, workload:active)
- hacluster/0: 10.5.3.128 (agent:idle, workload:active)
- congress/2: 10.5.3.129 (agent:idle, workload:active)
- hacluster/1: 10.5.3.129 (agent:idle, workload:active)
Querying keystone now shows the VIP being used for the congress endpoint, and the congress client still works unaltered.
$ openstack catalog show congress
+-----------+---------------------------------------+
| Field | Value |
+-----------+---------------------------------------+
| endpoints | RegionOne |
| | publicURL: http://10.5.100.1:1789 |
| | internalURL: http://10.5.100.1:1789 |
| | adminURL: http://10.5.100.1:1789 |
| | |
| name | congress |
| type | policy |
+-----------+---------------------------------------+
$ openstack congress policy list
+--------------------------------------+----------------+----------+--------------+-----------------------+
| id | name | owner_id | kind | description |
+--------------------------------------+----------------+----------+--------------+-----------------------+
| 0801bffe-acd0-4644-adab-12321efa0aaf | classification | user | nonrecursive | default policy |
| 38e375ec-b769-45e6-89ad-9eb62da85c57 | action | user | action | default action policy |
+--------------------------------------+----------------+----------+--------------+-----------------------+
The template assumes that the charm will be covered by the Apache 2.0 License. If another license is to be used please review the copyright files.
The src/metadata.yaml describes the charm. Update the description and tags in here.
Push charm up to your namespace in the charmstore:
cd ~/congress-charm/congress/build
charm push . cs:~<lp-usrname>/xenial/congress
To make the charm available to others:
charm grant cs:~<lp-usrname>/xenial/congress everyone