Fix go env panic when failed at loading plugin (#1031)

Fix go env panic when failed at loading plugin to make it easier for troubleshooting.
This commit is contained in:
Ta-Ching Chen
2018-12-27 00:14:22 +08:00
committed by GitHub
parent f68572ce78
commit f9f5fe436a
+48 -21
View File
@@ -2,13 +2,15 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"plugin" "plugin"
"github.com/pkg/errors"
"github.com/fission/fission/environments/go/context" "github.com/fission/fission/environments/go/context"
) )
@@ -37,47 +39,47 @@ type (
var userFunc http.HandlerFunc var userFunc http.HandlerFunc
func loadPlugin(codePath, entrypoint string) http.HandlerFunc { func loadPlugin(codePath, entrypoint string) (http.HandlerFunc, error) {
// if codepath's a directory, load the file inside it // if codepath's a directory, load the file inside it
info, err := os.Stat(codePath) info, err := os.Stat(codePath)
if err != nil { if err != nil {
panic(err) return nil, errors.Wrap(err, "error checking plugin path")
} }
if info.IsDir() { if info.IsDir() {
files, err := ioutil.ReadDir(codePath) files, err := ioutil.ReadDir(codePath)
if err != nil { if err != nil {
panic(err) return nil, errors.Wrap(err, "error reading directory")
} }
if len(files) == 0 { if len(files) == 0 {
panic("No files to load") return nil, errors.New("No files to load")
} }
fi := files[0] fi := files[0]
codePath = filepath.Join(codePath, fi.Name()) codePath = filepath.Join(codePath, fi.Name())
} }
fmt.Printf("loading plugin from %v\n", codePath) log.Printf("loading plugin from %v\n", codePath)
p, err := plugin.Open(codePath) p, err := plugin.Open(codePath)
if err != nil { if err != nil {
panic(err) return nil, errors.Wrap(err, "error loading plugin")
} }
sym, err := p.Lookup(entrypoint) sym, err := p.Lookup(entrypoint)
if err != nil { if err != nil {
panic("Entry point not found") return nil, errors.Wrap(err, "entry point not found")
} }
switch h := sym.(type) { switch h := sym.(type) {
case *http.Handler: case *http.Handler:
return (*h).ServeHTTP return (*h).ServeHTTP, nil
case *http.HandlerFunc: case *http.HandlerFunc:
return *h return *h, nil
case func(http.ResponseWriter, *http.Request): case func(http.ResponseWriter, *http.Request):
return h return h, nil
case func(context.Context, http.ResponseWriter, *http.Request): case func(context.Context, http.ResponseWriter, *http.Request):
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
c := context.New() c := context.New()
h(c, w, r) h(c, w, r)
} }, nil
default: default:
panic("Entry point not found: bad type") panic("Entry point not found: bad type")
} }
@@ -94,16 +96,28 @@ func specializeHandler(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
log.Printf(err.Error())
w.Write([]byte(CODE_PATH + ": not found")) w.Write([]byte(CODE_PATH + ": not found"))
return return
} else { } else {
panic(err) err = errors.Wrap(err, "unknown error")
log.Printf(err.Error())
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
} }
} }
fmt.Println("Specializing ...") log.Println("Specializing ...")
userFunc = loadPlugin(CODE_PATH, "Handler") userFunc, err = loadPlugin(CODE_PATH, "Handler")
fmt.Println("Done") if err != nil {
err = errors.Wrap(err, "error specializing function")
log.Printf(err.Error())
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
log.Println("Done")
} }
func specializeHandlerV2(w http.ResponseWriter, r *http.Request) { func specializeHandlerV2(w http.ResponseWriter, r *http.Request) {
@@ -115,6 +129,7 @@ func specializeHandlerV2(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
log.Println(err.Error())
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
} }
@@ -129,16 +144,28 @@ func specializeHandlerV2(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
log.Printf(err.Error())
w.Write([]byte(CODE_PATH + ": not found")) w.Write([]byte(CODE_PATH + ": not found"))
return return
} else { } else {
panic(err) err = errors.Wrap(err, "unknown error")
log.Printf(err.Error())
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
} }
} }
fmt.Println("Specializing ...") log.Println("Specializing ...")
userFunc = loadPlugin(loadreq.FilePath, loadreq.FunctionName) userFunc, err = loadPlugin(loadreq.FilePath, loadreq.FunctionName)
fmt.Println("Done") if err != nil {
err = errors.Wrap(err, "error specializing function")
log.Printf(err.Error())
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
log.Println("Done")
} }
func readinessProbeHandler(w http.ResponseWriter, r *http.Request) { func readinessProbeHandler(w http.ResponseWriter, r *http.Request) {
@@ -160,6 +187,6 @@ func main() {
userFunc(w, r) userFunc(w, r)
}) })
fmt.Println("Listening on 8888 ...") log.Println("Listening on 8888 ...")
http.ListenAndServe(":8888", nil) http.ListenAndServe(":8888", nil)
} }