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
b5e8f7aa
Commit
b5e8f7aa
authored
Aug 28, 2015
by
Jordan Liggitt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Recover panics in finishRequest, write correct API response
parent
cb2252b5
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
38 additions
and
18 deletions
+38
-18
apiserver.go
pkg/apiserver/apiserver.go
+22
-0
resthandler.go
pkg/apiserver/resthandler.go
+10
-0
master.go
pkg/master/master.go
+1
-17
util.go
pkg/util/util.go
+5
-1
No files found.
pkg/apiserver/apiserver.go
View file @
b5e8f7aa
...
@@ -25,6 +25,7 @@ import (
...
@@ -25,6 +25,7 @@ import (
"net"
"net"
"net/http"
"net/http"
"path"
"path"
rt
"runtime"
"strconv"
"strconv"
"strings"
"strings"
"time"
"time"
...
@@ -157,6 +158,27 @@ func InstallLogsSupport(mux Mux) {
...
@@ -157,6 +158,27 @@ func InstallLogsSupport(mux Mux) {
mux
.
Handle
(
"/logs/"
,
http
.
StripPrefix
(
"/logs/"
,
http
.
FileServer
(
http
.
Dir
(
"/var/log/"
))))
mux
.
Handle
(
"/logs/"
,
http
.
StripPrefix
(
"/logs/"
,
http
.
FileServer
(
http
.
Dir
(
"/var/log/"
))))
}
}
func
InstallRecoverHandler
(
container
*
restful
.
Container
)
{
container
.
RecoverHandler
(
logStackOnRecover
)
}
//TODO: Unify with RecoverPanics?
func
logStackOnRecover
(
panicReason
interface
{},
httpWriter
http
.
ResponseWriter
)
{
var
buffer
bytes
.
Buffer
buffer
.
WriteString
(
fmt
.
Sprintf
(
"recover from panic situation: - %v
\r\n
"
,
panicReason
))
for
i
:=
2
;
;
i
+=
1
{
_
,
file
,
line
,
ok
:=
rt
.
Caller
(
i
)
if
!
ok
{
break
}
buffer
.
WriteString
(
fmt
.
Sprintf
(
" %s:%d
\r\n
"
,
file
,
line
))
}
glog
.
Errorln
(
buffer
.
String
())
// TODO: make status unversioned or plumb enough of the request to deduce the requested API version
errorJSON
(
apierrors
.
NewGenericServerResponse
(
http
.
StatusInternalServerError
,
""
,
""
,
""
,
""
,
0
,
false
),
latest
.
Codec
,
httpWriter
)
}
func
InstallServiceErrorHandler
(
container
*
restful
.
Container
,
requestResolver
*
APIRequestInfoResolver
,
apiVersions
[]
string
)
{
func
InstallServiceErrorHandler
(
container
*
restful
.
Container
,
requestResolver
*
APIRequestInfoResolver
,
apiVersions
[]
string
)
{
container
.
ServiceErrorHandler
(
func
(
serviceErr
restful
.
ServiceError
,
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
container
.
ServiceErrorHandler
(
func
(
serviceErr
restful
.
ServiceError
,
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
serviceErrorHandler
(
requestResolver
,
apiVersions
,
serviceErr
,
request
,
response
)
serviceErrorHandler
(
requestResolver
,
apiVersions
,
serviceErr
,
request
,
response
)
...
...
pkg/apiserver/resthandler.go
View file @
b5e8f7aa
...
@@ -29,6 +29,7 @@ import (
...
@@ -29,6 +29,7 @@ import (
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/strategicpatch"
"k8s.io/kubernetes/pkg/util/strategicpatch"
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful"
...
@@ -618,7 +619,14 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
...
@@ -618,7 +619,14 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
// when the select statement reads something other than the one the goroutine sends on.
// when the select statement reads something other than the one the goroutine sends on.
ch
:=
make
(
chan
runtime
.
Object
,
1
)
ch
:=
make
(
chan
runtime
.
Object
,
1
)
errCh
:=
make
(
chan
error
,
1
)
errCh
:=
make
(
chan
error
,
1
)
panicCh
:=
make
(
chan
interface
{},
1
)
go
func
()
{
go
func
()
{
// panics don't cross goroutine boundaries, so we have to handle ourselves
defer
util
.
HandleCrash
(
func
(
panicReason
interface
{})
{
// Propagate to parent goroutine
panicCh
<-
panicReason
})
if
result
,
err
:=
fn
();
err
!=
nil
{
if
result
,
err
:=
fn
();
err
!=
nil
{
errCh
<-
err
errCh
<-
err
}
else
{
}
else
{
...
@@ -634,6 +642,8 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
...
@@ -634,6 +642,8 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
return
result
,
nil
return
result
,
nil
case
err
=
<-
errCh
:
case
err
=
<-
errCh
:
return
nil
,
err
return
nil
,
err
case
p
:=
<-
panicCh
:
panic
(
p
)
case
<-
time
.
After
(
timeout
)
:
case
<-
time
.
After
(
timeout
)
:
return
nil
,
errors
.
NewTimeoutError
(
"request did not complete within allowed duration"
,
0
)
return
nil
,
errors
.
NewTimeoutError
(
"request did not complete within allowed duration"
,
0
)
}
}
...
...
pkg/master/master.go
View file @
b5e8f7aa
...
@@ -17,7 +17,6 @@ limitations under the License.
...
@@ -17,7 +17,6 @@ limitations under the License.
package
master
package
master
import
(
import
(
"bytes"
"fmt"
"fmt"
"io/ioutil"
"io/ioutil"
"math/rand"
"math/rand"
...
@@ -26,7 +25,6 @@ import (
...
@@ -26,7 +25,6 @@ import (
"net/http/pprof"
"net/http/pprof"
"net/url"
"net/url"
"os"
"os"
rt
"runtime"
"strconv"
"strconv"
"strings"
"strings"
"sync"
"sync"
...
@@ -410,24 +408,10 @@ func (m *Master) HandleFuncWithAuth(pattern string, handler func(http.ResponseWr
...
@@ -410,24 +408,10 @@ func (m *Master) HandleFuncWithAuth(pattern string, handler func(http.ResponseWr
func
NewHandlerContainer
(
mux
*
http
.
ServeMux
)
*
restful
.
Container
{
func
NewHandlerContainer
(
mux
*
http
.
ServeMux
)
*
restful
.
Container
{
container
:=
restful
.
NewContainer
()
container
:=
restful
.
NewContainer
()
container
.
ServeMux
=
mux
container
.
ServeMux
=
mux
container
.
RecoverHandler
(
logStackOnRecov
er
)
apiserver
.
InstallRecoverHandler
(
contain
er
)
return
container
return
container
}
}
//TODO: Unify with RecoverPanics?
func
logStackOnRecover
(
panicReason
interface
{},
httpWriter
http
.
ResponseWriter
)
{
var
buffer
bytes
.
Buffer
buffer
.
WriteString
(
fmt
.
Sprintf
(
"recover from panic situation: - %v
\r\n
"
,
panicReason
))
for
i
:=
2
;
;
i
+=
1
{
_
,
file
,
line
,
ok
:=
rt
.
Caller
(
i
)
if
!
ok
{
break
}
buffer
.
WriteString
(
fmt
.
Sprintf
(
" %s:%d
\r\n
"
,
file
,
line
))
}
glog
.
Errorln
(
buffer
.
String
())
}
// init initializes master.
// init initializes master.
func
(
m
*
Master
)
init
(
c
*
Config
)
{
func
(
m
*
Master
)
init
(
c
*
Config
)
{
enableCacher
:=
true
enableCacher
:=
true
...
...
pkg/util/util.go
View file @
b5e8f7aa
...
@@ -44,7 +44,8 @@ var ReallyCrash bool
...
@@ -44,7 +44,8 @@ var ReallyCrash bool
var
PanicHandlers
=
[]
func
(
interface
{}){
logPanic
}
var
PanicHandlers
=
[]
func
(
interface
{}){
logPanic
}
// HandleCrash simply catches a crash and logs an error. Meant to be called via defer.
// HandleCrash simply catches a crash and logs an error. Meant to be called via defer.
func
HandleCrash
()
{
// Additional context-specific handlers can be provided, and will be called in case of panic
func
HandleCrash
(
additionalHandlers
...
func
(
interface
{}))
{
if
ReallyCrash
{
if
ReallyCrash
{
return
return
}
}
...
@@ -52,6 +53,9 @@ func HandleCrash() {
...
@@ -52,6 +53,9 @@ func HandleCrash() {
for
_
,
fn
:=
range
PanicHandlers
{
for
_
,
fn
:=
range
PanicHandlers
{
fn
(
r
)
fn
(
r
)
}
}
for
_
,
fn
:=
range
additionalHandlers
{
fn
(
r
)
}
}
}
}
}
...
...
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