Plugin Walkthrough
==================
This guide assumes that you are familiar with `general pulp concepts
`_ as well as the :ref:`planning-guide`.
It will be helpful to skim the :ref:`plugin-concepts` pages, and refer back to them as you go
through the process.
Bootstrap your plugin
---------------------
Start your new plugin by using the `Plugin Template `_.
Follow the documentation in the README to get a working stub plugin.
.. _define-content-type:
Define your plugin Content type
-------------------------------
To define a new content type(s), e.g. ``ExampleContent``:
* :class:`pulpcore.plugin.models.Content` should be subclassed and extended with additional
attributes to the plugin needs,
* define ``TYPE`` class attribute which is used for filtering purposes,
* uniqueness should be specified in ``Meta`` class of newly defined ``ExampleContent`` model,
* ``unique_together`` should be specified for the ``Meta`` class of ``ExampleContent`` model,
* create a serializer for your new Content type as a subclass of
:class:`pulpcore.plugin.serializers.NoArtifactContentSerializer`,
:class:`pulpcore.plugin.serializers.SingleArtifactContentSerializer`, or
:class:`pulpcore.plugin.serializers.MultipleArtifactContentSerializer`
* create a viewset for your new Content type. It can be as a subclass of
:class:`pulpcore.plugin.viewsets.ContentViewSet`, and you can define your ``create()`` method based
on the serializer you chose. If you need a read-only viewset, subclass
:class:`pulpcore.plugin.viewsets.ReadOnlyContentViewSet` instead. It's also convenient to subclass
:class:`pulpcore.plugin.viewsets.SingleArtifactContentUploadViewSet` if you need an upload support.
:class:`~pulpcore.plugin.models.Content` model should not be used directly anywhere in plugin code.
Only plugin-defined Content classes are expected to be used.
Check ``pulp_file`` implementation of `the FileContent
`_ and its
`serializer `_
and `viewset `_.
For a general reference for serializers and viewsets, check `DRF documentation
`_.
Add any fields that correspond to the metadata of your content, which could be the project name,
the author name, or any other type of metadata.
.. _define-remote:
Define your plugin Remote
-------------------------
To define a new remote, e.g. ``ExampleRemote``:
* :class:`pulpcore.plugin.models.Remote` should be subclassed and extended with additional
attributes to the plugin needs,
* define ``TYPE`` class attribute which is used for filtering purposes,
* create a serializer for your new remote as a subclass of
:class:`pulpcore.plugin.serializers.RemoteSerializer`,
* create a viewset for your new remote as a subclass of
:class:`pulpcore.plugin.viewsets.RemoteViewSet`.
:class:`~pulpcore.plugin.models.Remote` model should not be used directly anywhere in plugin code.
Only plugin-defined Remote classes are expected to be used.
There are several important aspects relevant to remote implementation which are briefly mentioned
in the :ref:`object-relationships` section:
* due to deduplication of :class:`~pulpcore.plugin.models.Content` and
:class:`~pulpcore.plugin.models.Artifact` data, they may already exist and the remote needs to
fetch and use them when they do.
* :class:`~pulpcore.plugin.models.ContentArtifact` associates
:class:`~pulpcore.plugin.models.Content` and :class:`~pulpcore.plugin.models.Artifact`. If
:class:`~pulpcore.plugin.models.Artifact` is not downloaded yet,
:class:`~pulpcore.plugin.models.ContentArtifact` contains ``NULL`` value for
:attr:`~pulpcore.plugin.models.ContentArtifact.artifact`. It should be updated whenever
corresponding :class:`~pulpcore.plugin.models.Artifact` is downloaded
.. note::
Some of these steps may need to behave differently for other download policies.
The remote implementation suggestion above allows plugin writer to have an understanding and
control at a low level.
Define your Tasks
-----------------
See :ref:`writing-tasks`. Almost all plugins must implement a `sync` task, most implement a
`publish` task as well.
Plugin Completeness Checklist
------------------------------
* :ref:`Plugin django app is defined using PulpAppConfig as a parent `
* :ref:`Plugin entry point is defined `
* `pulpcore is specified as a requirement `_
* Necessary models/serializers/viewsets are :ref:`defined ` and :ref:`discoverable `. At a minimum:
* models for plugin content type, remote, publisher
* serializers for plugin content type, remote, publisher
* viewset for plugin content type, remote, publisher
* :ref:`Errors are handled according to Pulp conventions `
* Docs for plugin are available (any location and format preferred and provided by plugin writer)