A provisioner is a controller responsible for reconciling Bundle
and/or BundleInstance
objects using
provisioner-specific logic, but with a consistent API. This provisioner concept is inspirted by and therefore very
similar to native Kubernetes's Ingress
API and the ecosystem of ingress controllers.
The idea of a provisioner is to unpack bundle content and install that bundle content onto a cluster, and the provisioner abstraction enables variations of bundle format and install/upgrade techniques to be implemented under a single API.
In order for bundle consumers and producers to be able to treat bundles and bundle instances homogeneously, all provisioners must include certain functionality and capabilities.
Term | Description |
---|---|
Bundle Source | A protocol that provisioners use to fetch bundle contents. |
Bundle Format | A schema that describes the contents of a bundle. |
- A provisioner must define one or more globally unique names for the
Bundle
andBundleInstance
controllers it runs. - A provisioner should use its unique controller names when configuring its watch predicates so that it only reconciles bundles and bundle instances that use its name.
- A provisioner is not required to implement controllers for both bundles and bundle instances.
- There may be use cases where a
Bundle
provisioner fetches a bundle in one format and converts it to another format such that a differentBundleInstance
provisioner can be used to install it. - There may also be use cases where different provisioners exist for to provide implementation variations for the same bundle formats. For example, two different provisioners that handle plain manifest bundles: one that performs "atomic" upgrades and one tha performs eventually consistent upgrades.
- There may be use cases where a
- A provisioner must reuse the defined condition types and phases when updating the status of bundles and bundle instances.
- A provisioner should populate all condition types during every reconciliation, even if that means setting
condition.status = "Unknown"
. This enables consumers to avoid making false assumptions about the status of the object. - A bundle provisioner must populate and update the observed generation in the bundle status such that it reflects
the
metadata.generation
value. - A bundle provisioner must populate the
contentURL
field and host a webserver at which the bundle can be fetched.- The webserver must deny unauthorized access to the bundle content.
- The webserver must allow access to the bundle content via the
bundle-reader
cluster role provided by rukpak.
- A bundle instance provisioner must populate and update the
installedBundleName
field in the status to reflect the currently installed bundle. It is up to the provisioner implementation to define what "installed" means for its implementation. - A bundle provisioner should implement all concrete source types in the bundle spec. In the event that it does
not implement a concrete source type, it must populate the
Unpacked
condition with statusFalse
and reasonReasonUnpackFailed
with a message explaining that the provisioner does not implement the desired source. - A bundle instance provisioner must reconcile embedded bundle objects by:
- Ensuring that the desired bundle template exists as a
Bundle
- Ensuring that the desired bundle has successfully unpacked prior to triggering a pivot to it.
- Ensuring that previous bundles associated with the bundle instance are cleaned up as soon as possible after the desired bundle has been successfully installed.
- Ensuring that the desired bundle template exists as a