-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ webhook: add an option to recover from panics in handler #1900
✨ webhook: add an option to recover from panics in handler #1900
Conversation
Hi @isitinschi. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
@vincepri WDYT? |
/ok-to-test |
pkg/webhook/admission/webhook.go
Outdated
"net/http" | ||
|
||
utilruntime "k8s.io/apimachinery/pkg/util/runtime" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please sort the imports
@@ -121,6 +124,9 @@ type Webhook struct { | |||
// and potentially patches to apply to the handler. | |||
Handler Handler | |||
|
|||
// RecoverPanic indicates whether the panic caused by webhook should be recovered. | |||
RecoverPanic bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be better if we support to set it in pkg/builder/webhook.go
.
e17b4ce
to
bd15155
Compare
/test pull-controller-runtime-test-master |
@FillZpp thank you for the review. I've addressed all your suggestions. PTAL |
pkg/builder/webhook.go
Outdated
@@ -68,6 +69,12 @@ func (blder *WebhookBuilder) WithValidator(validator admission.CustomValidator) | |||
return blder | |||
} | |||
|
|||
// WithRecoverPanic takes a bool flag which indicates whether the panic caused by webhook should be recovered. | |||
func (blder *WebhookBuilder) WithRecoverPanic(recoverPanic bool) *WebhookBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just defined as func (blder *WebhookBuilder) RecoverPanic() * WebhookBuilder
so that recoverPanic
should be true
if it is called?
pkg/webhook/admission/defaulter.go
Outdated
@@ -33,9 +33,10 @@ type Defaulter interface { | |||
} | |||
|
|||
// DefaultingWebhookFor creates a new Webhook for Defaulting the provided type. | |||
func DefaultingWebhookFor(defaulter Defaulter) *Webhook { | |||
func DefaultingWebhookFor(defaulter Defaulter, recoverPanic bool) *Webhook { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a little concern about these public API change, not sure if there were some ppl directly use them.
So how about a new func (wh *Webhook) WithRecoverPanic*(enable bool) *Webhook
and you can use it in builder/webhook like this return admission.ValidatingWebhookFor(validator).WithRecoverPanic(blder. recoverPanic)
85eab91
to
d52d0fe
Compare
@FillZpp is it better like this? |
/lgtm /cc @alvaroaleman |
@alvaroaleman Does it look good to you to be merged? |
pkg/webhook/admission/webhook.go
Outdated
func (wh *Webhook) Handle(ctx context.Context, req Request) (response Response) { | ||
defer func() { | ||
if r := recover(); r != nil { | ||
if wh.RecoverPanic { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this if
condition be before the recover()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We won't be able to process the panic if we don't recover from it first. Panic recovery works the same way in controller.go:
controller-runtime/pkg/internal/controller/controller.go
Lines 104 to 122 in 15154aa
// Reconcile implements reconcile.Reconciler. | |
func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, err error) { | |
defer func() { | |
if r := recover(); r != nil { | |
if c.RecoverPanic { | |
for _, fn := range utilruntime.PanicHandlers { | |
fn(r) | |
} | |
err = fmt.Errorf("panic: %v [recovered]", r) | |
return | |
} | |
log := logf.FromContext(ctx) | |
log.Info(fmt.Sprintf("Observed a panic in reconciler: %v", r)) | |
panic(r) | |
} | |
}() | |
return c.Do.Reconcile(ctx, req) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we don't want to process it when RecoverPanic is false? What is done in controller.go seems quite pointless to me and IIRC the r
won't contain the stacktrace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, let's make RecoverPanic
flag more fair and really not process anything if it is set to false. Adjusted my PR accordingly 👍
d52d0fe
to
b5ab2b2
Compare
@vincepri @alvaroaleman does it look good to you? |
pkg/webhook/admission/webhook.go
Outdated
defer func() { | ||
if wh.RecoverPanic { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defer func() { | |
if wh.RecoverPanic { | |
if wh.RecoverPanic | |
defer func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done ✅
Currently, a panic occcurence in a webhook handler is not recovered and crashes the webhook server. This change adds an option to Webhook to recover panics similar to how it is handled in Reconciler. It ensures that panics are converted to normal error response.
b5ab2b2
to
037bde6
Compare
Thank you! |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: alvaroaleman, isitinschi The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Currently, a panic occcurence in a webhook handler is not recovered and crashes the webhook server.
This change adds an option to Webhook to recover panics similar to how it is handled in Reconciler. It ensures that panics are converted to normal error response.