Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,31 @@ description: >

# Creating an Update Graph

OLM provides a variety of ways to specify updates between operator versions as well as different add
modes (requires bundle format) to control how versions fit into the catalog.
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][file-based-catalog-spec] 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 CSV to another, you can specify the CSV name to replace in your CSV as
For explicit updates from one operator version to another, you can specify the operator name to replace in your channel entry as
such:

```yaml
metadata:
name: myoperator.v1.0.1
spec:
replaces: myoperator.v1.0.0
---
schema: olm.channel
package: myoperator
channel: stable
entries:
- name: myoperator.v1.0.1
replaces: myoperator.v1.0.0
```

In order for `myoperator.v1.0.1` to be added to the catalog successfully, `myoperator.v1.0.0` needs to
be included in your manifests or have already been added to that catalog (in the case where packaging
is done in the bundle format).
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`][opm-validate-cli]) 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
Expand All @@ -40,22 +45,25 @@ A subscription on `myoperator.v1.0.0` will update to `myoperator.v1.0.2` through

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 CSV name. Note that, in this case, the subscription will
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 CSV names to be skipped as such:
In order to skip through certain updates, you can specify a list of operator names to be skipped. For example:

```yaml
metadata:
name: myoperator.v1.0.3
spec:
replaces: myoperator.v1.0.0
skips:
- myoperator.v1.0.1
- myoperator.v1.0.2
---
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
Expand All @@ -66,49 +74,29 @@ that are already on `myoperator.v1.0.1` or `myoperator.v1.0.2` will still be abl
This is particularly useful if `myoperator.v1.0.1` and `myoperator.v1.0.2` are affected by a CVE
or contain bugs.

Skipped CSVs do not need to be present in a catalog or set of manifests prior to adding to a catalog.
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 CSV. This requires your CSVs
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](https://semver.org/).
Internally, OLM uses the [blang/semver](https://github.com/blang/semver) go library.

```yaml
metadata:
name: myoperator.v1.0.3
annotations:
olm.skipRange: ">=1.0.0 <1.0.3"
---
schema: olm.channel
package: myoperator
channel: stable
entries:
- name: myoperator.v1.0.3
skipRange: ">=1.0.0 <1.0.3"
```

The version specifying the `olm.skipRange` will be presented as a direct (one hop) update to
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 index in order for bundle addition to be successful. We recommend avoiding using unbound ranges
such as `<1.0.3`.

**Warning:** Adding a bundle that only specifies skipRange to a given channel will wipe out all
the previous content in that channel. This means directly installing past versions by editing
the `startingCSV` field of the subscription is not possible when using skiprange only. In order
for past versions to be installable by `startingCSV` while also benefitting from the `skipRange`
feature, you will need to also connect past edges by setting a `replaces` field in addition to
the `olm.skipRange`. For example, assuming the above update graph:

```txt
myoperator.v1.0.0 -> myoperator.v1.0.1 -> myoperator.v1.0.2
```

In order to keep these versions installable by `startingCSV` when `myoperator.v1.0.3` is added,
the CSV for `myoperator.v1.0.3` needs to have the following:

```yaml
metadata:
name: myoperator.v1.0.3
annotations:
olm.skipRange: ">=1.0.0 <1.0.3"
spec:
replaces: myoperator.v1.0.2
```

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.
Expand All @@ -118,24 +106,152 @@ version.
### 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 subcription
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 a CSV in the new channel.
The CSV name currently installed must be in the `replaces` field of an entry in the new channel.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The CSV name currently installed must be in the `replaces` field of an entry in the new channel.
The operator version name currently installed must be in the `replaces` field of an entry in the new channel.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may actually be important in this case to keep using CSV name, because that's actually what OLM is using to decide what the upgrade candidates are when a CSV is installed on the cluster.


#### If using skips

The CSV name currently installed must be in the `skips` field of a CSV in the new channel.
The CSV name currently installed must be in the `skips` field of an entry in the new channel.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The CSV name currently installed must be in the `skips` field of an entry in the new channel.
The operator version 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 `olm.skipRange` field of a CSV in the new channel.
The version currently installed must be in the `skipRange` field of an entry in the new channel.

## Channel Promotion
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉


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.
```yaml
---
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 index (the image was already built and pushed, and the index already contains
> an `olm.bundle` blob and an entry for it in the `alpha` channel). The channel promotion step for `myoperator.v0.2.0`
> is to simply create a new `olm.channel` for the `beta` channel and include an entry for `myoperator.v0.2.0`.

```yaml
---
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` replaces `myoperator.v0.3.0`, but in channel `beta`, `myoperator.v0.4.0`
> replaces `myoperator.v0.2.0` because the `beta` channel does not include every entry from alpha.

```yaml
---
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).

## Add Modes
```yaml
---
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
```

TODO
[file-based-catalog-spec]: /docs/reference/file-based-catalogs
[opm-validate-cli]: /docs/reference/file-based-catalogs/#opm-validate
Loading