core: log panics in controller reconcile functions

add RecoverAndLogException() helper to log panics with stack trace.
added defer call in all rook controller Reconcile() methods for
better error visibility in operator logs

Signed-off-by: Oded Viner <oviner@redhat.com>
(cherry picked from commit cf13deee6f)
This commit is contained in:
Oded Viner authored and Mergify committed 2025-07-29 16:00:49 +00:00
1 parent af05d4b16f
commit ee0bae1a6c
24 files changed
+33

No files matched your search

+1
View File
@@ -135,6 +135,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephClient) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephClient, err := r.reconcile(request)
return reporting.ReportReconcileResult(logger, r.recorder, request, &cephClient, reconcileResponse, err)
+1
View File
@@ -244,6 +244,7 @@ func add(opManagerContext context.Context, mgr manager.Manager, r reconcile.Reco
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephCluster) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephCluster, err := r.reconcile(request)
@@ -73,6 +73,7 @@ type ReconcileNode struct {
// The Controller will requeue the Request to be processed again if an error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileNode) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
result, err := r.reconcile(request)
if err != nil {
@@ -159,6 +159,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephRBDMirror) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephRBDMirror, err := r.reconcile(request)
if err != nil {
+1
View File
@@ -93,6 +93,7 @@ func add(ctx context.Context, context *clusterd.Context, mgr manager.Manager, r
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileConfig) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, err := r.reconcile(request)
if err != nil {
@@ -20,6 +20,7 @@ import (
"context"
"fmt"
"reflect"
"runtime/debug"
"slices"
"strconv"
"strings"
@@ -281,3 +282,11 @@ var ClusterResource = k8sutil.CustomResource{
Kind: reflect.TypeOf(cephv1.CephCluster{}).Name(),
APIVersion: fmt.Sprintf("%s/%s", cephv1.CustomResourceGroup, cephv1.Version),
}
// RecoverAndLogException handles and logs panics from a controller Reconcile loop.
func RecoverAndLogException() {
if r := recover(); r != nil {
logger.Errorf("Panic: %v", r)
logger.Errorf("Stack trace:\n%s", string(debug.Stack()))
}
}
+1
View File
@@ -128,6 +128,7 @@ func add(ctx context.Context, mgr manager.Manager, r reconcile.Reconciler, opCon
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCSI) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, err := r.reconcile(request)
if err != nil {
@@ -32,6 +32,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
opcontroller "github.com/rook/rook/pkg/operator/ceph/controller"
"github.com/rook/rook/pkg/operator/ceph/disruption/controllerconfig"
"github.com/rook/rook/pkg/operator/k8sutil"
)
@@ -68,6 +69,7 @@ type ReconcileClusterDisruption struct {
// The Controller will requeue the Request to be processed again if an error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileClusterDisruption) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// wrapping reconcile because the rook logging mechanism is not compatible with the controller-runtime logging interface
result, err := r.reconcile(request)
if err != nil {
+1
View File
@@ -180,6 +180,7 @@ func add(opManagerContext context.Context, mgr manager.Manager, r reconcile.Reco
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephFilesystem) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephFilesystem, err := r.reconcile(request)
if err != nil {
@@ -150,6 +150,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileFilesystemMirror) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephFilesystemMirror, err := r.reconcile(request)
if err != nil {
@@ -138,6 +138,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephFilesystemSubVolumeGroup) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, err := r.reconcile(request)
if err != nil {
+1
View File
@@ -152,6 +152,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephNFS) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephNFS, err := r.reconcile(request)
@@ -112,6 +112,7 @@ func add(ctx context.Context, mgr manager.Manager, r reconcile.Reconciler) error
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileBucket) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, err := r.reconcile(request)
if err != nil {
+1
View File
@@ -268,6 +268,7 @@ func isObjStoreSpecContainsSecret(spec *cephv1.ObjectStoreSpec, secret *corev1.S
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephObjectStore) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, objectStore, err := r.reconcile(request)
@@ -125,6 +125,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// Reconcile reads that state of the cluster for a CephCOSIDriver object and makes changes based on the state read
// and what is in the CephCOSIDriver.Spec
func (r *ReconcileCephCOSIDriver) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
reconcileResponse, cephCOSIDriver, err := r.reconcile(request)
return reporting.ReportReconcileResult(logger, r.recorder, request, &cephCOSIDriver, reconcileResponse, err)
@@ -121,6 +121,7 @@ func addNotificationReconciler(mgr manager.Manager, r reconcile.Reconciler) erro
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileNotifications) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
reconcileResponse, notification, err := r.reconcile(request)
if err != nil {
logger.Errorf("failed to reconcile %v", err)
@@ -130,6 +130,7 @@ func addOBCLabelReconciler(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileOBCLabels) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, err := r.reconcile(request)
if err != nil {
@@ -126,6 +126,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileObjectRealm) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephObjectRealm, err := r.reconcile(request)
@@ -188,6 +188,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileBucketTopic) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, err := r.reconcile(request)
if err != nil {
@@ -217,6 +217,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileObjectStoreUser) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephObjectStoreUser, err := r.reconcile(request)
if err != nil {
@@ -134,6 +134,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileObjectZone) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephObjectZone, err := r.reconcile(request)
@@ -117,6 +117,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileObjectZoneGroup) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, err := r.reconcile(request)
if err != nil {
+1
View File
@@ -160,6 +160,7 @@ func add(opManagerContext context.Context, mgr manager.Manager, r reconcile.Reco
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephBlockPool) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, cephBlockPool, err := r.reconcile(request)
@@ -149,6 +149,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
// processed again if the returned error is non-nil or Result.Requeue is true,
// otherwise upon completion it will remove the work from the queue.
func (r *ReconcileCephBlockPoolRadosNamespace) Reconcile(context context.Context, request reconcile.Request) (reconcile.Result, error) {
defer opcontroller.RecoverAndLogException()
// workaround because the rook logging mechanism is not compatible with the controller-runtime logging interface
reconcileResponse, radosNamespace, err := r.reconcile(request)
if err != nil {