From 4d88c69629f7084459a9ba986ed0adfd30b455b8 Mon Sep 17 00:00:00 2001 From: Joe Lanford Date: Mon, 28 Aug 2023 16:25:25 -0400 Subject: [PATCH] Remove Package and BundleMetadata APIs Signed-off-by: Joe Lanford --- README.md | 114 +++---- api/core/v1alpha1/bundlemetadata_types.go | 88 ----- api/core/v1alpha1/package_types.go | 97 ------ api/core/v1alpha1/zz_generated.deepcopy.go | 301 ------------------ ...d.operatorframework.io_bundlemetadata.yaml | 96 ------ ...atalogd.operatorframework.io_packages.yaml | 115 ------- config/crd/kustomization.yaml | 4 +- config/default/manager_auth_proxy_patch.yaml | 3 +- config/rbac/role.yaml | 52 --- hack/scripts/generate-asciidemo.sh | 26 +- pkg/controllers/core/catalog_controller.go | 189 ----------- .../core/catalog_controller_test.go | 147 +-------- pkg/features/features.go | 5 +- pprof/README.md | 4 + test/e2e/unpack_test.go | 112 +++++-- 15 files changed, 164 insertions(+), 1189 deletions(-) delete mode 100644 api/core/v1alpha1/bundlemetadata_types.go delete mode 100644 api/core/v1alpha1/package_types.go delete mode 100644 config/crd/bases/catalogd.operatorframework.io_bundlemetadata.yaml delete mode 100644 config/crd/bases/catalogd.operatorframework.io_packages.yaml diff --git a/README.md b/README.md index 7727f86c..9b7c329b 100644 --- a/README.md +++ b/README.md @@ -91,74 +91,80 @@ Catalogd helps customers discover installable content by hosting catalog metadat Events: ``` -1. Run the following command to get a list of packages: `*` +1. Run the following command to get a list of packages: ```sh - $ kubectl get packages + $ kubectl get catalogmetadata -l schema=olm.package ``` *Example output* ```sh - NAME AGE - operatorhubio-ack-acm-controller 69s - operatorhubio-ack-apigatewayv2-controller 69s - operatorhubio-ack-applicationautoscaling-controller 69s - operatorhubio-ack-cloudtrail-controller 69s - operatorhubio-ack-dynamodb-controller 69s - operatorhubio-ack-ec2-controller 69s - operatorhubio-ack-ecr-controller 69s - operatorhubio-ack-eks-controller 69s - operatorhubio-ack-elasticache-controller 69s - operatorhubio-ack-emrcontainers-controller 69s - operatorhubio-ack-eventbridge-controller 69s - operatorhubio-ack-iam-controller 69s - operatorhubio-ack-kinesis-controller 69s - operatorhubio-ack-kms-controller 69s - operatorhubio-ack-lambda-controller 69s - operatorhubio-ack-memorydb-controller 69s - operatorhubio-ack-mq-controller 69s + NAME AGE + operatorhubio-olm.package-ack-acm-controller 18m + operatorhubio-olm.package-ack-apigatewayv2-controller 18m + operatorhubio-olm.package-ack-applicationautoscaling-controller 18m + operatorhubio-olm.package-ack-cloudtrail-controller 18m + operatorhubio-olm.package-ack-cloudwatch-controller 18m + operatorhubio-olm.package-ack-dynamodb-controller 18m + operatorhubio-olm.package-ack-ec2-controller 18m + operatorhubio-olm.package-ack-ecr-controller 18m + operatorhubio-olm.package-ack-eks-controller 18m + operatorhubio-olm.package-ack-elasticache-controller 18m + operatorhubio-olm.package-ack-emrcontainers-controller 18m + operatorhubio-olm.package-ack-eventbridge-controller 18m + operatorhubio-olm.package-ack-iam-controller 18m + operatorhubio-olm.package-ack-kinesis-controller 18m ... ``` -1. Run the following command to get a list of bundles: `*` +1. Run the following command to get a list of channels: ```sh - $ kubectl get bundlemetadata + $ kubectl get catalogmetadata -l olm.channel + ``` + + *Example output* + ```sh + NAME AGE + operatorhubio-olm.channel-ack-acm-controller-alpha 21m + operatorhubio-olm.channel-ack-apigatewayv2-controller-alpha 21m + operatorhubio-olm.channel-ack-applicationautoscaling-controller-alpha 21m + operatorhubio-olm.channel-ack-cloudtrail-controller-alpha 21m + operatorhubio-olm.channel-ack-cloudwatch-controller-alpha 21m + operatorhubio-olm.channel-ack-dynamodb-controller-alpha 21m + operatorhubio-olm.channel-ack-ec2-controller-alpha 21m + operatorhubio-olm.channel-ack-ecr-controller-alpha 21m + operatorhubio-olm.channel-ack-eks-controller-alpha 21m + operatorhubio-olm.channel-ack-elasticache-controller-alpha 21m + operatorhubio-olm.channel-ack-emrcontainers-controller-alpha 21m + operatorhubio-olm.channel-ack-eventbridge-controller-alpha 21m + operatorhubio-olm.channel-ack-iam-controller-alpha 21m + operatorhubio-olm.channel-ack-kinesis-controller-alpha 21m + ... + ``` + +1. Run the following command to get a list of bundles: + + ```sh + $ kubectl get catalogmetadata -l olm.bundle ``` *Example output* ```sh - NAME AGE - operatorhubio-ack-acm-controller.v0.0.1 2m15s - operatorhubio-ack-acm-controller.v0.0.2 2m15s - operatorhubio-ack-acm-controller.v0.0.4 2m15s - operatorhubio-ack-acm-controller.v0.0.5 2m15s - operatorhubio-ack-acm-controller.v0.0.6 2m15s - operatorhubio-ack-acm-controller.v0.0.7 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.10 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.11 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.12 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.13 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.14 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.15 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.16 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.17 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.18 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.19 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.20 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.21 2m15s - operatorhubio-ack-apigatewayv2-controller.v0.0.22 2m14s - operatorhubio-ack-apigatewayv2-controller.v0.0.9 2m14s - operatorhubio-ack-apigatewayv2-controller.v0.1.0 2m14s - operatorhubio-ack-apigatewayv2-controller.v0.1.1 2m14s - operatorhubio-ack-apigatewayv2-controller.v0.1.2 2m14s - operatorhubio-ack-apigatewayv2-controller.v0.1.3 2m14s - operatorhubio-ack-apigatewayv2-controller.v0.1.4 2m14s - operatorhubio-ack-apigatewayv2-controller.v0.1.5 2m14s - operatorhubio-ack-apigatewayv2-controller.v0.1.6 2m14s - operatorhubio-ack-apigatewayv2-controller.v1.0.0 2m14s - operatorhubio-ack-apigatewayv2-controller.v1.0.2 2m14s - operatorhubio-ack-apigatewayv2-controller.v1.0.3 2m14s - operatorhubio-ack-apigatewayv2-controller.v1.0.4 2m14s + NAME AGE + operatorhubio-olm.bundle-ack-acm-controller-ack-acm-controller.v0.0.1 19m + operatorhubio-olm.bundle-ack-acm-controller-ack-acm-controller.v0.0.2 19m + operatorhubio-olm.bundle-ack-acm-controller-ack-acm-controller.v0.0.4 19m + operatorhubio-olm.bundle-ack-acm-controller-ack-acm-controller.v0.0.5 19m + operatorhubio-olm.bundle-ack-acm-controller-ack-acm-controller.v0.0.6 19m + operatorhubio-olm.bundle-ack-acm-controller-ack-acm-controller.v0.0.7 19m + operatorhubio-olm.bundle-ack-apigatewayv2-controller-ack-apigatewayv2-controller.v0.0.10 19m + operatorhubio-olm.bundle-ack-apigatewayv2-controller-ack-apigatewayv2-controller.v0.0.11 19m + operatorhubio-olm.bundle-ack-apigatewayv2-controller-ack-apigatewayv2-controller.v0.0.12 19m + operatorhubio-olm.bundle-ack-apigatewayv2-controller-ack-apigatewayv2-controller.v0.0.13 19m + operatorhubio-olm.bundle-ack-apigatewayv2-controller-ack-apigatewayv2-controller.v0.0.14 19m + operatorhubio-olm.bundle-ack-apigatewayv2-controller-ack-apigatewayv2-controller.v0.0.15 19m + operatorhubio-olm.bundle-ack-apigatewayv2-controller-ack-apigatewayv2-controller.v0.0.16 19m + operatorhubio-olm.bundle-ack-apigatewayv2-controller-ack-apigatewayv2-controller.v0.0.17 19m ... ``` diff --git a/api/core/v1alpha1/bundlemetadata_types.go b/api/core/v1alpha1/bundlemetadata_types.go deleted file mode 100644 index ef4c9a2b..00000000 --- a/api/core/v1alpha1/bundlemetadata_types.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - "encoding/json" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -//+kubebuilder:object:root=true -//+kubebuilder:resource:scope=Cluster - -// BundleMetadata is the Schema for the bundlemetadata API -type BundleMetadata struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BundleMetadataSpec `json:"spec,omitempty"` - Status BundleMetadataStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// BundleMetadataList contains a list of BundleMetadata -type BundleMetadataList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - - Items []BundleMetadata `json:"items"` -} - -// BundleMetadataSpec defines the desired state of BundleMetadata -type BundleMetadataSpec struct { - // Catalog is the name of the Catalog that provides this bundle - Catalog corev1.LocalObjectReference `json:"catalog"` - - // Package is the name of the package that provides this bundle - Package string `json:"package"` - - // Image is a reference to the image that provides the bundle contents - Image string `json:"image"` - - // Properties is a string of references to property objects that are part of the bundle - Properties []Property `json:"properties,omitempty"` - - // RelatedImages are the RelatedImages in the bundle - RelatedImages []RelatedImage `json:"relatedImages,omitempty"` -} - -type Property struct { - Type string `json:"type"` - - // +kubebuilder:pruning:PreserveUnknownFields - // +kubebuilder:validation:Schemaless - Value json.RawMessage `json:"value"` -} - -// TODO: In the future we should remove this in favor of using `declcfg.RelatedImage` (or similar) from -// https://pkg.go.dev/github.com/operator-framework/operator-registry@v1.26.3/alpha/declcfg#RelatedImage -// This will likely require some changes to the `declcfg.RelatedImage` type -// to make it suitable for usage within the Spec for a CustomResource -type RelatedImage struct { - Name string `json:"name"` - Image string `json:"image"` -} - -// BundleMetadataStatus defines the observed state of BundleMetadata -type BundleMetadataStatus struct{} - -func init() { - SchemeBuilder.Register(&BundleMetadata{}, &BundleMetadataList{}) -} diff --git a/api/core/v1alpha1/package_types.go b/api/core/v1alpha1/package_types.go deleted file mode 100644 index 236eac3c..00000000 --- a/api/core/v1alpha1/package_types.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -//+kubebuilder:object:root=true -//+kubebuilder:resource:scope=Cluster - -// Package is the Schema for the packages API -type Package struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec PackageSpec `json:"spec,omitempty"` - Status PackageStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// PackageList contains a list of Package -type PackageList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - - Items []Package `json:"items"` -} - -// PackageSpec defines the desired state of Package -type PackageSpec struct { - // Catalog is the name of the Catalog this package belongs to - Catalog corev1.LocalObjectReference `json:"catalog"` - - // Name is the name of the package, ala `etcd`. - Name string `json:"packageName"` - - // Description is the description of the package - Description string `json:"description"` - - // Channels are the declared channels for the package, ala `stable` or `alpha`. - Channels []PackageChannel `json:"channels"` - - //Icon is the Base64data image of the package for console display - Icon *Icon `json:"icon,omitempty"` - - // DefaultChannel is, if specified, the name of the default channel for the package. The - // default channel will be installed if no other channel is explicitly given. If the package - // has a single channel, then that channel is implicitly the default. - DefaultChannel string `json:"defaultChannel"` -} - -// PackageChannel defines a single channel under a package, pointing to a version of that -// package. -type PackageChannel struct { - // Name is the name of the channel, e.g. `alpha` or `stable` - Name string `json:"name"` - - // Entries is all the channel entries within a channel - Entries []ChannelEntry `json:"entries"` -} - -type ChannelEntry struct { - Name string `json:"name"` - Replaces string `json:"replaces,omitempty"` - Skips []string `json:"skips,omitempty"` - SkipRange string `json:"skipRange,omitempty"` -} - -// Icon defines a base64 encoded icon and media type -type Icon struct { - Data []byte `json:"data,omitempty"` - MediaType string `json:"mediatype,omitempty"` -} - -// PackageStatus defines the observed state of Package -type PackageStatus struct{} - -func init() { - SchemeBuilder.Register(&Package{}, &PackageList{}) -} diff --git a/api/core/v1alpha1/zz_generated.deepcopy.go b/api/core/v1alpha1/zz_generated.deepcopy.go index c6f04589..3b4d2ed7 100644 --- a/api/core/v1alpha1/zz_generated.deepcopy.go +++ b/api/core/v1alpha1/zz_generated.deepcopy.go @@ -27,108 +27,6 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BundleMetadata) DeepCopyInto(out *BundleMetadata) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleMetadata. -func (in *BundleMetadata) DeepCopy() *BundleMetadata { - if in == nil { - return nil - } - out := new(BundleMetadata) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BundleMetadata) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BundleMetadataList) DeepCopyInto(out *BundleMetadataList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]BundleMetadata, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleMetadataList. -func (in *BundleMetadataList) DeepCopy() *BundleMetadataList { - if in == nil { - return nil - } - out := new(BundleMetadataList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BundleMetadataList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BundleMetadataSpec) DeepCopyInto(out *BundleMetadataSpec) { - *out = *in - out.Catalog = in.Catalog - if in.Properties != nil { - in, out := &in.Properties, &out.Properties - *out = make([]Property, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.RelatedImages != nil { - in, out := &in.RelatedImages, &out.RelatedImages - *out = make([]RelatedImage, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleMetadataSpec. -func (in *BundleMetadataSpec) DeepCopy() *BundleMetadataSpec { - if in == nil { - return nil - } - out := new(BundleMetadataSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BundleMetadataStatus) DeepCopyInto(out *BundleMetadataStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleMetadataStatus. -func (in *BundleMetadataStatus) DeepCopy() *BundleMetadataStatus { - if in == nil { - return nil - } - out := new(BundleMetadataStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Catalog) DeepCopyInto(out *Catalog) { *out = *in @@ -330,46 +228,6 @@ func (in *CatalogStatus) DeepCopy() *CatalogStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ChannelEntry) DeepCopyInto(out *ChannelEntry) { - *out = *in - if in.Skips != nil { - in, out := &in.Skips, &out.Skips - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelEntry. -func (in *ChannelEntry) DeepCopy() *ChannelEntry { - if in == nil { - return nil - } - out := new(ChannelEntry) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Icon) DeepCopyInto(out *Icon) { - *out = *in - if in.Data != nil { - in, out := &in.Data, &out.Data - *out = make([]byte, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Icon. -func (in *Icon) DeepCopy() *Icon { - if in == nil { - return nil - } - out := new(Icon) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImageSource) DeepCopyInto(out *ImageSource) { *out = *in @@ -384,162 +242,3 @@ func (in *ImageSource) DeepCopy() *ImageSource { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Package) DeepCopyInto(out *Package) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Package. -func (in *Package) DeepCopy() *Package { - if in == nil { - return nil - } - out := new(Package) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Package) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageChannel) DeepCopyInto(out *PackageChannel) { - *out = *in - if in.Entries != nil { - in, out := &in.Entries, &out.Entries - *out = make([]ChannelEntry, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageChannel. -func (in *PackageChannel) DeepCopy() *PackageChannel { - if in == nil { - return nil - } - out := new(PackageChannel) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageList) DeepCopyInto(out *PackageList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Package, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageList. -func (in *PackageList) DeepCopy() *PackageList { - if in == nil { - return nil - } - out := new(PackageList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PackageList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSpec) DeepCopyInto(out *PackageSpec) { - *out = *in - out.Catalog = in.Catalog - if in.Channels != nil { - in, out := &in.Channels, &out.Channels - *out = make([]PackageChannel, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Icon != nil { - in, out := &in.Icon, &out.Icon - *out = new(Icon) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSpec. -func (in *PackageSpec) DeepCopy() *PackageSpec { - if in == nil { - return nil - } - out := new(PackageSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageStatus) DeepCopyInto(out *PackageStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageStatus. -func (in *PackageStatus) DeepCopy() *PackageStatus { - if in == nil { - return nil - } - out := new(PackageStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Property) DeepCopyInto(out *Property) { - *out = *in - if in.Value != nil { - in, out := &in.Value, &out.Value - *out = make(json.RawMessage, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Property. -func (in *Property) DeepCopy() *Property { - if in == nil { - return nil - } - out := new(Property) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RelatedImage) DeepCopyInto(out *RelatedImage) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RelatedImage. -func (in *RelatedImage) DeepCopy() *RelatedImage { - if in == nil { - return nil - } - out := new(RelatedImage) - in.DeepCopyInto(out) - return out -} diff --git a/config/crd/bases/catalogd.operatorframework.io_bundlemetadata.yaml b/config/crd/bases/catalogd.operatorframework.io_bundlemetadata.yaml deleted file mode 100644 index fd68c7a7..00000000 --- a/config/crd/bases/catalogd.operatorframework.io_bundlemetadata.yaml +++ /dev/null @@ -1,96 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.12.0 - name: bundlemetadata.catalogd.operatorframework.io -spec: - group: catalogd.operatorframework.io - names: - kind: BundleMetadata - listKind: BundleMetadataList - plural: bundlemetadata - singular: bundlemetadata - scope: Cluster - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: BundleMetadata is the Schema for the bundlemetadata API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: BundleMetadataSpec defines the desired state of BundleMetadata - properties: - catalog: - description: Catalog is the name of the Catalog that provides this - bundle - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - image: - description: Image is a reference to the image that provides the bundle - contents - type: string - package: - description: Package is the name of the package that provides this - bundle - type: string - properties: - description: Properties is a string of references to property objects - that are part of the bundle - items: - properties: - type: - type: string - value: - x-kubernetes-preserve-unknown-fields: true - required: - - type - - value - type: object - type: array - relatedImages: - description: RelatedImages are the RelatedImages in the bundle - items: - description: 'TODO: In the future we should remove this in favor - of using `declcfg.RelatedImage` (or similar) from https://pkg.go.dev/github.com/operator-framework/operator-registry@v1.26.3/alpha/declcfg#RelatedImage - This will likely require some changes to the `declcfg.RelatedImage` - type to make it suitable for usage within the Spec for a CustomResource' - properties: - image: - type: string - name: - type: string - required: - - image - - name - type: object - type: array - required: - - catalog - - image - - package - type: object - status: - description: BundleMetadataStatus defines the observed state of BundleMetadata - type: object - type: object - served: true - storage: true diff --git a/config/crd/bases/catalogd.operatorframework.io_packages.yaml b/config/crd/bases/catalogd.operatorframework.io_packages.yaml deleted file mode 100644 index c985eb15..00000000 --- a/config/crd/bases/catalogd.operatorframework.io_packages.yaml +++ /dev/null @@ -1,115 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.12.0 - name: packages.catalogd.operatorframework.io -spec: - group: catalogd.operatorframework.io - names: - kind: Package - listKind: PackageList - plural: packages - singular: package - scope: Cluster - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Package is the Schema for the packages API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: PackageSpec defines the desired state of Package - properties: - catalog: - description: Catalog is the name of the Catalog this package belongs - to - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - channels: - description: Channels are the declared channels for the package, ala - `stable` or `alpha`. - items: - description: PackageChannel defines a single channel under a package, - pointing to a version of that package. - properties: - entries: - description: Entries is all the channel entries within a channel - items: - properties: - name: - type: string - replaces: - type: string - skipRange: - type: string - skips: - items: - type: string - type: array - required: - - name - type: object - type: array - name: - description: Name is the name of the channel, e.g. `alpha` or - `stable` - type: string - required: - - entries - - name - type: object - type: array - defaultChannel: - description: DefaultChannel is, if specified, the name of the default - channel for the package. The default channel will be installed if - no other channel is explicitly given. If the package has a single - channel, then that channel is implicitly the default. - type: string - description: - description: Description is the description of the package - type: string - icon: - description: Icon is the Base64data image of the package for console - display - properties: - data: - format: byte - type: string - mediatype: - type: string - type: object - packageName: - description: Name is the name of the package, ala `etcd`. - type: string - required: - - catalog - - channels - - defaultChannel - - description - - packageName - type: object - status: - description: PackageStatus defines the observed state of Package - type: object - type: object - served: true - storage: true diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 62eb52ff..41af6421 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -2,8 +2,6 @@ # since it depends on service name and namespace that are out of this kustomize package. # It should be run by config/default resources: -- bases/catalogd.operatorframework.io_bundlemetadata.yaml -- bases/catalogd.operatorframework.io_packages.yaml - bases/catalogd.operatorframework.io_catalogs.yaml - bases/catalogd.operatorframework.io_catalogmetadata.yaml #+kubebuilder:scaffold:crdkustomizeresource @@ -14,4 +12,4 @@ patches: group: apiextensions.k8s.io version: v1 kind: CustomResourceDefinition - name: catalogs.catalogd.operatorframework.io \ No newline at end of file + name: catalogs.catalogd.operatorframework.io diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml index 3bd84262..817eabf3 100644 --- a/config/default/manager_auth_proxy_patch.yaml +++ b/config/default/manager_auth_proxy_patch.yaml @@ -50,5 +50,4 @@ spec: - "--health-probe-bind-address=:8081" - "--metrics-bind-address=127.0.0.1:8080" - "--leader-elect" - - "--feature-gates=PackagesBundleMetadataAPIs=true,CatalogMetadataAPI=true" - + - "--feature-gates=CatalogMetadataAPI=true" diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 689e67ff..de78dd1c 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -4,32 +4,6 @@ kind: ClusterRole metadata: name: manager-role rules: -- apiGroups: - - catalogd.operatorframework.io - resources: - - bundlemetadata - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - catalogd.operatorframework.io - resources: - - bundlemetadata/finalizers - verbs: - - update -- apiGroups: - - catalogd.operatorframework.io - resources: - - bundlemetadata/status - verbs: - - get - - patch - - update - apiGroups: - catalogd.operatorframework.io resources: @@ -68,32 +42,6 @@ rules: - get - patch - update -- apiGroups: - - catalogd.operatorframework.io - resources: - - packages - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - catalogd.operatorframework.io - resources: - - packages/finalizers - verbs: - - update -- apiGroups: - - catalogd.operatorframework.io - resources: - - packages/status - verbs: - - get - - patch - - update - apiGroups: - "" resources: diff --git a/hack/scripts/generate-asciidemo.sh b/hack/scripts/generate-asciidemo.sh index 56ae6ad0..4ddf8f8d 100755 --- a/hack/scripts/generate-asciidemo.sh +++ b/hack/scripts/generate-asciidemo.sh @@ -20,26 +20,26 @@ function run() { sleep 10 typeline "make install" sleep 10 - # inspect crds (catalog, package, bundlemetadata) - #k get crds catalogs.catalogd.operatorframework.io - #k get crds packages.catalogd.operatorframework.io - #k get crds bundlemetadata.catalogd.operatorframework.io - #typeline 'kubectl get crds -A| grep -A10 -B10 -E "catalogs|packages|bundlemetadata"' + # inspect crds (catalog, catalogmetadata) typeline 'kubectl get crds -A' typeline -x "# create a catalog" typeline "kubectl apply -f config/samples/core_v1alpha1_catalog.yaml" # or other typeline "kubectl get catalog -A" # shows catalog-sample typeline -x "# waiting for catalog to report ready status" - typeline "kubectl wait --for=condition=Ready catalog/catalog-sample --timeout=1h" - # inspect packages, and then details on one package CR + typeline "kubectl wait --for=condition=Unpacked catalog/operatorhubio --timeout=1h" + # inspect packages, and then details on one package typeline -x "# check what 'packages' are available in this catalog and then inspect the content of one of the packages" - typeline "kubectl get packages" - typeline "kubectl get packages wavefront -o yaml" - # inspect bundlemetadata, and then details on one bundlemetadata CR - typeline -x "# check what bundles are included in those packages and then inspect the content of the wavefront-operator.v0.1.0 bundle included in the 'wavefront' package we just inspected" - typeline "kubectl get bundlemetadata" - typeline "kubectl get bundlemetadata wavefront-operator.v0.1.0 -o yaml" + typeline "kubectl get catalogmetadata -l schema=olm.package" + typeline "kubectl get catalogmetadata operatorhubio-olm.package-wavefront -o yaml" + # inspect channels, and then details on one channel + typeline -x "# check what channels are included in the wavefront package and then inspect the content of the alpha channel" + typeline "kubectl get catalogmetadata -l schema=olm.channel,package=wavefront" + typeline "kubectl get catalogmetadata operatorhubio-olm.channel-wavefront-alpha -o yaml" + # inspect bundles, and then details on one bundle + typeline -x "# check what bundles are included in the wavefront package and then inspect the content of the wavefront-operator.v0.1.0 bundle" + typeline "kubectl get catalogmetadata -l schema=olm.bundle,package=wavefront" + typeline "kubectl get catalogmetadata operatorhubio-olm.bundle-wavefront-wavefront-operator.v0.1.0 -o yaml" } run diff --git a/pkg/controllers/core/catalog_controller.go b/pkg/controllers/core/catalog_controller.go index ec11a16e..4d478489 100644 --- a/pkg/controllers/core/catalog_controller.go +++ b/pkg/controllers/core/catalog_controller.go @@ -56,12 +56,6 @@ type CatalogReconciler struct { //+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=catalogs,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=catalogs/status,verbs=get;update;patch //+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=catalogs/finalizers,verbs=update -//+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=bundlemetadata,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=bundlemetadata/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=bundlemetadata/finalizers,verbs=update -//+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=packages,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=packages/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=packages/finalizers,verbs=update //+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=catalogmetadata,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core,resources=pods,verbs=create;update;patch;delete;get;list;watch //+kubebuilder:rbac:groups=core,resources=pods/log,verbs=get;list;watch @@ -143,22 +137,6 @@ func (r *CatalogReconciler) reconcile(ctx context.Context, catalog *v1alpha1.Cat // TODO: We should check to see if the unpacked result has the same content // as the already unpacked content. If it does, we should skip this rest // of the unpacking steps. - - fbc, err := declcfg.LoadFS(unpackResult.FS) - if err != nil { - return ctrl.Result{}, updateStatusUnpackFailing(&catalog.Status, fmt.Errorf("load FBC from filesystem: %v", err)) - } - - if features.CatalogdFeatureGate.Enabled(features.PackagesBundleMetadataAPIs) { - if err := r.syncPackages(ctx, fbc, catalog); err != nil { - return ctrl.Result{}, updateStatusUnpackFailing(&catalog.Status, fmt.Errorf("create package objects: %v", err)) - } - - if err := r.syncBundleMetadata(ctx, fbc, catalog); err != nil { - return ctrl.Result{}, updateStatusUnpackFailing(&catalog.Status, fmt.Errorf("create bundle metadata objects: %v", err)) - } - } - if features.CatalogdFeatureGate.Enabled(features.CatalogMetadataAPI) { if err = r.syncCatalogMetadata(ctx, unpackResult.FS, catalog); err != nil { return ctrl.Result{}, updateStatusUnpackFailing(&catalog.Status, fmt.Errorf("create catalog metadata objects: %v", err)) @@ -217,173 +195,6 @@ func updateStatusUnpackFailing(status *v1alpha1.CatalogStatus, err error) error return err } -// syncBundleMetadata will create a `BundleMetadata` resource for each -// "olm.bundle" object that exists for the given catalog contents. Returns an -// error if any are encountered. -func (r *CatalogReconciler) syncBundleMetadata(ctx context.Context, declCfg *declcfg.DeclarativeConfig, catalog *v1alpha1.Catalog) error { - newBundles := map[string]*v1alpha1.BundleMetadata{} - - for _, bundle := range declCfg.Bundles { - bundleName, _ := k8sutil.MetadataName(fmt.Sprintf("%s-%s", catalog.Name, bundle.Name)) - - bundleMeta := v1alpha1.BundleMetadata{ - TypeMeta: metav1.TypeMeta{ - APIVersion: v1alpha1.GroupVersion.String(), - Kind: "BundleMetadata", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: bundleName, - Labels: map[string]string{ - "catalog": catalog.Name, - }, - OwnerReferences: []metav1.OwnerReference{{ - APIVersion: v1alpha1.GroupVersion.String(), - Kind: "Catalog", - Name: catalog.Name, - UID: catalog.UID, - BlockOwnerDeletion: pointer.Bool(true), - Controller: pointer.Bool(true), - }}, - }, - Spec: v1alpha1.BundleMetadataSpec{ - Catalog: corev1.LocalObjectReference{Name: catalog.Name}, - Package: bundle.Package, - Image: bundle.Image, - }, - } - - for _, relatedImage := range bundle.RelatedImages { - bundleMeta.Spec.RelatedImages = append(bundleMeta.Spec.RelatedImages, v1alpha1.RelatedImage{ - Name: relatedImage.Name, - Image: relatedImage.Image, - }) - } - - for _, prop := range bundle.Properties { - // skip any properties that are of type `olm.bundle.object` - if prop.Type == "olm.bundle.object" { - continue - } - - bundleMeta.Spec.Properties = append(bundleMeta.Spec.Properties, v1alpha1.Property{ - Type: prop.Type, - Value: prop.Value, - }) - } - newBundles[bundleName] = &bundleMeta - } - - var existingBundles v1alpha1.BundleMetadataList - if err := r.List(ctx, &existingBundles, &client.MatchingLabels{"catalog": catalog.Name}); err != nil { - return fmt.Errorf("list existing bundle metadatas: %v", err) - } - for i := range existingBundles.Items { - existingBundle := existingBundles.Items[i] - if _, ok := newBundles[existingBundle.Name]; !ok { - if err := r.Delete(ctx, &existingBundle); err != nil { - return fmt.Errorf("delete existing bundle metadata %q: %v", existingBundle.Name, err) - } - } - } - - ordered := sets.List(sets.KeySet(newBundles)) - for _, bundleName := range ordered { - newBundle := newBundles[bundleName] - if err := r.Client.Patch(ctx, newBundle, client.Apply, &client.PatchOptions{Force: pointer.Bool(true), FieldManager: "catalog-controller"}); err != nil { - return fmt.Errorf("applying bundle metadata %q: %w", newBundle.Name, err) - } - } - return nil -} - -// syncPackages will create a `Package` resource for each -// "olm.package" object that exists for the given catalog contents. -// `Package.Spec.Channels` is populated by filtering all "olm.channel" objects -// where the "packageName" == `Package.Name`. Returns an error if any are encountered. -func (r *CatalogReconciler) syncPackages(ctx context.Context, declCfg *declcfg.DeclarativeConfig, catalog *v1alpha1.Catalog) error { - newPkgs := map[string]*v1alpha1.Package{} - - for _, pkg := range declCfg.Packages { - name, _ := k8sutil.MetadataName(fmt.Sprintf("%s-%s", catalog.Name, pkg.Name)) - var icon *v1alpha1.Icon - if pkg.Icon != nil { - icon = &v1alpha1.Icon{ - Data: pkg.Icon.Data, - MediaType: pkg.Icon.MediaType, - } - } - newPkgs[name] = &v1alpha1.Package{ - TypeMeta: metav1.TypeMeta{ - APIVersion: v1alpha1.GroupVersion.String(), - Kind: "Package", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - "catalog": catalog.Name, - }, - OwnerReferences: []metav1.OwnerReference{{ - APIVersion: v1alpha1.GroupVersion.String(), - Kind: "Catalog", - Name: catalog.Name, - UID: catalog.UID, - BlockOwnerDeletion: pointer.Bool(true), - Controller: pointer.Bool(true), - }}, - }, - Spec: v1alpha1.PackageSpec{ - Catalog: corev1.LocalObjectReference{Name: catalog.Name}, - Name: pkg.Name, - DefaultChannel: pkg.DefaultChannel, - Description: pkg.Description, - Icon: icon, - Channels: []v1alpha1.PackageChannel{}, - }, - } - } - - for _, ch := range declCfg.Channels { - pkgName, _ := k8sutil.MetadataName(fmt.Sprintf("%s-%s", catalog.Name, ch.Package)) - pkg, ok := newPkgs[pkgName] - if !ok { - return fmt.Errorf("channel %q references package %q which does not exist", ch.Name, ch.Package) - } - pkgChannel := v1alpha1.PackageChannel{Name: ch.Name} - for _, entry := range ch.Entries { - pkgChannel.Entries = append(pkgChannel.Entries, v1alpha1.ChannelEntry{ - Name: entry.Name, - Replaces: entry.Replaces, - Skips: entry.Skips, - SkipRange: entry.SkipRange, - }) - } - pkg.Spec.Channels = append(pkg.Spec.Channels, pkgChannel) - } - - var existingPkgs v1alpha1.PackageList - if err := r.List(ctx, &existingPkgs, &client.MatchingLabels{"catalog": catalog.Name}); err != nil { - return fmt.Errorf("list existing packages: %v", err) - } - for i := range existingPkgs.Items { - existingPkg := existingPkgs.Items[i] - if _, ok := newPkgs[existingPkg.Name]; !ok { - // delete existing package - if err := r.Delete(ctx, &existingPkg); err != nil { - return fmt.Errorf("delete existing package %q: %v", existingPkg.Name, err) - } - } - } - - ordered := sets.List(sets.KeySet(newPkgs)) - for _, pkgName := range ordered { - newPkg := newPkgs[pkgName] - if err := r.Client.Patch(ctx, newPkg, client.Apply, &client.PatchOptions{Force: pointer.Bool(true), FieldManager: "catalog-controller"}); err != nil { - return fmt.Errorf("applying package %q: %w", newPkg.Name, err) - } - } - return nil -} - // syncCatalogMetadata will sync all of the catalog contents to `CatalogMetadata` objects // by creating, updating and deleting the objects as necessary. Returns an // error if any are encountered. diff --git a/pkg/controllers/core/catalog_controller_test.go b/pkg/controllers/core/catalog_controller_test.go index e4b82385..c91d40b9 100644 --- a/pkg/controllers/core/catalog_controller_test.go +++ b/pkg/controllers/core/catalog_controller_test.go @@ -15,11 +15,9 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/rand" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" "github.com/operator-framework/catalogd/api/core/v1alpha1" - "github.com/operator-framework/catalogd/internal/k8sutil" "github.com/operator-framework/catalogd/internal/source" "github.com/operator-framework/catalogd/pkg/controllers/core" "github.com/operator-framework/catalogd/pkg/features" @@ -234,13 +232,8 @@ var _ = Describe("Catalogd Controller Test", func() { testPackage = fmt.Sprintf(testPackageTemplate, testPackageDefaultChannel, testPackageName) testBundle = fmt.Sprintf(testBundleTemplate, testBundleImage, testBundleName, testPackageName, testBundleRelatedImageName, testBundleRelatedImageImage, testBundleObjectData) testChannel = fmt.Sprintf(testChannelTemplate, testPackageName, testChannelName, testBundleName) - - testBundleMetaName string - testPackageMetaName string ) BeforeEach(func() { - testBundleMetaName, _ = k8sutil.MetadataName(fmt.Sprintf("%s-%s", catalog.Name, testBundleName)) - testPackageMetaName, _ = k8sutil.MetadataName(fmt.Sprintf("%s-%s", catalog.Name, testPackageName)) filesys := &fstest.MapFS{ "bundle.yaml": &fstest.MapFile{Data: []byte(testBundle), Mode: os.ModePerm}, @@ -273,142 +266,6 @@ var _ = Describe("Catalogd Controller Test", func() { Expect(cond.Status).To(Equal(metav1.ConditionTrue)) }) - When("PackagesBundleMetadataAPIs feature gate is enabled", func() { - BeforeEach(func() { - Expect(features.CatalogdFeatureGate.SetFromMap(map[string]bool{ - string(features.PackagesBundleMetadataAPIs): true, - string(features.CatalogMetadataAPI): false, - })).NotTo(HaveOccurred()) - - // reconcile - res, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: catalogKey}) - Expect(res).To(Equal(ctrl.Result{})) - Expect(err).ToNot(HaveOccurred()) - }) - - AfterEach(func() { - Expect(cl.DeleteAllOf(ctx, &v1alpha1.Package{})).To(Succeed()) - Expect(cl.DeleteAllOf(ctx, &v1alpha1.BundleMetadata{})).To(Succeed()) - - Expect(features.CatalogdFeatureGate.SetFromMap(map[string]bool{ - string(features.PackagesBundleMetadataAPIs): false, - string(features.CatalogMetadataAPI): false, - })).NotTo(HaveOccurred()) - }) - - It("should create BundleMetadata resources", func() { - // validate bundlemetadata resources - bundlemetadatas := &v1alpha1.BundleMetadataList{} - Expect(cl.List(ctx, bundlemetadatas)).To(Succeed()) - Expect(bundlemetadatas.Items).To(HaveLen(1)) - bundlemetadata := bundlemetadatas.Items[0] - Expect(bundlemetadata.Name).To(Equal(testBundleMetaName)) - Expect(bundlemetadata.Spec.Image).To(Equal(testBundleImage)) - Expect(bundlemetadata.Spec.Catalog.Name).To(Equal(catalog.Name)) - Expect(bundlemetadata.Spec.Package).To(Equal(testPackageName)) - Expect(bundlemetadata.Spec.RelatedImages).To(HaveLen(1)) - Expect(bundlemetadata.Spec.RelatedImages[0].Name).To(Equal(testBundleRelatedImageName)) - Expect(bundlemetadata.Spec.RelatedImages[0].Image).To(Equal(testBundleRelatedImageImage)) - Expect(bundlemetadata.Spec.Properties).To(HaveLen(1)) - }) - - // TODO (rashmigottipati): Add testing of Package sync process. - It("should create Package resources", func() { - // validate package resources - packages := &v1alpha1.PackageList{} - Expect(cl.List(ctx, packages)).To(Succeed()) - Expect(packages.Items).To(HaveLen(1)) - pack := packages.Items[0] - Expect(pack.Name).To(Equal(testPackageMetaName)) - Expect(pack.Spec.DefaultChannel).To(Equal(testPackageDefaultChannel)) - Expect(pack.Spec.Catalog.Name).To(Equal(catalog.Name)) - Expect(pack.Spec.Channels).To(HaveLen(1)) - Expect(pack.Spec.Channels[0].Name).To(Equal(testChannelName)) - Expect(pack.Spec.Channels[0].Entries).To(HaveLen(1)) - Expect(pack.Spec.Channels[0].Entries[0].Name).To(Equal(testBundleName)) - }) - - When("creating another Catalog", func() { - var ( - tempCatalog *v1alpha1.Catalog - tempTestBundleMetaName string - tempTestPackageMetaName string - ) - BeforeEach(func() { - tempCatalog = &v1alpha1.Catalog{ - ObjectMeta: metav1.ObjectMeta{Name: "tempedout"}, - Spec: v1alpha1.CatalogSpec{ - Source: v1alpha1.CatalogSource{ - Type: "image", - Image: &v1alpha1.ImageSource{ - Ref: "somecatalog:latest", - }, - }, - }, - } - - tempTestBundleMetaName, _ = k8sutil.MetadataName(fmt.Sprintf("%s-%s", tempCatalog.Name, testBundleName)) - tempTestPackageMetaName, _ = k8sutil.MetadataName(fmt.Sprintf("%s-%s", tempCatalog.Name, testPackageName)) - - Expect(cl.Create(ctx, tempCatalog)).To(Succeed()) - res, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: types.NamespacedName{Name: "tempedout"}}) - Expect(res).To(Equal(ctrl.Result{})) - Expect(err).ToNot(HaveOccurred()) - }) - - AfterEach(func() { - Expect(cl.Delete(ctx, tempCatalog)).NotTo(HaveOccurred()) - }) - - It("should not delete BundleMetadata belonging to a different catalog", func() { - bundlemetadata := &v1alpha1.BundleMetadata{} - Expect(cl.Get(ctx, client.ObjectKey{Name: testBundleMetaName}, bundlemetadata)).To(Succeed()) - Expect(bundlemetadata.Name).To(Equal(testBundleMetaName)) - Expect(bundlemetadata.Spec.Image).To(Equal(testBundleImage)) - Expect(bundlemetadata.Spec.Catalog.Name).To(Equal(catalog.Name)) - Expect(bundlemetadata.Spec.Package).To(Equal(testPackageName)) - Expect(bundlemetadata.Spec.RelatedImages).To(HaveLen(1)) - Expect(bundlemetadata.Spec.RelatedImages[0].Name).To(Equal(testBundleRelatedImageName)) - Expect(bundlemetadata.Spec.RelatedImages[0].Image).To(Equal(testBundleRelatedImageImage)) - Expect(bundlemetadata.Spec.Properties).To(HaveLen(1)) - - bundlemetadata = &v1alpha1.BundleMetadata{} - Expect(cl.Get(ctx, client.ObjectKey{Name: tempTestBundleMetaName}, bundlemetadata)).To(Succeed()) - Expect(bundlemetadata.Name).To(Equal(tempTestBundleMetaName)) - Expect(bundlemetadata.Spec.Image).To(Equal(testBundleImage)) - Expect(bundlemetadata.Spec.Catalog.Name).To(Equal(tempCatalog.Name)) - Expect(bundlemetadata.Spec.Package).To(Equal(testPackageName)) - Expect(bundlemetadata.Spec.RelatedImages).To(HaveLen(1)) - Expect(bundlemetadata.Spec.RelatedImages[0].Name).To(Equal(testBundleRelatedImageName)) - Expect(bundlemetadata.Spec.RelatedImages[0].Image).To(Equal(testBundleRelatedImageImage)) - Expect(bundlemetadata.Spec.Properties).To(HaveLen(1)) - }) - - It("should not delete Packages belonging to a different catalog", func() { - // validate package resources - pack := &v1alpha1.Package{} - Expect(cl.Get(ctx, client.ObjectKey{Name: testPackageMetaName}, pack)).To(Succeed()) - Expect(pack.Name).To(Equal(testPackageMetaName)) - Expect(pack.Spec.DefaultChannel).To(Equal(testPackageDefaultChannel)) - Expect(pack.Spec.Catalog.Name).To(Equal(catalog.Name)) - Expect(pack.Spec.Channels).To(HaveLen(1)) - Expect(pack.Spec.Channels[0].Name).To(Equal(testChannelName)) - Expect(pack.Spec.Channels[0].Entries).To(HaveLen(1)) - Expect(pack.Spec.Channels[0].Entries[0].Name).To(Equal(testBundleName)) - - pack = &v1alpha1.Package{} - Expect(cl.Get(ctx, client.ObjectKey{Name: tempTestPackageMetaName}, pack)).To(Succeed()) - Expect(pack.Name).To(Equal(tempTestPackageMetaName)) - Expect(pack.Spec.DefaultChannel).To(Equal(testPackageDefaultChannel)) - Expect(pack.Spec.Catalog.Name).To(Equal(tempCatalog.Name)) - Expect(pack.Spec.Channels).To(HaveLen(1)) - Expect(pack.Spec.Channels[0].Name).To(Equal(testChannelName)) - Expect(pack.Spec.Channels[0].Entries).To(HaveLen(1)) - Expect(pack.Spec.Channels[0].Entries[0].Name).To(Equal(testBundleName)) - }) - }) - }) - When("the CatalogMetadataAPI feature gate is enabled", func() { BeforeEach(func() { Expect(features.CatalogdFeatureGate.SetFromMap(map[string]bool{ @@ -505,8 +362,8 @@ var _ = Describe("Catalogd Controller Test", func() { // To learn more about File-Based Catalogs and the different objects, view the // documentation at https://olm.operatorframework.io/docs/reference/file-based-catalogs/. // The reasoning behind having these as a template is to parameterize different -// fields to use custom values during testing and verifying to ensure that the BundleMetadata -// and Package resources created by the Catalog controller have the appropriate values. +// fields to use custom values during testing and verifying to ensure that the CatalogMetadata +// resources created by the Catalog controller have the appropriate values. // Having the parameterized fields allows us to easily change the values that are used in // the tests by changing them in one place as opposed to manually changing many string literals // throughout the code. diff --git a/pkg/features/features.go b/pkg/features/features.go index 3fce4e59..21a0db16 100644 --- a/pkg/features/features.go +++ b/pkg/features/features.go @@ -9,16 +9,13 @@ const ( // Add new feature gates constants (strings) // Ex: SomeFeature featuregate.Feature = "SomeFeature" - CatalogMetadataAPI featuregate.Feature = "CatalogMetadataAPI" - PackagesBundleMetadataAPIs featuregate.Feature = "PackagesBundleMetadataAPIs" + CatalogMetadataAPI featuregate.Feature = "CatalogMetadataAPI" ) var catalogdFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ // Add new feature gate definitions // Ex: SomeFeature: {...} - PackagesBundleMetadataAPIs: {Default: false, PreRelease: featuregate.Deprecated}, - // Marking the CatalogMetadataAPI feature gate as Deprecated in the interest of introducing // the HTTP Server functionality in the future and use it as a default method of serving the catalog contents. CatalogMetadataAPI: {Default: false, PreRelease: featuregate.Deprecated}, diff --git a/pprof/README.md b/pprof/README.md index 612fc76a..9e8b7db5 100644 --- a/pprof/README.md +++ b/pprof/README.md @@ -1,5 +1,9 @@ ## pprof +> **Warning** +> This pprof data is based on early versions of catalogd and has not been updated since. The data is likely not accurate anymore. +> A decision about removing or updating this data will be made in the future. + This folder contains some profiles that can be read using [pprof](https://github.com/google/pprof) to show how the core kubernetes apiserver and the custom catalogd apiserver CPU & Memory utilization is affected by the creation and reconciliation of the sample `Catalog` CR found at `../config/samples/core_v1alpha1_catalog.yaml`. Instead of providing static screenshots and losing the interactivity associated with these `pprof` profiles, each of the files with the extension `.pb` can be used to view the profiles that were the result of running `pprof` against the live processes. diff --git a/test/e2e/unpack_test.go b/test/e2e/unpack_test.go index cf7594ed..7825366c 100644 --- a/test/e2e/unpack_test.go +++ b/test/e2e/unpack_test.go @@ -8,11 +8,14 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/operator-framework/operator-registry/alpha/declcfg" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest/komega" catalogd "github.com/operator-framework/catalogd/api/core/v1alpha1" ) @@ -75,48 +78,97 @@ var _ = Describe("Catalog Unpacking", func() { g.Expect(cond.Status).To(Equal(metav1.ConditionTrue)) g.Expect(cond.Reason).To(Equal(catalogd.ReasonUnpackSuccessful)) }).Should(Succeed()) + catalogOwnerRef := metav1.NewControllerRef(catalog, catalogd.GroupVersion.WithKind("Catalog")) - By("Ensuring the expected Package resource is created") - pack := &catalogd.Package{} - expectedPackSpec := catalogd.PackageSpec{ - Catalog: corev1.LocalObjectReference{ - Name: catalogName, + By("Ensuring the expected number of CatalogMetadata objects exist") + catalogMetadataList := &catalogd.CatalogMetadataList{} + err := c.List(ctx, catalogMetadataList) + Expect(err).ToNot(HaveOccurred()) + Expect(catalogMetadataList.Items).To(HaveLen(3)) + + By("Validating the expected CatalogMetadata olm.package object exists") + pack := &catalogd.CatalogMetadata{} + expectedPack := &catalogd.CatalogMetadata{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%s-%s", catalog.Name, declcfg.SchemaPackage, pkg), + Labels: map[string]string{ + "schema": "olm.package", + "catalog": "test-catalog", + "name": "prometheus", + "package": "", + "packageOrName": "prometheus", + }, + OwnerReferences: []metav1.OwnerReference{*catalogOwnerRef}, }, - Channels: []catalogd.PackageChannel{ - { - Name: channel, - Entries: []catalogd.ChannelEntry{ - { - Name: bundle, - }, - }, + Spec: catalogd.CatalogMetadataSpec{ + Catalog: corev1.LocalObjectReference{ + Name: catalogName, }, + Schema: declcfg.SchemaPackage, + Name: pkg, + Package: "", + Content: json.RawMessage(`{"defaultChannel":"beta","name":"prometheus","schema":"olm.package"}`), }, - DefaultChannel: channel, - Name: pkg, } - err := c.Get(ctx, types.NamespacedName{Name: fmt.Sprintf("%s-%s", catalog.Name, pkg)}, pack) + err = c.Get(ctx, client.ObjectKeyFromObject(expectedPack), pack) Expect(err).ToNot(HaveOccurred()) - Expect(pack.Spec).To(Equal(expectedPackSpec)) + Expect(expectedPack).To(komega.EqualObject(pack, komega.IgnoreAutogeneratedMetadata)) - By("Ensuring the expected BundleMetadata resource is created") - bm := &catalogd.BundleMetadata{} - expectedBMSpec := catalogd.BundleMetadataSpec{ - Catalog: corev1.LocalObjectReference{ - Name: catalogName, + By("Validating the expected CatalogMetadata olm.channel object exists") + ch := &catalogd.CatalogMetadata{} + expectedCh := &catalogd.CatalogMetadata{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%s-%s-%s", catalog.Name, declcfg.SchemaChannel, pkg, channel), + Labels: map[string]string{ + "schema": declcfg.SchemaChannel, + "catalog": catalog.Name, + "name": channel, + "package": pkg, + "packageOrName": pkg, + }, + OwnerReferences: []metav1.OwnerReference{*catalogOwnerRef}, + }, + Spec: catalogd.CatalogMetadataSpec{ + Catalog: corev1.LocalObjectReference{ + Name: catalogName, + }, + Schema: declcfg.SchemaChannel, + Name: channel, + Package: pkg, + Content: json.RawMessage(`{"entries":[{"name":"prometheus-operator.0.47.0"}],"name":"beta","package":"prometheus","schema":"olm.channel"}`), + }, + } + err = c.Get(ctx, client.ObjectKeyFromObject(expectedCh), ch) + Expect(err).ToNot(HaveOccurred()) + Expect(expectedCh).To(komega.EqualObject(ch, komega.IgnoreAutogeneratedMetadata)) + + By("Validating the expected CatalogMetadata olm.bundle object exists") + bndl := &catalogd.CatalogMetadata{} + expectedBndl := &catalogd.CatalogMetadata{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%s-%s-%s", catalog.Name, declcfg.SchemaBundle, pkg, bundle), + Labels: map[string]string{ + "schema": declcfg.SchemaBundle, + "catalog": catalog.Name, + "name": bundle, + "package": pkg, + "packageOrName": pkg, + }, + OwnerReferences: []metav1.OwnerReference{*catalogOwnerRef}, }, - Package: pkg, - Image: bundleImage, - Properties: []catalogd.Property{ - { - Type: "olm.package", - Value: json.RawMessage(`{"packageName":"prometheus","version":"0.47.0"}`), + Spec: catalogd.CatalogMetadataSpec{ + Catalog: corev1.LocalObjectReference{ + Name: catalogName, }, + Schema: declcfg.SchemaBundle, + Name: bundle, + Package: pkg, + Content: json.RawMessage(`{"image":"localhost/testdata/bundles/registry-v1/prometheus-operator:v0.47.0","name":"prometheus-operator.0.47.0","package":"prometheus","properties":[{"type":"olm.package","value":{"packageName":"prometheus","version":"0.47.0"}}],"schema":"olm.bundle"}`), }, } - err = c.Get(ctx, types.NamespacedName{Name: fmt.Sprintf("%s-%s", catalog.Name, bundle)}, bm) + err = c.Get(ctx, client.ObjectKeyFromObject(expectedBndl), bndl) Expect(err).ToNot(HaveOccurred()) - Expect(bm.Spec).To(Equal(expectedBMSpec)) + Expect(expectedBndl).To(komega.EqualObject(bndl, komega.IgnoreAutogeneratedMetadata)) }) AfterEach(func() {