Skip to content

Commit eda10fc

Browse files
committed
install: Add a TechPreviewNoUpgrade cluster-update console plugin
The console folks are pushing to decentralize console implementation from [1], so we've created a new console plugin for cluster updates [2]. It's built by both CI [3] and ART [4]. Checking on app.ci ImageStreams: $ oc whoami -c default/api-ci-l2s4-p1-openshiftapps-com:6443/wking $ oc -n ocp get -o json imagestream 5.0 | jq -r '.status.tags[] | select(.tag == "cluster-update-console-plugin").items[] | .created + " " + .image' 2026-05-01T20:55:38Z sha256:10e4f1b5763f40372823173b2a9528777ff8e97d416c5447e10df023c0e35656 2026-04-29T05:00:56Z sha256:b0433455cbbff13bdda03ee78371e18c139adebc00432dea716e8cdf83eeb042 2026-04-17T11:10:31Z sha256:e1296b64ffb35757fb2fb56bb5dd9cbd55c7f17f9f59c0a10a2d71a0ad6702d3 $ oc -n ocp get -o json imagestream 5.0-art-latest | jq -r '.status.tags[] | select(.tag == "cluster-update-console-plugin").items[] | .created + " " + .image' 2026-05-12T19:45:33Z sha256:b943be0ae0eba97c27741d0184e99a77ea928749cc578ae7e17a8e5329652642 2026-05-12T14:42:55Z sha256:c29ba37ef5a426de5320d680d3fb58befc530274e6df4c32b4dc4fd0acaaaae0 2026-05-12T09:02:35Z sha256:901bc6aac1142fe1da2a756bb4d91ae8fe14b459ce2bf9904ceae6d2fc818fc2 2026-05-12T04:38:56Z sha256:1f4e8b200d97f82db1784b4d7fc9f0bd3ccaf2cc664fd5f0ff6b80485da16950 2026-05-11T22:54:34Z sha256:d369ca7c73d7a3abe159e9e6f5644f63e0b091f0b75f202773a023e91c7faaf6 This commit sets up an image-references file [5], so 'oc adm release new ...' knows that we'll want that image injected in the Deployment manifest. I'm using placeholder.url.oc.will.replace.this.example.org as part of my placeholder name. That's similar to the machine-config operator's use of placeholder.url.oc.will.replace.this.org [6], except that I'm using a subdomain of the reserved example.com [7], to avoid any possible confusion with an actually in-use domain. The new manifests are in run-level 50, which is the default, so they can roll out in parallel with other components to avoid slowing updates. The new manifests are tried to the Console capability [8] and the TechPreviewNoUpgrade feature set [9] (in the absence of a specific feature gate for this functionality). I'm just carrying the old exclude.release.openshift.io/internal-openshift-hosted annotation over from other CVO manifests. It predates cluster profiles [10], and I'm not sure anyone still uses it, but it seems like the CVO should be consistent about whether it matters or not anymore. Perhaps we can drop it from all CVO manifests in follow-up work. Otherwise these manifests are loosely based on my attempts to meld the plugin's Help chart templates [11] with existing CVO manifest conventions. [1]: https://github.com/openshift/console [2]: https://github.com/openshift/cluster-update-console-plugin [3]: openshift/release#77945 [4]: openshift-eng/ocp-build-data#10393 [5]: https://github.com/openshift/enhancements/blob/4f67eee19ad16f1d5e9e8a2622b708e2ea6d8e6a/dev-guide/cluster-version-operator/dev/operators.md#how-do-i-ensure-the-right-images-get-used-by-my-manifests [6]: https://github.com/openshift/machine-config-operator/blob/99cb8a46e6a31b2b72d6a8371c6cd4ee45393263/install/image-references#L10 [7]: https://www.rfc-editor.org/rfc/rfc6761#section-6.5 [8]: https://github.com/openshift/enhancements/blob/4f67eee19ad16f1d5e9e8a2622b708e2ea6d8e6a/enhancements/installer/component-selection.md#manifest-annotations [9]: https://github.com/openshift/enhancements/blob/4f67eee19ad16f1d5e9e8a2622b708e2ea6d8e6a/enhancements/update/cvo-techpreview-manifests.md#proposal [10]: https://github.com/openshift/enhancements/blob/4f67eee19ad16f1d5e9e8a2622b708e2ea6d8e6a/enhancements/update/ibm-public-cloud-support.md#cluster-version-operator-changes-for-beta [11]: https://github.com/openshift/cluster-update-console-plugin/tree/9778f4fc0c19e60cad55a45591a066b6b7a3cb12/charts/openshift-console-plugin/templates
1 parent 4cfd94b commit eda10fc

