Skip to content

Commit 8d5bce1

Browse files
jhadvigclaude
andcommitted
install: Add TechPreviewNoUpgrade cluster-update console plugin
Add manifests to deploy the cluster-update-console-plugin, a web console interface for managing ClusterVersion updates. The plugin is gated behind the TechPreviewNoUpgrade feature set and the Console capability. Manifests include: namespace, serviceaccount, networkpolicy, deployment, service, and consoleplugin resources. The deployment uses readiness and liveness probes, a read-only root filesystem with emptyDir volumes for nginx runtime directories, and a serving-cert annotation for TLS. Extend manifestRenderConfig with an Images map populated from the release payload's image-references, so CVO manifests can resolve component images by short name at deploy time using Go template syntax: {{index .Images "cluster-update-console-plugin"}}. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4cfd94b commit 8d5bce1

10 files changed

Lines changed: 201 additions & 2 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: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v1
2+
kind: ServiceAccount
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"
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: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
serviceAccountName: cluster-update-console-plugin
30+
automountServiceAccountToken: false
31+
containers:
32+
- name: plugin
33+
image: '{{index .Images "cluster-update-console-plugin"}}'
34+
imagePullPolicy: IfNotPresent
35+
ports:
36+
- name: https
37+
containerPort: 9001
38+
readinessProbe:
39+
httpGet:
40+
path: /
41+
port: https
42+
scheme: HTTPS
43+
livenessProbe:
44+
httpGet:
45+
path: /
46+
port: https
47+
scheme: HTTPS
48+
resources:
49+
requests:
50+
cpu: 20m
51+
memory: 50Mi
52+
securityContext:
53+
allowPrivilegeEscalation: false
54+
capabilities:
55+
drop:
56+
- ALL
57+
terminationMessagePolicy: FallbackToLogsOnError
58+
volumeMounts:
59+
- mountPath: /var/cert
60+
name: cluster-update-console-plugin-cert
61+
readOnly: true
62+
dnsPolicy: Default
63+
hostUsers: false
64+
priorityClassName: system-cluster-critical
65+
securityContext:
66+
runAsNonRoot: true
67+
seccompProfile:
68+
type: RuntimeDefault
69+
terminationGracePeriodSeconds: 30
70+
tolerations:
71+
- effect: NoSchedule
72+
key: node-role.kubernetes.io/infra
73+
operator: Exists
74+
volumes:
75+
- name: cluster-update-console-plugin-cert
76+
secret:
77+
defaultMode: 420
78+
secretName: cluster-update-console-plugin-cert
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
service.beta.openshift.io/serving-cert-secret-name: cluster-update-console-plugin-cert
9+
capability.openshift.io/name: Console
10+
release.openshift.io/feature-set: TechPreviewNoUpgrade
11+
exclude.release.openshift.io/internal-openshift-hosted: "true"
12+
include.release.openshift.io/self-managed-high-availability: "true"
13+
spec:
14+
type: ClusterIP
15+
selector:
16+
app: cluster-update-console-plugin
17+
ports:
18+
- name: https
19+
port: 9001
20+
targetPort: https
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: openshift-cluster-update-console-plugin
19+
namespace: openshift-cluster-update-console-plugin
20+
port: 9001
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

pkg/payload/payload.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func LoadUpdate(dir, releaseImage, excludeIdentifier string, requiredFeatureSet
153153
return nil, err
154154
}
155155

156-
tasks := loadPayloadTasks(releaseDir, cvoDir, releaseImage, profile)
156+
tasks := loadPayloadTasks(releaseDir, cvoDir, releaseImage, profile, payload.ImageRef)
157157

158158
var onlyKnownCaps *configv1.ClusterVersionCapabilitiesStatus
159159

@@ -317,13 +317,14 @@ type payloadTasks struct {
317317
skipFiles sets.Set[string]
318318
}
319319

320-
func loadPayloadTasks(releaseDir, cvoDir, releaseImage, clusterProfile string) []payloadTasks {
320+
func loadPayloadTasks(releaseDir, cvoDir, releaseImage, clusterProfile string, imageRef *imagev1.ImageStream) []payloadTasks {
321321
cjf := filepath.Join(releaseDir, cincinnatiJSONFile)
322322
irf := filepath.Join(releaseDir, imageReferencesFile)
323323

324324
mrc := manifestRenderConfig{
325325
ReleaseImage: releaseImage,
326326
ClusterProfile: clusterProfile,
327+
Images: imagesFromImageRef(imageRef),
327328
}
328329

329330
return []payloadTasks{{

pkg/payload/render.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"github.com/openshift/api/config"
2222
configv1 "github.com/openshift/api/config/v1"
23+
imagev1 "github.com/openshift/api/image/v1"
2324
"github.com/openshift/library-go/pkg/manifest"
2425
)
2526

@@ -38,6 +39,12 @@ func Render(outputDir, releaseImage, clusterVersionManifestPath, featureGateMani
3839
}
3940
)
4041

42+
imageRef, err := loadImageReferences(releaseManifestsDir)
43+
if err != nil {
44+
return fmt.Errorf("error loading image references for manifest rendering: %w", err)
45+
}
46+
renderConfig.Images = imagesFromImageRef(imageRef)
47+
4148
overrides, err := parseClusterVersionManifest(clusterVersionManifestPath)
4249
if err != nil {
4350
return fmt.Errorf("error parsing cluster version manifest: %w", err)
@@ -181,6 +188,21 @@ func renderDir(renderConfig manifestRenderConfig, idir, odir string, overrides [
181188
type manifestRenderConfig struct {
182189
ReleaseImage string
183190
ClusterProfile string
191+
Images map[string]string
192+
}
193+
194+
// imagesFromImageRef builds a map from image short names to their resolved URIs.
195+
func imagesFromImageRef(imageRef *imagev1.ImageStream) map[string]string {
196+
images := make(map[string]string)
197+
if imageRef == nil {
198+
return images
199+
}
200+
for _, tag := range imageRef.Spec.Tags {
201+
if tag.From != nil && tag.From.Kind == "DockerImage" {
202+
images[tag.Name] = tag.From.Name
203+
}
204+
}
205+
return images
184206
}
185207

186208
// renderManifest Executes go text template from `manifestBytes` with `config`.

pkg/payload/render_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ func Test_cvoManifests(t *testing.T) {
313313
config := manifestRenderConfig{
314314
ReleaseImage: "quay.io/cvo/release:latest",
315315
ClusterProfile: "some-profile",
316+
Images: map[string]string{
317+
"cluster-update-console-plugin": "quay.io/openshift/cluster-update-console-plugin:latest",
318+
},
316319
}
317320

318321
tests := []struct {
@@ -341,6 +344,10 @@ func Test_cvoManifests(t *testing.T) {
341344
return nil
342345
}
343346

347+
if _, fileName := filepath.Split(path); fileName == "image-references" {
348+
return nil
349+
}
350+
344351
var manifestsWithoutIncludeAnnotation []manifest.Manifest
345352
data, err := os.ReadFile(path)
346353
if err != nil {

0 commit comments

Comments
 (0)