Merge ~cjwatson/launchpad:doc-charm-workflow into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 8d4da17eecc3b85ec4e1cee9b983f18ff6af4081
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:doc-charm-workflow
Merge into: launchpad:master
Diff against target: 141 lines (+115/-1)
3 files modified
doc/conf.py (+1/-1)
doc/explanation/charms.rst (+113/-0)
doc/explanation/index.rst (+1/-0)
Reviewer Review Type Date Requested Status
Simone Pelosi Approve
Review via email: mp+439223@code.launchpad.net

Commit message

doc: Add explanation of charm development

Description of the change

This is doubtless incomplete, but I thought I'd at least get everything I could immediately think of written down as a starting point for others.

To post a comment you must log in.
Revision history for this message
Simone Pelosi (pelpsi) wrote :

LGTM!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/doc/conf.py b/doc/conf.py
2index f43f4fd..3f6130a 100644
3--- a/doc/conf.py
4+++ b/doc/conf.py
5@@ -38,7 +38,7 @@ master_doc = "index"
6
7 # General information about the project.
8 project = "Launchpad"
9-copyright = "2004-2022, Canonical Ltd."
10+copyright = "2004-2023, Canonical Ltd."
11
12 # The version info for the project you're documenting, acts as replacement for
13 # |version| and |release|, also used in various other places throughout the
14diff --git a/doc/explanation/charms.rst b/doc/explanation/charms.rst
15new file mode 100644
16index 0000000..6fe52d3
17--- /dev/null
18+++ b/doc/explanation/charms.rst
19@@ -0,0 +1,113 @@
20+=================
21+Charm development
22+=================
23+
24+The direction of our official deployments is to use `Juju charms
25+<https://juju.is/docs/sdk>`_. (We still have a number of manually-deployed
26+systems, so we aren't there yet.)
27+
28+To get an overview of how this works, you'll need to look in the ``charm/``
29+directory of Launchpad itself, as well as `ols-layers
30+<https://git.launchpad.net/ols-charm-deps>`_, `launchpad-layers
31+<https://git.launchpad.net/launchpad-layers>`_, and `launchpad-mojo-specs
32+<https://git.launchpad.net/launchpad-mojo-specs>`_. Each of the
33+subdirectories of ``charm/`` represents a single logical function which can
34+be deployed as a Juju `application <https://juju.is/docs/olm/application>`_
35+with one or more `units <https://juju.is/docs/olm/unit>`_. The layers
36+provide common code used by multiple charms. The specs are used with `Mojo
37+<https://mojo.canonical.com/>`_ to coordinate whole deployments of multiple
38+applications; they contain configuration of individual applications and
39+`integrations <https://juju.is/docs/olm/integration>`_ between applications.
40+
41+Principles
42+==========
43+
44+Wherever possible, charm code should live in the same repository as the code
45+it deploys (the payload). This makes it easier to evolve both in parallel.
46+
47+Launchpad is open source. Its charms and its configuration (aside from a
48+small number of necessary secrets) should also be open source. As well as
49+being the right thing to do, this also allows using machinery such as
50+Launchpad's charm recipes that upload to `Charmhub <https://charmhub.io/>`_.
51+When used in combination with Charmhub, Juju can easily be instructed to
52+upgrade charms and update configuration using a single `bundle
53+<https://juju.is/docs/olm/bundle>`_, allowing the top-level spec to be
54+relatively simple.
55+
56+Each charm should correspond to a deployment of a single top-level payload.
57+On the other hand, it's fine for a single payload to have multiple charms
58+corresponding to different ways in which it can be deployed: for example,
59+Launchpad itself will have charms for the appservers, buildd-manager,
60+publishers, and so on.
61+
62+If a legacy deployment bundled multiple logical functions onto a single
63+machine purely for economic convenience, don't be afraid to split those up
64+in a way that makes sense. However, there's no need to go to extremes: if
65+multiple cron jobs all have broadly the same system requirements, then we're
66+unlikely to want each cron job to be deployed using its own Juju
67+application.
68+
69+It will not always make sense to expose every single configuration option of
70+the payload directly in the charm. Some configuration options may only
71+exist for internal testing purposes or for backward-compatibility, and some
72+may make sense for the charm to use internally but not expose in ``juju
73+config``. A good rule of thumb is to consider whether a given configuration
74+option needs to differ between deployments; if it doesn't, there's probably
75+no need to expose it.
76+
77+`DRY <https://en.wikipedia.org/wiki/Don%27t_repeat_yourself>`_ applies to
78+configuration as well as code, and can help to avoid gratuitous differences
79+between deployments. `Jinja <https://jinja.palletsprojects.com/>`_
80+templates are widely used in both charms and Mojo specs as part of this.
81+
82+Keep multi-datacentre operation in mind where possible. We don't have
83+enough experience with this yet to know what we'll need to do, but it's
84+likely to involve deploying parts of an application in different datacentres
85+from other parts, so loose coupling will help: for example, it may be useful
86+to allow configuring connections using explicit configuration as well as or
87+instead of Juju integrations.
88+
89+Workflow
90+========
91+
92+You can run test deployments using `Juju <https://juju.is/docs/olm>`_ and
93+`LXD <https://linuxcontainers.org/lxd/introduction/>`_. If you don't
94+already have a suitable testbed, then see the `Juju tutorial
95+<https://juju.is/docs/olm/get-started-with-juju>`_ for how to set one up;
96+you should use the non-Kubernetes approach here.
97+
98+Each Mojo spec has a ``README.md`` file explaining how to deploy it, and
99+that's usually the easiest way to get started. You should normally use the
100+corresponding ``devel`` stage, as that's intended for local deployments: for
101+example, it will normally deploy fewer units, and doesn't assume that parts
102+of Canonical's internal infrastructure will be available.
103+
104+Once you've successfully deployed an environment, you will probably want to
105+iterate on it in various ways. You can build a new charm using ``charmcraft
106+pack`` in the appropriate subdirectory, and then use ``juju refresh`` to
107+upgrade your local deployment to that. You can change configuration items
108+using ``juju config``. Alternatively, you can make a local clone of the
109+Mojo spec and point ``mojo run`` at that rather than at a repository on
110+``git.launchpad.net``, and then you can iterate by changing the spec.
111+
112+Use ``juju debug-log`` and ``juju status`` liberally to observe what's
113+happening as you make changes. See `How to debug a charm
114+<https://juju.is/docs/sdk/debug-a-charm>`_ for more specific advice on that
115+topic.
116+
117+Secrets
118+=======
119+
120+Cryptographic secrets should not be stored in Mojo specs, and nor should
121+some other pieces of information (such as configuration relevant to
122+preventing spam). These are instead stored in a secrets file on the
123+relevant deployment host (``launchpad-bastion-ps5.internal`` or
124+``is-bastion-ps5.internal`` for official deployments), and are updated
125+manually. The ``bundle`` command in the Mojo manifest will have a
126+``local=`` parameter pointing to this file, relative to
127+``$MOJO_ROOT/LOCAL/$MOJO_PROJECT/$MOJO_STAGE``.
128+
129+Managing secrets like this is more cumbersome than updating Mojo specs, so
130+try to keep it to a minimum. In some cases there may be automation
131+available to help, such as the `autocert charm
132+<https://charmhub.io/autocert>`_.
133diff --git a/doc/explanation/index.rst b/doc/explanation/index.rst
134index 9b66e6d..21299fd 100644
135--- a/doc/explanation/index.rst
136+++ b/doc/explanation/index.rst
137@@ -13,3 +13,4 @@ Explanation
138 architecture
139 pip
140 favicon
141+ charms

Subscribers

People subscribed via source and target branches

to status/vote changes: