diff --git a/bootstrap/bootstrap-pod.yaml b/bootstrap/bootstrap-pod.yaml index 580eebd49b..c9fffbdad4 100644 --- a/bootstrap/bootstrap-pod.yaml +++ b/bootstrap/bootstrap-pod.yaml @@ -1,3 +1,5 @@ +# The Pod is deployed as a static Pod during cluster bootstrap by the installer. Static Pods have some notable details, +# such as the fact that the spec cannot refer to API objects, like ServiceAccount and ConfigMap. apiVersion: v1 kind: Pod metadata: diff --git a/cmd/cluster-version-operator/render.go b/cmd/cluster-version-operator/render.go index 068c9a1e3f..2502241c3c 100644 --- a/cmd/cluster-version-operator/render.go +++ b/cmd/cluster-version-operator/render.go @@ -14,9 +14,11 @@ import ( var ( renderCmd = &cobra.Command{ Use: "render", - Short: "Renders the UpdatePayload to disk.", - Long: "", - Run: runRenderCmd, + Short: "Renders and filters release payload manifests for cluster bootstrap.", + Long: `Renders and filters CVO manifests and specific release payload manifests. + +Called by the installer as part of cluster bootstrap to generate the initial manifests related to the CVO.`, + Run: runRenderCmd, } renderOpts struct { diff --git a/install/0000_00_cluster-version-operator_03_roles-default.yaml b/install/0000_00_cluster-version-operator_90_roles-default.yaml similarity index 90% rename from install/0000_00_cluster-version-operator_03_roles-default.yaml rename to install/0000_00_cluster-version-operator_90_roles-default.yaml index 34c14b4602..83cfa5fed4 100644 --- a/install/0000_00_cluster-version-operator_03_roles-default.yaml +++ b/install/0000_00_cluster-version-operator_90_roles-default.yaml @@ -4,6 +4,7 @@ metadata: name: cluster-version-operator annotations: include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/delete: "true" roleRef: kind: ClusterRole name: cluster-admin diff --git a/pkg/payload/render.go b/pkg/payload/render.go index fc075a6e5c..5fae362ebf 100644 --- a/pkg/payload/render.go +++ b/pkg/payload/render.go @@ -21,6 +21,8 @@ import ( "github.com/openshift/api/config" configv1 "github.com/openshift/api/config/v1" "github.com/openshift/library-go/pkg/manifest" + + "github.com/openshift/cluster-version-operator/lib/resourcedelete" ) // Render renders critical manifests from /manifests to outputDir. @@ -148,6 +150,10 @@ func renderDir(renderConfig manifestRenderConfig, idir, odir string, overrides [ klog.Infof("excluding %s because we do not render that group/kind", manifest.String()) } else if err := manifest.Include(nil, requiredFeatureSet, clusterProfile, nil, overrides, enabledFeatureGates, majorVersion); err != nil { klog.Infof("excluding %s: %v", manifest.String(), err) + } else if found, err := resourcedelete.ValidDeleteAnnotation(manifest.Obj.GetAnnotations()); err != nil { + errs = append(errs, fmt.Errorf("invalid delete annotation in %s from %s: %w", manifest.String(), file.Name(), err)) + } else if found { + klog.Infof("excluding %s because we do not render manifests with the delete annotation", manifest.String()) } else { filteredManifests = append(filteredManifests, string(manifest.Raw)) klog.Infof("including %s", manifest.String()) diff --git a/pkg/payload/render_test.go b/pkg/payload/render_test.go index 10882dd798..1b22866f32 100644 --- a/pkg/payload/render_test.go +++ b/pkg/payload/render_test.go @@ -65,13 +65,14 @@ func TestRenderManifest(t *testing.T) { } } -func TestRenderDirWithMajorVersionFiltering(t *testing.T) { +func TestRenderDirFiltering(t *testing.T) { tests := []struct { name string manifests []testManifest majorVersion *uint64 expectedInclusions []string // Names of manifests that should be included expectedExclusions []string // Names of manifests that should be excluded + expectError bool // Whether an error is expected }{ { name: "major version 4 includes version 4 manifests", @@ -183,6 +184,49 @@ func TestRenderDirWithMajorVersionFiltering(t *testing.T) { expectedInclusions: []string{"version4-or-5-manifest", "exclude-version3-manifest"}, expectedExclusions: []string{"version6-only-manifest"}, }, + { + name: "delete annotation excludes manifests", + manifests: []testManifest{ + { + name: "normal-manifest", + annotations: map[string]string{}, + }, + { + name: "deleted-manifest", + annotations: map[string]string{ + "release.openshift.io/delete": "true", + }, + }, + { + name: "another-normal-manifest", + annotations: map[string]string{ + "some.other.annotation": "value", + }, + }, + }, + majorVersion: ptr.To(uint64(4)), + expectedInclusions: []string{"normal-manifest", "another-normal-manifest"}, + expectedExclusions: []string{"deleted-manifest"}, + }, + { + name: "invalid delete annotation value returns error but continues rendering", + manifests: []testManifest{ + { + name: "normal-manifest", + annotations: map[string]string{}, + }, + { + name: "invalid-delete-manifest", + annotations: map[string]string{ + "release.openshift.io/delete": "false", + }, + }, + }, + majorVersion: ptr.To(uint64(4)), + expectedInclusions: []string{"normal-manifest"}, + expectedExclusions: []string{"invalid-delete-manifest"}, + expectError: true, + }, } for _, tt := range tests { @@ -233,8 +277,14 @@ func TestRenderDirWithMajorVersionFiltering(t *testing.T) { sets.Set[schema.GroupKind]{}, // filterGroupKind ) - if err != nil { - t.Fatalf("renderDir failed: %v", err) + if tt.expectError { + if err == nil { + t.Errorf("expected error but got none") + } + } else { + if err != nil { + t.Fatalf("renderDir failed: %v", err) + } } // Check which manifests were included in output