Skip to content

Commit

Permalink
Merge pull request #2598 from OSInside/revise-contributing
Browse files Browse the repository at this point in the history
Revise contributing
  • Loading branch information
schaefi authored Jul 22, 2024
2 parents 90fb39e + ed74872 commit d9102d3
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 89 deletions.
22 changes: 11 additions & 11 deletions doc/source/contributing/kiwi_from_python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ Using {kiwi} in a Python Project

.. note:: **Abstract**

{kiwi} is provided as python module under the **kiwi** namespace.
It is available for the python 3 version. The following
{kiwi} is provided as a Python module under the **kiwi** namespace.
It is available for the Python 3 version. The following
description applies for {kiwi} version |version|.

{kiwi} can also function as a module for other Python projects.
The following example demonstrates how to read an existing image
description, add a new repository definition and export the
description, add a new repository definition, and export the
modified description on stdout.

.. code:: python
Expand Down Expand Up @@ -39,15 +39,15 @@ modified description on stdout.
outfile=sys.stdout, level=0
)
All classes are written in a way to care for a single responsibility
in order to allow for re-use on other use cases. Therefore it is possible
to use {kiwi} outside of the main image building scope to manage e.g
the setup of loop devices, filesystems, partitions, etc...
Each class in the example is responsible for a single tasks, so they can be
reused in other user cases. Therefore it is possible to use {kiwi} beyond the
main image building scope, for example to manage setup of loop devices,
filesystems, partitions, etc.

This means {kiwi} provides you a way to describe a system but you are
free to make use of the kiwi description format or not. The following
example shows how to use kiwi to create a simple filesystem image
which contains your host `tmp` directory.
This means {kiwi} offers a way to describe a system, but you can choose whether
you want to use the {kiwi} description format or not. The following example
shows how to use {kiwi} to create a simple filesystem image which contains your
host `tmp` directory.

.. code:: python
Expand Down
39 changes: 18 additions & 21 deletions doc/source/contributing/kiwi_plugin_architecture.rst
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
Plugin Architecture
===================

Each command provided by {kiwi} is written as a task plugin under
the **kiwi.tasks** namespace. As a developer you can extend {kiwi}
with custom task plugins if the following conventions are taken
into account:
Each command provided by {kiwi} is written as a task plugin under the
**kiwi.tasks** namespace. As a developer, you can extend {kiwi} with custom task
plugins, following the conventions below.

Naming Conventions
Naming conventions
------------------

Task Plugin File Name
Task plugin file name
The file name of a task plugin must follow the pattern
:file:`<service>_<command>.py`. This allows to invoke the task
:file:`<service>_<command>.py`. This allows you to invoke the task
with :command:`kiwi-ng service command ...`

Task Plugin Option Handling
Task plugin option handling
{kiwi} uses the docopt module to handle options. Each task plugin
must use docopt to allow option handling.

Task Plugin Class
The implementation of the plugin must be a class that matches
the naming convention: :class:`<Service><Command>Task`. The class
must inherit from the :class:`CliTask` base class. On startup of
the plugin, {kiwi} expects an implementation of the
:file:`process` method.
Task plugin class
The implementation of the plugin must be a class that matches the naming
convention :class:`<Service><Command>Task`. The class must inherit from the
:class:`CliTask` base class. On the plugin startup, {kiwi} expects an
implementation of the :file:`process` method.

Task Plugin Entry Point
Task plugin entry point
Registration of the plugin must be done in :file:`setup.py`
using the ``entry_points`` concept from Python's setuptools.

Expand All @@ -38,7 +36,7 @@ Task Plugin Entry Point
]
}
Example Plugin
Example plugin
--------------

.. note::
Expand All @@ -47,14 +45,13 @@ Example Plugin
which was set up according to the Python project rules
and standards.

1. Assuming the project namespace is **kiwi_relax_plugin**.

Create the task plugin directory :file:`kiwi_relax_plugin/tasks`
1. Assuming the project namespace is **kiwi_relax_plugin**, create the task
plugin directory :file:`kiwi_relax_plugin/tasks`

2. Create the entry point in :command:`setup.py`.

Assuming we want to create the service named **relax** providing
the command **justdoit** this would be the following entry point
Assuming we want to create the service named **relax** that has
the command **justdoit**, this is the following entry point
definition in :file:`setup.py`:

.. code:: python
Expand Down
66 changes: 30 additions & 36 deletions doc/source/contributing/schema_extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,15 @@ Extending {kiwi} with Custom Operations

.. note:: **Abstract**

Users building images with {kiwi} need to implement their
own infrastructure if the image description does not
provide a way to embed custom information which is
outside of the scope of the general schema as it is
provided by {kiwi} today.
Extension plugins in {kiwi} offer a mechanism for adding information outside the standard {kiwi} schema.

This document describes how to create an extension plugin
for the {kiwi} schema to add and validate additional information
in the {kiwi} image description.
This document describes how to create an extension plugin for the {kiwi}
schema as well as how to add and validate additional information in the
{kiwi} image description.

Such a schema extension can be used in an additional {kiwi}
task plugin to provide a new subcommand for {kiwi}.
As of today there is no other plugin interface except for
providing additional {kiwi} commands implemented.
The described schema extension can be used in an additional {kiwi} task
plugin to provide a new subcommand for {kiwi}. At the present moment, there
is no other plugin interface except for providing additional {kiwi} commands.

Depending on the demand for custom plugins, the interface
to hook in code into other parts of the {kiwi} processing
Expand All @@ -27,10 +22,10 @@ Extending {kiwi} with Custom Operations
The <extension> Section
-----------------------

The main {kiwi} schema supports an extension section which allows
to specify any XML structure and attributes as long as they are
connected to a namespace. According to this any custom XML
structure can be implemented like the following example shows:
The main {kiwi} schema supports an extension section that allows you
to specify any XML structure and attributes, as long as they are
attached to a namespace. This means that any custom XML
structure can be implemented similar to the the example below:

.. code:: bash
Expand All @@ -43,20 +38,20 @@ structure can be implemented like the following example shows:
</extension>
</image>
* Any toplevel namespace must exist only once
* Any toplevel namespace must be unique
* Multiple different toplevel namespaces are allowed,
e.g my_plugin_a, my_plugin_b
for example: my_plugin_a, my_plugin_b

RELAX NG Schema for the Extension
---------------------------------

If an extension section is found, {kiwi} looks up its namespace and asks
If an extension section is found, {kiwi} looks up its namespace and uses
the main XML catalog for the schema file to validate the extension data.
The schema file must be a RELAX NG schema in the .rng format. We recommend
to place the schema as :file:`/usr/share/xml/kiwi/my_plugin.rng`
to save the schema as :file:`/usr/share/xml/kiwi/my_plugin.rng`

For the above example the RELAX NG Schema in the compressed format
:file:`my_plugin.rnc` would look like this:
For the example above, the RELAX NG Schema in the compressed format
:file:`my_plugin.rnc` looks as follows:

.. there is no rnc syntax highlighting, try cpp
.. code:: cpp
Expand Down Expand Up @@ -91,12 +86,12 @@ In order to convert this schema to the .rng format just call:
$ trang -I rnc -O rng my_plugin.rnc /usr/share/xml/kiwi/my_plugin.rng
Extension Schema in XML catalog
Extension schema in XML catalog
-------------------------------

As mentioned above the mapping from the extension namespace to the
As mentioned above, the mapping from the extension namespace to the
correct RELAX NG schema file is handled by a XML catalog file. The
XML catalog for the example use here looks like this:
XML catalog for the example is as follows:

.. code:: bash
Expand All @@ -107,30 +102,29 @@ XML catalog for the example use here looks like this:
uri="file:////usr/share/xml/kiwi/my_plugin.rng"/>
</catalog>
For resolving the catalog {kiwi} uses the :command:`xmlcatalog` command
and the main XML catalog from the system which is :file:`/etc/xml/catalog`.
For resolving the catalog, {kiwi} uses the :command:`xmlcatalog` command
and the main XML catalog from the system :file:`/etc/xml/catalog`.

.. note::

It depends on the distribution and its version how the main catalog
gets informed about the existence of the {kiwi} extension catalog file.
Please consult the distribution manual about adding XML catalogs.
How the main catalog is informed about the existence of the {kiwi} extension
catalog file depends on the distribution and its version. Refer to the
distribution documentation for information on adding XML catalogs.

If the following command provides the information to the correct
RELAX NG schema file you are ready for a first test:
RELAX NG schema file, you are ready for a first test:

.. code:: bash
$ xmlcatalog /etc/xml/catalog http://www.my_plugin.com
Using the Extension
Using the extension
-------------------

In order to test your extension place the example extension section
from the beginning of this document into one of your image description's
:file:`config.xml` file
In order to test the extension, insert the example extension into one of your
image description's :file:`config.xml` file.

The following example will read the name attribute from the title
The following example reads the name attribute from the title
section of the my_feature root element and prints it:

.. code:: python
Expand Down
41 changes: 20 additions & 21 deletions doc/source/contributing/scripts_testing.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
Write Integration Tests for the Scripts
---------------------------------------

Kiwi ships a set of helper functions that can be used in :file:`config.sh` (see
also: :ref:`working-with-kiwi-user-defined-scripts`). These utilize containers
to run the individual functions and verify that they resulted in the desired
state.
{kiwi} comes with a set of helper functions that can be used in :file:`config.sh` (see
also: :ref:`working-with-kiwi-user-defined-scripts`). These functions utilize containers
to run the individual tasks and verify the final result.

Ensure that you have either :command:`podman` or :command:`docker` installed and
configured on your system. The integration tests will use :command:`podman` in
**rootless mode** by default, if it is installed on your system. You can select
configured on your system. With Podman, the integration tests use :command:`podman` in
**rootless mode** by default. You can select
:command:`docker` instead by setting the environment variable
``CONTAINER_RUNTIME`` to ``docker``. Then you can run the integration tests via
tox:
Expand All @@ -19,23 +18,23 @@ tox:
The tests are written using the `pytest-container
<https://github.com/dcermak/pytest_container>`__ plugin. If applicable please
leverage the utility functions and fixtures of that plugin, e.g. the
<https://github.com/dcermak/pytest_container>`__ plugin. If applicable,
use the utility functions and fixtures of the plugin. For example, the
``auto_container`` and ``auto_container_per_test`` fixtures in conjunction with
`testinfra <https://testinfra.readthedocs.io/>`__.


Test Setup
Test setup
~~~~~~~~~~

The script tests can be run inside different containers, which are setup in
The script tests can be run inside different containers specified in
:file:`test/scripts/conftest.py`. This file contains the ``CONTAINERS`` list
with all currently present images. These images get pulled and build when needed
and the :file:`functions.sh` is copied into :file:`/bin/`, so that it is
with all currently present images. These images are pulled and built as needed,
and the :file:`functions.sh` is copied into :file:`/bin/`, so it is
available in ``PATH``.

To use any of these containers, you can either define the global variable
``CONTAINER_IMAGES`` in a test module and use the ``auto_container`` fixture or
``CONTAINER_IMAGES`` in a test module and use the ``auto_container`` fixture, or
`parametrize <https://docs.pytest.org/en/stable/parametrize.html>`__ the
``container`` fixture indirectly:

Expand All @@ -54,13 +53,13 @@ To use any of these containers, you can either define the global variable
assert not container_per_test.connection.file("/root/foobar").exists
We used the ``_per_test`` variant of the ``container`` fixture in the above
example. This fixture ensures that this container is only used in a single test
function. You should use this variant for tests that mutate the system under
test, as otherwise hard to debug race conditions could occur. For tests that
only perform reads, you can omit the ``_per_test`` suffix and the container
environment will be shared with other tests. This improves execution speed, but
comes at the expense of safety in case mutation does occur.
The example above uses the ``_per_test`` variant of the ``container`` fixture.
It ensures that the container is used only in a single test function. Use this
variant for tests that mutate the system under test, because otherwise it may
lead race conditions that are difficult to debug. For tests that only perform
reads, you can omit the ``_per_test`` suffix, so that the container environment can
shared with other tests. This improves execution speed, but comes at the
expense of safety in case of mutation.

For further information please refer to the documentation of `pytest-container
For further information, refer to `pytest-container
<https://github.com/dcermak/pytest_container>`__.

0 comments on commit d9102d3

Please sign in to comment.