7 files changed

Lines changed: 293 additions & 0 deletions
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: openshift-cluster-update-console-plugin
5+
annotations:
6+
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
7+
capability.openshift.io/name: Console
8+
release.openshift.io/feature-set: TechPreviewNoUpgrade
9+
exclude.release.openshift.io/internal-openshift-hosted: "true"
10+
include.release.openshift.io/self-managed-high-availability: "true"
11+
labels:
12+
openshift.io/cluster-monitoring: "true"
13+
pod-security.kubernetes.io/audit: restricted
14+
pod-security.kubernetes.io/enforce: restricted
15+
pod-security.kubernetes.io/warn: restricted
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: networking.k8s.io/v1
2+
kind: NetworkPolicy
3+
metadata:
4+
name: default-deny
5+
namespace: openshift-cluster-update-console-plugin
6+
annotations:
7+
kubernetes.io/description: This NetworkPolicy is used to deny all ingress and egress traffic by default in this namespace, matching all Pods, and serving as a baseline.
8+
capability.openshift.io/name: Console
9+
release.openshift.io/feature-set: TechPreviewNoUpgrade
10+
exclude.release.openshift.io/internal-openshift-hosted: "true"
11+
include.release.openshift.io/self-managed-high-availability: "true"
12+
spec:
13+
podSelector: {}
14+
policyTypes:
15+
- Ingress
16+
- Egress
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: cluster-update-console-plugin
5+
namespace: openshift-cluster-update-console-plugin
6+
annotations:
7+
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
8+
capability.openshift.io/name: Console
9+
release.openshift.io/feature-set: TechPreviewNoUpgrade
10+
exclude.release.openshift.io/internal-openshift-hosted: "true"
11+
include.release.openshift.io/self-managed-high-availability: "true"
12+
spec:
13+
selector:
14+
matchLabels:
15+
app: cluster-update-console-plugin
16+
strategy:
17+
rollingUpdate:
18+
maxSurge: 25%
19+
maxUnavailable: 1
20+
type: RollingUpdate
21+
template:
22+
metadata:
23+
annotations:
24+
target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
25+
openshift.io/required-scc: restricted-v3
26+
labels:
27+
app: cluster-update-console-plugin
28+
spec:
29+
automountServiceAccountToken: false
30+
containers:
31+
- name: plugin
32+
image: placeholder.url.oc.will.replace.this.example.org:cluster-update-console-plugin
33+
imagePullPolicy: IfNotPresent
34+
ports:
35+
- name: https
36+
containerPort: 9001
37+
resources:
38+
requests:
39+
cpu: 20m
40+
memory: 50Mi
41+
securityContext:
42+
allowPrivilegeEscalation: false
43+
capabilities:
44+
drop:
45+
- ALL
46+
terminationMessagePolicy: FallbackToLogsOnError
47+
volumeMounts:
48+
- mountPath: /var/cert
49+
name: cluster-update-console-plugin
50+
readOnly: true
51+
dnsPolicy: Default
52+
nodeSelector:
53+
node-role.kubernetes.io/infra: ""
54+
priorityClassName: system-cluster-critical
55+
securityContext:
56+
runAsNonRoot: true
57+
seccompProfile:
58+
type: RuntimeDefault
59+
terminationGracePeriodSeconds: 30
60+
tolerations:
61+
- effect: NoSchedule
62+
key: node-role.kubernetes.io/infra
63+
operator: Exists
64+
volumes:
65+
- name: cluster-update-console-plugin-cert
66+
secret:
67+
defaultMode: 420
68+
secretName: cluster-update-console-plugin-cert
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: openshift-cluster-update-console-plugin
5+
namespace: openshift-cluster-update-console-plugin
6+
annotations:
7+
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
8+
capability.openshift.io/name: Console
9+
release.openshift.io/feature-set: TechPreviewNoUpgrade
10+
exclude.release.openshift.io/internal-openshift-hosted: "true"
11+
include.release.openshift.io/self-managed-high-availability: "true"
12+
spec:
13+
type: ClusterIP
14+
selector:
15+
app: cluster-update-console-plugin
16+
ports:
17+
- name: https
18+
port: 9001
19+
targetPort: https
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
apiVersion: monitoring.coreos.com/v1
2+
kind: ServiceMonitor
3+
metadata:
4+
labels:
5+
k8s-app: cluster-version-operator
6+
name: cluster-version-operator
7+
namespace: openshift-cluster-version
8+
annotations:
9+
kubernetes.io/description: Configure Prometheus to monitor cluster-version operator metrics.
10+
exclude.release.openshift.io/internal-openshift-hosted: "true"
11+
include.release.openshift.io/self-managed-high-availability: "true"
12+
spec:
13+
endpoints:
14+
- interval: 30s
15+
port: metrics
16+
scheme: https
17+
tlsConfig:
18+
serverName: cluster-version-operator.openshift-cluster-version.svc
19+
scrapeClass: tls-client-certificate-auth
20+
namespaceSelector:
21+
matchNames:
22+
- openshift-cluster-version
23+
selector:
24+
matchLabels:
25+
k8s-app: cluster-version-operator
26+
---
27+
apiVersion: monitoring.coreos.com/v1
28+
kind: PrometheusRule
29+
metadata:
30+
labels:
31+
k8s-app: cluster-version-operator
32+
name: cluster-version-operator
33+
namespace: openshift-cluster-version
34+
annotations:
35+
kubernetes.io/description: Alerting rules for when cluster-version operator metrics call for administrator attention.
36+
exclude.release.openshift.io/internal-openshift-hosted: "true"
37+
include.release.openshift.io/self-managed-high-availability: "true"
38+
spec:
39+
groups:
40+
- name: cluster-version
41+
rules:
42+
- alert: ClusterVersionOperatorDown
43+
annotations:
44+
summary: Cluster version operator has disappeared from Prometheus target discovery.
45+
description: The operator may be down or disabled. The cluster will not be kept up to date and upgrades will not be possible. Inspect the openshift-cluster-version namespace for events or changes to the cluster-version-operator deployment or pods to diagnose and repair. {{ "{{ with $console_url := \"console_url\" | query }}{{ if ne (len (label \"url\" (first $console_url ) ) ) 0}} For more information refer to {{ label \"url\" (first $console_url ) }}/k8s/cluster/projects/openshift-cluster-version.{{ end }}{{ end }}" }}
46+
runbook_url: https://github.com/openshift/runbooks/blob/master/alerts/cluster-version-operator/ClusterVersionOperatorDown.md
47+
expr: |
48+
absent(up{job="cluster-version-operator"} == 1)
49+
for: 10m
50+
labels:
51+
namespace: openshift-cluster-version
52+
severity: critical
53+
- alert: CannotRetrieveUpdates
54+
annotations:
55+
summary: Cluster version operator has not retrieved updates in {{ "{{ $value | humanizeDuration }}" }}.
56+
description: Failure to retrieve updates means that cluster administrators will need to monitor for available updates on their own or risk falling behind on security or other bugfixes. If the failure is expected, you can clear spec.channel in the ClusterVersion object to tell the cluster-version operator to not retrieve updates. Failure reason {{ "{{ with $cluster_operator_conditions := \"cluster_operator_conditions\" | query}}{{range $value := .}}{{if and (eq (label \"name\" $value) \"version\") (eq (label \"condition\" $value) \"RetrievedUpdates\") (eq (label \"endpoint\" $value) \"metrics\") (eq (value $value) 0.0)}}{{label \"reason\" $value}} {{end}}{{end}}{{end}}" }}. For more information refer to `oc get clusterversion/version -o=jsonpath="{.status.conditions[?(.type=='RetrievedUpdates')]}{'\n'}"`{{ "{{ with $console_url := \"console_url\" | query }}{{ if ne (len (label \"url\" (first $console_url ) ) ) 0}} or {{ label \"url\" (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}" }}.
57+
expr: |
58+
max by (namespace)
59+
(
60+
(
61+
time()-cluster_version_operator_update_retrieval_timestamp_seconds
62+
) >= 3600
63+
and ignoring(condition, name, reason)
64+
(cluster_operator_conditions{name="version", condition="RetrievedUpdates", endpoint="metrics", reason!="NoChannel"})
65+
)
66+
labels:
67+
severity: warning
68+
- alert: UpdateAvailable
69+
annotations:
70+
summary: Your upstream update recommendation service recommends you update your cluster.
71+
description: For more information refer to 'oc adm upgrade'{{ "{{ with $console_url := \"console_url\" | query }}{{ if ne (len (label \"url\" (first $console_url ) ) ) 0}} or {{ label \"url\" (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}" }}.
72+
expr: |
73+
sum by (channel, namespace, upstream) (cluster_version_available_updates) > 0
74+
labels:
75+
severity: info
76+
- alert: ClusterReleaseNotAccepted
77+
annotations:
78+
summary: The desired cluster release has not been accepted for at least an hour.
79+
description: The desired cluster release has not been accepted because {{ "{{ $labels.reason }}" }}, and the cluster will continue to reconcile an earlier release instead of moving towards that desired release. For more information refer to 'oc adm upgrade'{{ "{{ with $console_url := \"console_url\" | query }}{{ if ne (len (label \"url\" (first $console_url ) ) ) 0}} or {{ label \"url\" (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}" }}.
80+
expr: |
81+
max by (namespace, name, reason) (cluster_operator_conditions{name="version", condition="ReleaseAccepted", endpoint="metrics"} == 0)
82+
for: 60m
83+
labels:
84+
severity: warning
85+
- name: cluster-operators
86+
rules:
87+
- alert: ClusterNotUpgradeable
88+
annotations:
89+
summary: One or more cluster operators have been blocking minor or major version cluster updates for at least an hour.
90+
description: In most cases, you will still be able to apply patch releases. Reason {{ "{{ with $cluster_operator_conditions := \"cluster_operator_conditions\" | query}}{{range $value := .}}{{if and (eq (label \"name\" $value) \"version\") (eq (label \"condition\" $value) \"Upgradeable\") (eq (label \"endpoint\" $value) \"metrics\") (eq (value $value) 0.0) (ne (len (label \"reason\" $value)) 0) }}{{label \"reason\" $value}}.{{end}}{{end}}{{end}}"}} For more information refer to 'oc adm upgrade'{{ "{{ with $console_url := \"console_url\" | query }}{{ if ne (len (label \"url\" (first $console_url ) ) ) 0}} or {{ label \"url\" (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}" }}.
91+
expr: |
92+
max by (namespace, name, condition, endpoint) (cluster_operator_conditions{name="version", condition="Upgradeable", endpoint="metrics"} == 0)
93+
for: 60m
94+
labels:
95+
severity: info
96+
- alert: ClusterOperatorDown
97+
annotations:
98+
summary: Cluster operator has not been available for 10 minutes.
99+
description: The {{ "{{ $labels.name }}" }} operator may be down or disabled because {{ "{{ $labels.reason }}" }}, and the components it manages may be unavailable or degraded. Cluster upgrades may not complete. For more information refer to '{{ "{{ if eq $labels.name \"version\" }}oc adm upgrade{{ else }}oc get -o yaml clusteroperator {{ $labels.name }}{{ end }}" }}'{{ "{{ with $console_url := \"console_url\" | query }}{{ if ne (len (label \"url\" (first $console_url ) ) ) 0}} or {{ label \"url\" (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}" }}.
100+
runbook_url: https://github.com/openshift/runbooks/blob/master/alerts/cluster-monitoring-operator/ClusterOperatorDown.md
101+
expr: |
102+
max by (namespace, name, reason) (cluster_operator_up{job="cluster-version-operator"} == 0)
103+
for: 10m
104+
labels:
105+
severity: critical
106+
- alert: ClusterOperatorDegraded
107+
annotations:
108+
summary: Cluster operator has been degraded for 30 minutes.
109+
description: The {{ "{{ $labels.name }}" }} operator is degraded because {{ "{{ $labels.reason }}" }}, and the components it manages may have reduced quality of service. Cluster upgrades may not complete. For more information refer to '{{ "{{ if eq $labels.name \"version\" }}oc adm upgrade{{ else }}oc get -o yaml clusteroperator {{ $labels.name }}{{ end }}" }}'{{ "{{ with $console_url := \"console_url\" | query }}{{ if ne (len (label \"url\" (first $console_url ) ) ) 0}} or {{ label \"url\" (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}" }}.
110+
runbook_url: https://github.com/openshift/runbooks/blob/master/alerts/cluster-monitoring-operator/ClusterOperatorDegraded.md
111+
expr: |
112+
max by (namespace, name, reason)
113+
(
114+
(
115+
cluster_operator_conditions{job="cluster-version-operator", name!="version", condition="Degraded"}
116+
or on (namespace, name)
117+
cluster_operator_conditions{job="cluster-version-operator", name="version", condition="Failing"}
118+
or on (namespace, name)
119+
group by (namespace, name) (cluster_operator_up{job="cluster-version-operator"})
120+
) == 1
121+
)
122+
for: 30m
123+
labels:
124+
severity: warning
125+
- alert: ClusterOperatorFlapping
126+
annotations:
127+
summary: Cluster operator up status is changing often.
128+
description: The {{ "{{ $labels.name }}" }} operator behavior might cause upgrades to be unstable. For more information refer to '{{ "{{ if eq $labels.name \"version\" }}oc adm upgrade{{ else }}oc get -o yaml clusteroperator {{ $labels.name }}{{ end }}" }}'{{ "{{ with $console_url := \"console_url\" | query }}{{ if ne (len (label \"url\" (first $console_url ) ) ) 0}} or {{ label \"url\" (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}" }}.
129+
expr: |
130+
max by (namespace, name) (changes(cluster_operator_up{job="cluster-version-operator"}[2m]) > 2)
131+
for: 10m
132+
labels:
133+
severity: warning
134+
- alert: CannotEvaluateConditionalUpdates
135+
annotations:
136+
summary: Cluster Version Operator cannot evaluate conditional update matches for {{ "{{ $value | humanizeDuration }}" }}.
137+
description: Failure to evaluate conditional update matches means that Cluster Version Operator cannot decide whether an update path is recommended or not.
138+
expr: |
139+
max by (version, condition, status, reason)
140+
(
141+
(
142+
time()-cluster_version_conditional_update_condition_seconds{condition="Recommended", status="Unknown"}
143+
) >= 3600
144+
)
145+
labels:
146+
severity: warning
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
apiVersion: console.openshift.io/v1
2+
kind: ConsolePlugin
3+
metadata:
4+
name: openshift-cluster-update-console-plugin
5+
annotations:
6+
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
7+
capability.openshift.io/name: Console
8+
release.openshift.io/feature-set: TechPreviewNoUpgrade
9+
exclude.release.openshift.io/internal-openshift-hosted: "true"
10+
include.release.openshift.io/self-managed-high-availability: "true"
11+
spec:
12+
displayName: Cluster Updates
13+
i18n:
14+
loadType: Preload
15+
backend:
16+
type: Service
17+
service:
18+
name: cluster-update-console-plugin
19+
namespace: openshift-cluster-update-console-plugin
20+
port: https
21+
basePath: /

install/image-references

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
kind: ImageStream
2+
apiVersion: image.openshift.io/v1
3+
spec:
4+
tags:
5+
- name: cluster-update-console-plugin
6+
from:
7+
kind: DockerImage
8+
name: placeholder.url.oc.will.replace.this.example.org:cluster-update-console-plugin

0 commit comments

Comments
 (0)