diff --git a/api/numaresourcesoperator/v1/numaresourcesoperator_normalize.go b/api/numaresourcesoperator/v1/numaresourcesoperator_normalize.go index 25599b926..2347ad2a1 100644 --- a/api/numaresourcesoperator/v1/numaresourcesoperator_normalize.go +++ b/api/numaresourcesoperator/v1/numaresourcesoperator_normalize.go @@ -20,8 +20,20 @@ import ( "sort" corev1 "k8s.io/api/core/v1" + + operatorv1 "github.com/openshift/api/operator/v1" ) +func NormalizeSpec(spec *NUMAResourcesOperatorSpec) { + defaultLog := operatorv1.Normal + if spec.LogLevel == "" { + spec.LogLevel = defaultLog + } + if spec.OperatorLogLevel == nil { + spec.OperatorLogLevel = &defaultLog + } +} + func (nodeGroup NodeGroup) NormalizeConfig() NodeGroupConfig { conf := DefaultNodeGroupConfig() if nodeGroup.Config == nil { diff --git a/api/numaresourcesoperator/v1/numaresourcesoperator_types.go b/api/numaresourcesoperator/v1/numaresourcesoperator_types.go index 01c70ff9e..bff5375ca 100644 --- a/api/numaresourcesoperator/v1/numaresourcesoperator_types.go +++ b/api/numaresourcesoperator/v1/numaresourcesoperator_types.go @@ -45,6 +45,12 @@ type NUMAResourcesOperatorSpec struct { // +optional //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Optional ignore pod namespace/name glob patterns" PodExcludes []NamespacedName `json:"podExcludes,omitempty"` + // Valid values are: "Normal", "Debug", "Trace", "TraceAll". + // Defaults to "Normal". + // +optional + // +kubebuilder:default=Normal + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Operator log verbosity" + OperatorLogLevel *operatorv1.LogLevel `json:"operatorLogLevel,omitempty"` } // +kubebuilder:validation:Enum=Disabled;Enabled;EnabledExclusiveResources @@ -136,6 +142,9 @@ type NUMAResourcesOperatorStatus struct { // RelatedObjects list of objects of interest for this operator //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="Related Objects" RelatedObjects []configv1.ObjectReference `json:"relatedObjects,omitempty"` + // OperatorLogLevel is the current log verbosity of the operator. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="Operator log verbosity" + OperatorLogLevel operatorv1.LogLevel `json:"operatorLogLevel,omitempty"` } // MachineConfigPool defines the observed state of each MachineConfigPool selected by node groups diff --git a/api/numaresourcesoperator/v1/zz_generated.deepcopy.go b/api/numaresourcesoperator/v1/zz_generated.deepcopy.go index 0e404ffc7..799b45799 100644 --- a/api/numaresourcesoperator/v1/zz_generated.deepcopy.go +++ b/api/numaresourcesoperator/v1/zz_generated.deepcopy.go @@ -22,6 +22,7 @@ package v1 import ( configv1 "github.com/openshift/api/config/v1" + operatorv1 "github.com/openshift/api/operator/v1" machineconfiguration_openshift_iov1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -129,6 +130,11 @@ func (in *NUMAResourcesOperatorSpec) DeepCopyInto(out *NUMAResourcesOperatorSpec *out = make([]NamespacedName, len(*in)) copy(*out, *in) } + if in.OperatorLogLevel != nil { + in, out := &in.OperatorLogLevel, &out.OperatorLogLevel + *out = new(operatorv1.LogLevel) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NUMAResourcesOperatorSpec. diff --git a/bundle/manifests/nodetopology.openshift.io_numaresourcesoperators.yaml b/bundle/manifests/nodetopology.openshift.io_numaresourcesoperators.yaml index 58a34ca34..c20e34f5f 100644 --- a/bundle/manifests/nodetopology.openshift.io_numaresourcesoperators.yaml +++ b/bundle/manifests/nodetopology.openshift.io_numaresourcesoperators.yaml @@ -184,6 +184,18 @@ spec: x-kubernetes-map-type: atomic type: object type: array + operatorLogLevel: + default: Normal + description: |- + Valid values are: "Normal", "Debug", "Trace", "TraceAll". + Defaults to "Normal". + enum: + - "" + - Normal + - Debug + - Trace + - TraceAll + type: string podExcludes: description: Optional Namespace/Name glob patterns of pod to ignore at node level @@ -401,6 +413,16 @@ spec: - name type: object type: array + operatorLogLevel: + description: OperatorLogLevel is the current log verbosity of the + operator. + enum: + - "" + - Normal + - Debug + - Trace + - TraceAll + type: string relatedObjects: description: RelatedObjects list of objects of interest for this operator items: diff --git a/bundle/manifests/numaresources-operator.clusterserviceversion.yaml b/bundle/manifests/numaresources-operator.clusterserviceversion.yaml index 06efc4ad6..111ba1f30 100644 --- a/bundle/manifests/numaresources-operator.clusterserviceversion.yaml +++ b/bundle/manifests/numaresources-operator.clusterserviceversion.yaml @@ -62,7 +62,7 @@ metadata: } ] capabilities: Basic Install - createdAt: "2024-09-17T08:34:36Z" + createdAt: "2024-09-24T16:05:02Z" olm.skipRange: '>=4.17.0 <4.18.0' operators.operatorframework.io/builder: operator-sdk-v1.36.1 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 @@ -126,6 +126,11 @@ spec: path: nodeGroups[0].config.tolerations x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text + - description: |- + Valid values are: "Normal", "Debug", "Trace", "TraceAll". + Defaults to "Normal". + displayName: Operator log verbosity + path: operatorLogLevel - description: Optional Namespace/Name glob patterns of pod to ignore at node level displayName: Optional ignore pod namespace/name glob patterns @@ -149,6 +154,9 @@ spec: applied to this MachineConfigPool displayName: Optional configuration enforced on this NodeGroup path: machineconfigpools[0].config + - description: OperatorLogLevel is the current log verbosity of the operator. + displayName: Operator log verbosity + path: operatorLogLevel - description: RelatedObjects list of objects of interest for this operator displayName: Related Objects path: relatedObjects diff --git a/config/crd/bases/nodetopology.openshift.io_numaresourcesoperators.yaml b/config/crd/bases/nodetopology.openshift.io_numaresourcesoperators.yaml index 0f0378371..5f3504dc7 100644 --- a/config/crd/bases/nodetopology.openshift.io_numaresourcesoperators.yaml +++ b/config/crd/bases/nodetopology.openshift.io_numaresourcesoperators.yaml @@ -184,6 +184,18 @@ spec: x-kubernetes-map-type: atomic type: object type: array + operatorLogLevel: + default: Normal + description: |- + Valid values are: "Normal", "Debug", "Trace", "TraceAll". + Defaults to "Normal". + enum: + - "" + - Normal + - Debug + - Trace + - TraceAll + type: string podExcludes: description: Optional Namespace/Name glob patterns of pod to ignore at node level @@ -401,6 +413,16 @@ spec: - name type: object type: array + operatorLogLevel: + description: OperatorLogLevel is the current log verbosity of the + operator. + enum: + - "" + - Normal + - Debug + - Trace + - TraceAll + type: string relatedObjects: description: RelatedObjects list of objects of interest for this operator items: diff --git a/config/manifests/bases/numaresources-operator.clusterserviceversion.yaml b/config/manifests/bases/numaresources-operator.clusterserviceversion.yaml index 409120760..7705ae7cd 100644 --- a/config/manifests/bases/numaresources-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/numaresources-operator.clusterserviceversion.yaml @@ -65,6 +65,11 @@ spec: path: nodeGroups[0].config.tolerations x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text + - description: |- + Valid values are: "Normal", "Debug", "Trace", "TraceAll". + Defaults to "Normal". + displayName: Operator log verbosity + path: operatorLogLevel - description: Optional Namespace/Name glob patterns of pod to ignore at node level displayName: Optional ignore pod namespace/name glob patterns @@ -88,6 +93,9 @@ spec: applied to this MachineConfigPool displayName: Optional configuration enforced on this NodeGroup path: machineconfigpools[0].config + - description: OperatorLogLevel is the current log verbosity of the operator. + displayName: Operator log verbosity + path: operatorLogLevel - description: RelatedObjects list of objects of interest for this operator displayName: Related Objects path: relatedObjects diff --git a/controllers/numaresourcesoperator_controller.go b/controllers/numaresourcesoperator_controller.go index c972cf255..ce3774569 100644 --- a/controllers/numaresourcesoperator_controller.go +++ b/controllers/numaresourcesoperator_controller.go @@ -63,6 +63,8 @@ import ( rteupdate "github.com/openshift-kni/numaresources-operator/pkg/objectupdate/rte" "github.com/openshift-kni/numaresources-operator/pkg/status" "github.com/openshift-kni/numaresources-operator/pkg/validation" + + intkloglevel "github.com/openshift-kni/numaresources-operator/internal/kloglevel" ) const numaResourcesRetryPeriod = 1 * time.Minute @@ -132,6 +134,20 @@ func (r *NUMAResourcesOperatorReconciler) Reconcile(ctx context.Context, req ctr return r.updateStatus(ctx, instance, status.ConditionDegraded, status.ConditionTypeIncorrectNUMAResourcesOperatorResourceName, message) } + needStatusUpdate := false + nropv1.NormalizeSpec(&instance.Spec) + + // do as early as possible, so we don't miss log messages + if lev := *instance.Spec.OperatorLogLevel; lev != instance.Status.OperatorLogLevel { + err := intkloglevel.Set(loglevel.ToKlog(lev)) + if err != nil { + klog.InfoS("cannot updated log level dynamically", "desiredLevel", lev) + } else { + instance.Status.OperatorLogLevel = lev + needStatusUpdate = true + } + } + if err := validation.NodeGroups(instance.Spec.NodeGroups); err != nil { return r.updateStatus(ctx, instance, status.ConditionDegraded, validation.NodeGroupsError, err.Error()) } @@ -152,6 +168,9 @@ func (r *NUMAResourcesOperatorReconciler) Reconcile(ctx context.Context, req ctr result, condition, err := r.reconcileResource(ctx, instance, trees) if condition != "" { + needStatusUpdate = true + } + if needStatusUpdate { // TODO: use proper reason reason, message := condition, messageFromError(err) _, _ = r.updateStatus(ctx, instance, condition, reason, message) diff --git a/main.go b/main.go index 2dccddc10..abadb43fe 100644 --- a/main.go +++ b/main.go @@ -472,15 +472,3 @@ func webhookTLSOpts(enableHTTP2 bool) []func(config *tls.Config) { return []func(config *tls.Config){disableHTTP2} } - -// getKlogLevel reconstructs the klog verb level, because -// the klog package doesn't give a clean easy way to access -// the setting, so we have to jumps through some hoops. -func getKlogLevel() int { - for j := 1; j < 15; j++ { - if !klog.V(klog.Level(j)).Enabled() { - return j - 1 - } - } - return 0 -}