Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
0952c9ee
Commit
0952c9ee
authored
Nov 15, 2018
by
Jordan Liggitt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
apiserver: propagate panics from REST handlers correctly
parent
b7e2980a
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
64 additions
and
18 deletions
+64
-18
rest.go
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go
+11
-3
rest_test.go
.../src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go
+53
-15
No files found.
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go
View file @
0952c9ee
...
...
@@ -23,6 +23,8 @@ import (
"io/ioutil"
"net/http"
"net/url"
goruntime
"runtime"
"strings"
"time"
"k8s.io/klog"
...
...
@@ -33,7 +35,6 @@ import (
metav1beta1
"k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
...
...
@@ -182,10 +183,17 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
panicCh
:=
make
(
chan
interface
{},
1
)
go
func
()
{
// panics don't cross goroutine boundaries, so we have to handle ourselves
defer
utilruntime
.
HandleCrash
(
func
(
panicReason
interface
{})
{
defer
func
()
{
panicReason
:=
recover
()
if
panicReason
!=
nil
{
const
size
=
64
<<
10
buf
:=
make
([]
byte
,
size
)
buf
=
buf
[
:
goruntime
.
Stack
(
buf
,
false
)]
panicReason
=
strings
.
TrimSuffix
(
fmt
.
Sprintf
(
"%v
\n
%s"
,
panicReason
,
string
(
buf
)),
"
\n
"
)
}
// Propagate to parent goroutine
panicCh
<-
panicReason
})
}
(
)
if
result
,
err
:=
fn
();
err
!=
nil
{
errCh
<-
err
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go
View file @
0952c9ee
...
...
@@ -22,6 +22,7 @@ import (
"fmt"
"net/http"
"reflect"
"strings"
"testing"
"time"
...
...
@@ -835,13 +836,15 @@ func TestFinishRequest(t *testing.T) {
successStatusObj
:=
&
metav1
.
Status
{
Status
:
metav1
.
StatusSuccess
,
Message
:
"success message"
}
errorStatusObj
:=
&
metav1
.
Status
{
Status
:
metav1
.
StatusFailure
,
Message
:
"error message"
}
testcases
:=
[]
struct
{
timeout
time
.
Duration
fn
resultFunc
expectedObj
runtime
.
Object
expectedErr
error
name
string
timeout
time
.
Duration
fn
resultFunc
expectedObj
runtime
.
Object
expectedErr
error
expectedPanic
string
}{
{
// Expected obj is returned.
name
:
"Expected obj is returned"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
return
exampleObj
,
nil
...
...
@@ -850,7 +853,7 @@ func TestFinishRequest(t *testing.T) {
expectedErr
:
nil
,
},
{
// Expected error is returned.
name
:
"Expected error is returned"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
return
nil
,
exampleErr
...
...
@@ -859,7 +862,7 @@ func TestFinishRequest(t *testing.T) {
expectedErr
:
exampleErr
,
},
{
// Successful status object is returned as expected.
name
:
"Successful status object is returned as expected"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
return
successStatusObj
,
nil
...
...
@@ -868,7 +871,7 @@ func TestFinishRequest(t *testing.T) {
expectedErr
:
nil
,
},
{
// Error status object is converted to StatusError.
name
:
"Error status object is converted to StatusError"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
return
errorStatusObj
,
nil
...
...
@@ -876,15 +879,50 @@ func TestFinishRequest(t *testing.T) {
expectedObj
:
nil
,
expectedErr
:
apierrors
.
FromObject
(
errorStatusObj
),
},
{
name
:
"Panic is propagated up"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
panic
(
"my panic"
)
return
nil
,
nil
},
expectedObj
:
nil
,
expectedErr
:
nil
,
expectedPanic
:
"my panic"
,
},
{
name
:
"Panic is propagated with stack"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
panic
(
"my panic"
)
return
nil
,
nil
},
expectedObj
:
nil
,
expectedErr
:
nil
,
expectedPanic
:
"rest_test.go"
,
},
}
for
i
,
tc
:=
range
testcases
{
obj
,
err
:=
finishRequest
(
tc
.
timeout
,
tc
.
fn
)
if
(
err
==
nil
&&
tc
.
expectedErr
!=
nil
)
||
(
err
!=
nil
&&
tc
.
expectedErr
==
nil
)
||
(
err
!=
nil
&&
tc
.
expectedErr
!=
nil
&&
err
.
Error
()
!=
tc
.
expectedErr
.
Error
())
{
t
.
Errorf
(
"%d: unexpected err. expected: %v, got: %v"
,
i
,
tc
.
expectedErr
,
err
)
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
obj
,
tc
.
expectedObj
)
{
t
.
Errorf
(
"%d: unexpected obj. expected %#v, got %#v"
,
i
,
tc
.
expectedObj
,
obj
)
}
t
.
Run
(
tc
.
name
,
func
(
t
*
testing
.
T
)
{
defer
func
()
{
r
:=
recover
()
switch
{
case
r
==
nil
&&
len
(
tc
.
expectedPanic
)
>
0
:
t
.
Errorf
(
"expected panic containing '%s', got none"
,
tc
.
expectedPanic
)
case
r
!=
nil
&&
len
(
tc
.
expectedPanic
)
==
0
:
t
.
Errorf
(
"unexpected panic: %v"
,
r
)
case
r
!=
nil
&&
len
(
tc
.
expectedPanic
)
>
0
&&
!
strings
.
Contains
(
fmt
.
Sprintf
(
"%v"
,
r
),
tc
.
expectedPanic
)
:
t
.
Errorf
(
"expected panic containing '%s', got '%v'"
,
tc
.
expectedPanic
,
r
)
}
}()
obj
,
err
:=
finishRequest
(
tc
.
timeout
,
tc
.
fn
)
if
(
err
==
nil
&&
tc
.
expectedErr
!=
nil
)
||
(
err
!=
nil
&&
tc
.
expectedErr
==
nil
)
||
(
err
!=
nil
&&
tc
.
expectedErr
!=
nil
&&
err
.
Error
()
!=
tc
.
expectedErr
.
Error
())
{
t
.
Errorf
(
"%d: unexpected err. expected: %v, got: %v"
,
i
,
tc
.
expectedErr
,
err
)
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
obj
,
tc
.
expectedObj
)
{
t
.
Errorf
(
"%d: unexpected obj. expected %#v, got %#v"
,
i
,
tc
.
expectedObj
,
obj
)
}
})
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment