summaryrefslogtreecommitdiff
path: root/doc/rtd/development/module_creation.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/rtd/development/module_creation.rst')
-rw-r--r--doc/rtd/development/module_creation.rst130
1 files changed, 130 insertions, 0 deletions
diff --git a/doc/rtd/development/module_creation.rst b/doc/rtd/development/module_creation.rst
new file mode 100644
index 00000000..cb46d7cf
--- /dev/null
+++ b/doc/rtd/development/module_creation.rst
@@ -0,0 +1,130 @@
+.. _module_creation:
+
+Module creation
+***************
+
+Much of ``cloud-init``'s functionality is provided by :ref:`modules<modules>`.
+All modules follow a similar layout in order to provide consistent execution
+and documentation. Use the example provided here to create a new module.
+
+Example
+=======
+
+.. code-block:: python
+
+ # This file is part of cloud-init. See LICENSE file for license information.
+ """Example Module: Shows how to create a module"""
+
+ from logging import Logger
+
+ from cloudinit.cloud import Cloud
+ from cloudinit.config import Config
+ from cloudinit.config.schema import MetaSchema, get_meta_doc
+ from cloudinit.distros import ALL_DISTROS
+ from cloudinit.settings import PER_INSTANCE
+
+ MODULE_DESCRIPTION = """\
+ Description that will be used in module documentation.
+
+ This will likely take multiple lines.
+ """
+
+ meta: MetaSchema = {
+ "id": "cc_example",
+ "name": "Example Module",
+ "title": "Shows how to create a module",
+ "description": MODULE_DESCRIPTION,
+ "distros": [ALL_DISTROS],
+ "frequency": PER_INSTANCE,
+ "activate_by_schema_keys": ["example_key, example_other_key"],
+ "examples": [
+ "example_key: example_value",
+ "example_other_key: ['value', 2]",
+ ],
+ }
+
+ __doc__ = get_meta_doc(meta)
+
+
+ def handle(
+ name: str, cfg: Config, cloud: Cloud, log: Logger, args: list
+ ) -> None:
+ log.debug(f"Hi from module {name}")
+
+.. _module_creation-Guidelines:
+
+Guidelines
+==========
+
+* Create a new module in the :file:`cloudinit/config` directory with a ``cc_``
+ prefix.
+* Your module must include a ``handle`` function. The arguments are:
+
+ * ``name``: The module name specified in the configuration.
+ * ``cfg``: A configuration object that is the result of the merging of
+ cloud-config configuration with any datasource-provided configuration.
+ * ``cloud``: A cloud object that can be used to access various datasource
+ and paths for the given distro and data provided by the various datasource
+ instance types.
+ * ``log``: A logger object that can be used to log messages.
+ * ``args``: An argument list. This is usually empty and is only populated
+ if the module is called independently from the command line or if the
+ module definition in :file:`/etc/cloud/cloud.cfg[.d]` has been modified
+ to pass arguments to this module.
+
+* If your module introduces any new cloud-config keys, you must provide a
+ schema definition in `cloud-init-schema.json`_.
+* The ``meta`` variable must exist and be of type `MetaSchema`_.
+
+ * ``id``: The module ID. In most cases this will be the filename without
+ the ``.py`` extension.
+ * ``distros``: Defines the list of supported distros. It can contain
+ any of the values (not keys) defined in the `OSFAMILIES`_ map or
+ ``[ALL_DISTROS]`` if there is no distro restriction.
+ * ``frequency``: Defines how often module runs. It must be one of:
+
+ * ``PER_ALWAYS``: Runs on every boot.
+ * ``ONCE``: Runs only on first boot.
+ * ``PER_INSTANCE``: Runs once per instance. When exactly this happens
+ is dependent on the datasource, but may triggered any time there
+ would be a significant change to the instance metadata. An example
+ could be an instance being moved to a different subnet.
+
+ * ``activate_by_schema_keys``: Optional list of cloud-config keys that will
+ activate this module. When this list not empty, the config module will be
+ skipped unless one of the ``activate_by_schema_keys`` are present in merged
+ cloud-config instance-data.
+ * ``examples``: Lists examples of any cloud-config keys this module reacts
+ to. These examples will be rendered in the module reference documentation
+ and will automatically be tested against the defined schema
+ during testing.
+
+* ``__doc__ = get_meta_doc(meta)`` is necessary to provide proper module
+ documentation.
+
+Module execution
+================
+
+In order for a module to be run, it must be defined in a module run section in
+:file:`/etc/cloud/cloud.cfg` or :file:`/etc/cloud/cloud.cfg.d` on the launched
+instance. The three module sections are
+`cloud_init_modules`_, `cloud_config_modules`_, and `cloud_final_modules`_,
+corresponding to the :ref:`Network<boot-Network>`, :ref:`Config<boot-Config>`,
+and :ref:`Final<boot-Final>` boot stages respectively.
+
+Add your module to `cloud.cfg.tmpl`_ under the appropriate module section.
+Each module gets run in the order listed, so ensure your module is defined
+in the correct location based on dependencies. If your module has no particular
+dependencies or is not necessary for a later boot stage, it should be placed
+in the ``cloud_final_modules`` section before the ``final-message`` module.
+
+
+
+.. _MetaSchema: https://github.com/canonical/cloud-init/blob/3bcffacb216d683241cf955e4f7f3e89431c1491/cloudinit/config/schema.py#L58
+.. _OSFAMILIES: https://github.com/canonical/cloud-init/blob/3bcffacb216d683241cf955e4f7f3e89431c1491/cloudinit/distros/__init__.py#L35
+.. _settings.py: https://github.com/canonical/cloud-init/blob/3bcffacb216d683241cf955e4f7f3e89431c1491/cloudinit/settings.py#L66
+.. _cloud-init-schema.json: https://github.com/canonical/cloud-init/blob/main/cloudinit/config/schemas/versions.schema.cloud-config.json
+.. _cloud.cfg.tmpl: https://github.com/canonical/cloud-init/blob/main/config/cloud.cfg.tmpl
+.. _cloud_init_modules: https://github.com/canonical/cloud-init/blob/b4746b6aed7660510071395e70b2d6233fbdc3ab/config/cloud.cfg.tmpl#L70
+.. _cloud_config_modules: https://github.com/canonical/cloud-init/blob/b4746b6aed7660510071395e70b2d6233fbdc3ab/config/cloud.cfg.tmpl#L101
+.. _cloud_final_modules: https://github.com/canonical/cloud-init/blob/b4746b6aed7660510071395e70b2d6233fbdc3ab/config/cloud.cfg.tmpl#L144