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/controllers/numaresourcesoperator_controller.go b/controllers/numaresourcesoperator_controller.go index c972cf255..d86802d37 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,16 @@ 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 { + intkloglevel.Set(loglevel.ToKlog(lev)) + 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 +164,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)