Creating an update graph with OLM
Note: This document discusses creating an upgrade graph for your operator using plaintext files to store catalog metadata, which is the latest feature of OLM catalogs. If you are looking to create an upgrade graph for your operator using the deprecated sqllite database format to store catalog metadata instead, please read the v0.18.z version of this doc instead.
Creating an Update Graph
OLM provides a variety of ways to specify updates between operator versions.
Methods for Specifying Updates
All update graphs are defined in file-based catalogs via olm.channel
blobs. Each olm.channel
defines the set of
bundles present in the channel and the update graph edges between each entry in the channel.
Replaces
For explicit updates from one operator version to another, you can specify the operator name to replace in your channel entry as such:
---
schema: olm.channel
package: myoperator
channel: stable
entries:
- name: myoperator.v1.0.1
replaces: myoperator.v1.0.0
Note that it is not required for there to be an entry for myoperator.v1.0.0
in the catalog as long as
other channel invariants (verified by opm validate
) still hold. Generally, this means that the tail of the channel’s
replaces
chain can replace a bundle that is not present in the catalog.
An update sequence of bundles created via replaces
will have updates step through each version in
the chain. For example, given
myoperator.v1.0.0 -> myoperator.v1.0.1 -> myoperator.v1.0.2
A subscription on myoperator.v1.0.0
will update to myoperator.v1.0.2
through myoperator.v1.0.1
.
Installing from the UI today will always install the latest of a given channel. However, installing
specific versions is possible with this update graph by modifying the startingCSV
field
of the subscription to point to the desired operator name. Note that, in this case, the subscription will
need its approval
field set to Manual
to ensure that the subscription does not auto-update and
instead stays pinned to the specified version.
Skips
In order to skip through certain updates, you can specify a list of operator names to be skipped. For example:
---
schema: olm.channel
package: myoperator
channel: stable
entries:
- name: myoperator.v1.0.3
replaces: myoperator.v1.0.0
skips:
- myoperator.v1.0.1
- myoperator.v1.0.2
Using the above graph, this will mean subscriptions on myoperator.v1.0.0
can update directly to
myoperator.v1.0.3
without going through myoperator.v1.0.1
or myoperator.v1.0.2
. Installs
that are already on myoperator.v1.0.1
or myoperator.v1.0.2
will still be able to update to
myoperator.v1.0.3
.
This is particularly useful if myoperator.v1.0.1
and myoperator.v1.0.2
are affected by a CVE
or contain bugs.
Skipped operators do not need to be present in a catalog or set of manifests prior to adding to a catalog.
SkipRange
OLM also allows you to specify updates through version ranges in your channel entry. This requires your CSVs to define a version in their version field which must follow the semver spec. Internally, OLM uses the blang/semver go library.
---
schema: olm.channel
package: myoperator
name: stable
entries:
- name: myoperator.v1.0.3
skipRange: ">=1.0.0 <1.0.3"
The entry specifying the skipRange
will be presented as a direct (one hop) update to
any version from that package within that range. The versions in this range do not need to be in
the catalog in order for bundle addition to be successful. We recommend avoiding using unbound ranges
such as <1.0.3
.
WARNING: As a consequence of using skipRange
the skipped operator versions will be pruned from OLMs
update graph and therefore will not be installable anymore by users with the spec.startingCSV
property
of Subscriptions.
Use with caution. If you want to have direct (one hop) updates to this version from
multiple previous versions but keep those previous versions available to users for install, always use
skipRange
in conjunction with replaces
pointing to the immediate previous version of the operator
version in question.
SkipRange by itself is useful for teams who are not interested in supporting directly installing versions within a given range or for whom consumers of the operator are always on the latest version.
Channel Guidelines
Cross channel updates
Cross channel updates are not possible today in an automated way. In order for your subscription
to switch channels, the cluster admin must manually change the channel
field in the subscription
object.
Changing this field does not always result in receiving updates from that channel. For that to occur, updates paths must be available from the given version to versions in the new channel.
If using replaces
The CSV name currently installed must be in the replaces
field of an entry in the new channel.
If using skips
The CSV name currently installed must be in the skips
field of an entry in the new channel.
If using skipRange
The version currently installed must be in the skipRange
field of an entry in the new channel.
Channel Promotion
A popular channel strategy is to use alpha
, beta
, and stable
channels, where every new bundle is added to alpha
,
a subset of bundles from alpha
are promoted to beta
, and a further subset of bundles from beta
are promoted to
stable
.
An operator author wishing to employ the alpha
/beta
/stable
channel strategy may have created and updated their
olm.channel
blobs following the below scenario.
First, an operator author releases a few versions into the alpha
channel, with a simple linear replaces chain.
---
schema: olm.channel
package: myoperator
channel: alpha
entries:
- name: myoperator.v0.1.0
- name: myoperator.v0.2.0
replaces: myoperator.v0.1.0
- name: myoperator.v0.3.0
replaces: myoperator.v0.2.0
Next, an operator author decides that myoperator.v0.2.0
is a good candidate to promote to beta
, so they add a new
olm.channel
schema and include myoperator.v0.2.0
as the first entry, taking care to preserve any upgrade edges from
alpha
to enable users to switch from the alpha
to the beta
channel if they have myoperator.v0.1.0
installed.
NOTE: This bundle already exists in the catalog (the image was already built and pushed, and the catalog already contains an
olm.bundle
blob and an entry for it in thealpha
channel). The channel promotion step formyoperator.v0.2.0
is to simply create a newolm.channel
for thebeta
channel and include an entry formyoperator.v0.2.0
.
---
schema: olm.channel
package: myoperator
channel: alpha
entries:
- name: myoperator.v0.1.0
- name: myoperator.v0.2.0
replaces: myoperator.v0.1.0
- name: myoperator.v0.3.0
replaces: myoperator.v0.2.0
---
schema: olm.channel
package: myoperator
channel: beta
entries:
- name: myoperator.v0.2.0
replaces: myoperator.v0.1.0
The operator continues releasing bundles to alpha
and promotes myoperator.v0.4.0
to beta
.
NOTE: In channel
alpha
,myoperator.v0.4.0
replacesmyoperator.v0.3.0
, but in channelbeta
,myoperator.v0.4.0
replacesmyoperator.v0.2.0
because thebeta
channel does not include every entry from alpha.
---
schema: olm.channel
package: myoperator
channel: alpha
entries:
- name: myoperator.v0.1.0
- name: myoperator.v0.2.0
replaces: myoperator.v0.1.0
- name: myoperator.v0.3.0
replaces: myoperator.v0.2.0
- name: myoperator.v0.4.0
replaces: myoperator.v0.3.0
- name: myoperator.v0.5.0
replaces: myoperator.v0.4.0
---
schema: olm.channel
package: myoperator
channel: beta
entries:
- name: myoperator.v0.2.0
replaces: myoperator.v0.1.0
- name: myoperator.v0.4.0
replaces: myoperator.v0.2.0
Finally, the operator author releases several more bundles and makes several more promotions, finally deciding to
promote myoperator.v0.4.0
to the stable channel. With myoperator.v0.4.0
being the first entry in the stable
channel, the operator author has decided to add replaces
and skips
edges for all previously released bundles to
assist users in moving to the stable
channel directly from the alpha
and beta
channels. However, it would have
been equally valid to require that a user have either myoperator.v0.2.0
or myoperator.v0.3.0
installed (e.g. if the
direct upgrade from myoperator.v0.1.0
has not been tested or is known to be unsupported).
---
schema: olm.channel
package: myoperator
channel: alpha
entries:
- name: myoperator.v0.1.0
- name: myoperator.v0.2.0
replaces: myoperator.v0.1.0
- name: myoperator.v0.3.0
replaces: myoperator.v0.2.0
- name: myoperator.v0.4.0
replaces: myoperator.v0.3.0
- name: myoperator.v0.5.0
replaces: myoperator.v0.4.0
- name: myoperator.v0.6.0
replaces: myoperator.v0.5.0
---
schema: olm.channel
package: myoperator
channel: beta
entries:
- name: myoperator.v0.2.0
replaces: myoperator.v0.1.0
- name: myoperator.v0.4.0
replaces: myoperator.v0.2.0
- name: myoperator.v0.6.0
replaces: myoperator.v0.4.0
---
schema: olm.channel
package: myoperator
channel: stable
entries:
- name: myoperator.v0.4.0
replaces: myoperator.v0.1.0
skips:
- myoperator.v0.2.0
- myoperator.v0.3.0