Crossplane supports two types of packages: Providers and Configurations. These
packages are distributed as generic OCI images, which contain YAML content
informing the Crossplane package manager how to alter the state of a cluster by
installing objects that configure new resource types, and starting controllers
to reconcile them. An OCI image that contains valid Crossplane package content
is commonly referred to as an xpkg
(“ex-package”). This document provides the
specification for a valid xpkg
, which can be considered a superset of the
requirements detailed in the OCI image specification. It is divided into two
broad sections: requirements related to OCI image format and requirements
related to Crossplane package.yaml
contents.
OCI images are comprised of manifests, configuration, and layers.
Additionally, an image reference could refer to an image index, which may
reference multiple image manifests and is frequently used for multi-platform
images. A valid Crossplane xpkg
imposes various requirements on the components
of an OCI, each of which are described in the following sections.
The components of an xpkg
that Crossplane interacts with do not contain any
platform-specific information, so Crossplane is broadly agnostic to the
formatting of an image index. Crossplane does impose the following requirements
on an image index:
The OCI image specification allows for zero-length manifest descriptor arrays in an index.
The following default behavior when interacting with image indexes is implemented in the Crossplane package manager:
linux/amd64
variant by default.It is important to note that the platform of the package image that is used by Crossplane does not necessarily mean that the same platform will be used for the controller if the package is a Provider. The decision of selecting a platform for a Provider controller image is deferred to the configured container runtime.
A manifest defines the layers and configuration of a specific image. Crossplane is only concerned with the layer descriptors array in an image manifest and does not impose additional requirements on any other portions of the manifest. The following requirements are imposed on the layer descriptors array:
io.crossplane.xpkg
and value base
.io.crossplane.xpkg
and arbitrary value. Whether multiple layer descriptors
may have the same value is left to the specification of the consumer of those
layers.As evidenced by the fact that annotations are provided as a map of string-string, no single descriptor will contain multiple
io.crossplane.xpkg
annotations.
Crossplane is only concerned with the layer with the base
annotation, and any
other layers with the io.crossplane.xpkg
key are used to signify to
third-party consumers that a layer contains content related to the xpkg
that
may be specific to a given consumer.
If no layer descriptors have an annotation in the form io.crossplane.xpkg: base
, the resultant filesystem from applying changesets from all layers will
be used. It is preferred to use layer descriptor annotations.
Motivation
Crossplane prefers the usage of annotated layer descriptors because it allows
for fetching and processing individual layers, rather than all layers in the
image. In the event that the image contains a single layer, this overhead is
minimal. However, larger images with many layers, whether they contain
third-party xpkg
content or unrelated data, will result in multiple network
calls and more data to process.
Crossplane also prefers the usage of annotated layer descriptors to define
additive package content (i.e. third-party xpkg
content) as it provides a
clean mechanism to build an xpkg
through a series of stages. A valid xpkg
can be produced and later modified while verifying that the integrity of the
existing content is not violated, which ensures that Crossplane’s package
manager will process the resulting xpkg
in the same manner as the it would
prior to modification.
While not explicitly forbidden, modifying content from a preceding layer with
the io.crossplane.xpkg
annotation in any subsequent layers is discouraged, as
it may lead to confusion if a third-party is consuming content from the
flattened filesystem.
Crossplane imposes no additional requirements on image configuration and does not consider its contents when processing a package.
As described above, Crossplane is only concerned with the single layer
referenced by the descriptor containing io.crossplane.xpkg: base
if
distinguished. Crossplane imposes no additional restrictions on any other
layers, including those with a io.crossplane.xpkg
annotation but a value other
than base
, but does require the following of the xpkg
base layer:
package.yaml
MUST exist in the root directory of the
xpkg
base layer if distinguished, or in the root of the image filesystem
after all layer changesets are applied.package.yaml
file MUST contain a valid YAML stream.xpkg
base layer, or the full image
filesystem is ignored by Crossplane.The ability to use the image’s flattened filesystem is primarily for backwards compatibility and is not encouraged, especially in the event that an image contains more than just
xpkg
related content, due to the fact that accidentally overwriting or modifying thexpkg
layer contents in subsequent layers when constructing an image could cause the package to be invalid.
Depending on the type of package, the YAML stream in the xpkg
base layer
package.yaml
may contain different content. Additionally, the objects in the
YAML stream may contain common annotations that are suitable for the given
object type.
The package.yaml
for Configuration packages must adhere to the following
requirements:
Configuration.meta.pkg.crossplane.io
object MUST be
defined in the YAML stream.CompositeResourceDefinition.apiextensions.crossplane.io
objects MAY be defined in the YAML stream.Composition.apiextensions.crossplane.io
objects MAY be
defined in the YAML stream.The package.yaml
for Provider packages must adhere to the following
requirements:
Provider.meta.pkg.crossplane.io
object MUST be defined
in the YAML stream.CustomResourceDefinition.apiextensions.k8s.io
objects MAY
be defined in the YAML stream.AdmissionWebhookConfiguration.admissionregistration.k8s.io
objects MAY be defined in the YAML stream.MutatingWebhookConfiguration.admissionregistration.k8s.io
objects MAY be defined in the YAML stream.Though not used directly by Crossplane, the following object metadata
annotations (not to be confused with descriptor annotations in an OCI image
manifest) are defined for Configuration.meta.pkg.crossplane.io
and
Provider.meta.pkg.crossplane.io
and should be honored over any competing
annotations by third-party consumers of Crossplane packages:
meta.crossplane.io/maintainer
: The package’s maintainers, as a short opaque
text string.meta.crossplane.io/source
: The URL at which the package’s source can be
found.meta.crossplane.io/license
: The license under which the package’s source is
released. This should be a valid SPDX License Identifier.meta.crossplane.io/description
: A one sentence description of the package.meta.crossplane.io/readme
: A longer description, documentation, etc.Third party consumers may define additional arbitrary annotations with any key
and value on any object in a package. All annotations on “meta” types (i.e.
Configuration.meta.pkg.crossplane.io
and Provider.meta.pkg.crossplane.io
)
are propagated to the respective package revision (i.e.
ConfigurationRevision.pkg.crossplane.io
and
ProviderRevision.pkg.crossplane.io
) on package install. Annotations on all
other objects in a package are propagated to their in-cluster representation
unmodified.