Skip to content

Upgrades

Set version in the cluster's fleet file and merge. On a minor bump, change channel too.

 # fleet/prod-east-1.yaml
 revision: v3.0.0
-version: 4.20.8
+version: 4.20.12
 channel: stable-4.20
Key Effect
version OpenShift release x.y.z the cluster runs. Unset, nothing upgrades it. Required on a cluster a hub builds.
channel Update channel. Unset, the cluster's channel is left alone.

Both keys live only in the fleet file (fleet/<cluster>.yaml, or fleet/hubs/<hubName>.yaml for a hub). The validator rejects them in a values layer (POLICY034), so the clusters a merge upgrades are exactly the fleet files it changes, and the Render Diff lists each one.

Note

version must be a full x.y.z. Unquoted, version: 4.20 is the number 4.2; the validator rejects any value YAML reads as a number (POLICY050).

A wave is one commit that bumps several fleet files:

 # fleet/nonprod-west-1.yaml
-version: 4.20.8
+version: 4.21.2
-channel: stable-4.20
+channel: stable-4.21
 # fleet/prod-east-1.yaml
-version: 4.20.8
+version: 4.21.2
-channel: stable-4.20
+channel: stable-4.21

Who upgrades what

Each field has one writer.

lifecycle-<cluster> on the hub writes HostedCluster spec.release and spec.channel, then each NodePool's release once the control plane completes. See Cluster lifecycle.

The upgrade element is inert on the guest (Infrastructure controlPlaneTopology: External), since HyperShift owns its ClusterVersion.

The upgrade element on the cluster writes ClusterVersion spec.channel, spec.desiredUpdate and spec.upstream.

An imported hosted cluster is the exception: the element is inert on any HyperShift guest, so PolicyStack does not upgrade it.

upgrade element

Enabled by default. Renders nothing until the fleet file sets version or channel.

Template Policy (renders when) Mode Does
channel-pin channel-upgrade-<cluster> (channel set) enforce Sets ClusterVersion spec.channel.
upgrade-guard upgrade-upgrade-<cluster> (version set) inform NonCompliant unless version is in availableUpdates, is already the desired version, or is at or below the current version.
upgrade-trigger same enforce After the guard is Compliant, sets desiredUpdate.version, only while version is newer than current and no update is progressing. Never sets image or force.
upgrade-progress same inform NonCompliant until the cluster has completed version.
  • A version the update service does not offer is held at the guard.
  • Downgrades are never attempted.

upgrade-trigger also sets spec.upstream from stack.upgrade.config.upstream (default https://api.openshift.com/api/upgrades_info/v1/graph). On a local OpenShift Update Service, override it in a values layer:

# values/datacenters/dc1.yaml
stack:
  upgrade:
    config:
      upstream: https://osus.example.internal/api/upgrades_info/v1/graph

Watch it:

oc get policy -n pstack upgrade-upgrade-prod-east-1                 # on the hub
oc get clusterversion version -o jsonpath='{.status.history[0]}'    # on the cluster
Migrating from config.targetVersion / config.channel

Both keys are gone; the render fails while any layer sets them. In the commit that bumps revision, delete them from the values layer and set version and channel in the fleet file:

 # values/clusters/prod-east-1.yaml
 stack:
   upgrade:
-    config:
-      targetVersion: 4.20.12
-      channel: stable-4.20
 # fleet/prod-east-1.yaml
+version: 4.20.12
+channel: stable-4.20

Pausing

Turn a toggle off in any layer the cluster reads:

# values/clusters/prod-east-1.yaml
stack:
  upgrade:
    toggles:
      upgrade: false # (1)!
      channel: false # (2)!
  1. Deletes upgrade-upgrade-<cluster>. An update already started on the cluster keeps running.
  2. Stops managing the channel.

A hosted cluster is paused by leaving version where it is.

Why not ClusterCurator or TALM?

ClusterCurator runs an upgrade as a one-shot Job: a failure is not retried, and a Policy owning the ClusterCurator cannot tell a finished upgrade from a new one. TALM's ClusterGroupUpgrade is also one-shot and needs its own inform policies. ClusterVersion is declarative, so a Policy can keep enforcing it.