Golang v2 environment -- runtime and builder (#427)
v2 environment for Go; includes runtime and builder.
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
FROM golang:1.8.1
|
ARG GO_VERSION=1.9.2
|
||||||
|
|
||||||
|
FROM golang:${GO_VERSION}
|
||||||
|
|
||||||
ENV GOPATH /usr
|
ENV GOPATH /usr
|
||||||
ENV APP ${GOPATH}/src/github.com/fission/fission/environments/go
|
ENV APP ${GOPATH}/src/github.com/fission/fission/environments/go
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
FROM golang:1.8.1
|
ARG BUILDER_IMAGE=fission/builder
|
||||||
|
ARG GO_VERSION=1.9.2
|
||||||
|
|
||||||
|
FROM ${BUILDER_IMAGE}
|
||||||
|
|
||||||
|
FROM golang:${GO_VERSION}
|
||||||
|
|
||||||
|
COPY --from=0 /builder /builder
|
||||||
|
|
||||||
ENV GOPATH /usr
|
ENV GOPATH /usr
|
||||||
RUN go get github.com/fission/fission
|
RUN go get github.com/fission/fission
|
||||||
|
|
||||||
|
ADD build.sh /usr/local/bin/build
|
||||||
|
|
||||||
|
|||||||
Executable
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
cd ${SRC_PKG}
|
||||||
|
go build -buildmode=plugin -i -o ${DEPLOY_PKG} .
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if [ $# -eq 0 ]
|
|
||||||
then
|
|
||||||
echo "No arguments, building current dir"
|
|
||||||
filename='.'
|
|
||||||
else
|
|
||||||
filename=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker run --rm -v $(pwd):/build -w /build fission/go-builder:1.8.1 go build -buildmode=plugin -o function.so $filename && echo "Compiled plugin: function.so. Use 'fission function create' to upload to fission."
|
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"plugin"
|
"plugin"
|
||||||
|
|
||||||
"github.com/fission/fission/environments/go/context"
|
"github.com/fission/fission/environments/go/context"
|
||||||
@@ -13,14 +16,52 @@ const (
|
|||||||
CODE_PATH = "/userfunc/user"
|
CODE_PATH = "/userfunc/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
FunctionLoadRequest struct {
|
||||||
|
// FilePath is an absolute filesystem path to the
|
||||||
|
// function. What exactly is stored here is
|
||||||
|
// env-specific. Optional.
|
||||||
|
FilePath string `json:"filepath"`
|
||||||
|
|
||||||
|
// FunctionName has an environment-specific meaning;
|
||||||
|
// usually, it defines a function within a module
|
||||||
|
// containing multiple functions. Optional; default is
|
||||||
|
// environment-specific.
|
||||||
|
FunctionName string `json:"functionName"`
|
||||||
|
|
||||||
|
// URL to expose this function at. Optional; defaults
|
||||||
|
// to "/".
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
var userFunc http.HandlerFunc
|
var userFunc http.HandlerFunc
|
||||||
|
|
||||||
func loadPlugin() http.HandlerFunc {
|
func loadPlugin(codePath, entrypoint string) http.HandlerFunc {
|
||||||
p, err := plugin.Open(CODE_PATH)
|
|
||||||
|
// if codepath's a directory, load the file inside it
|
||||||
|
info, err := os.Stat(codePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
sym, err := p.Lookup("Handler")
|
if info.IsDir() {
|
||||||
|
files, err := ioutil.ReadDir(codePath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(files) == 0 {
|
||||||
|
panic("No files to load")
|
||||||
|
}
|
||||||
|
fi := files[0]
|
||||||
|
codePath = filepath.Join(codePath, fi.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("loading plugin from %v\n", codePath)
|
||||||
|
p, err := plugin.Open(codePath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
sym, err := p.Lookup(entrypoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Entry point not found")
|
panic("Entry point not found")
|
||||||
}
|
}
|
||||||
@@ -44,7 +85,7 @@ func loadPlugin() http.HandlerFunc {
|
|||||||
|
|
||||||
func specializeHandler(w http.ResponseWriter, r *http.Request) {
|
func specializeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if userFunc != nil {
|
if userFunc != nil {
|
||||||
w.WriteHeader(400)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte("Not a generic container"))
|
w.Write([]byte("Not a generic container"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -61,12 +102,48 @@ func specializeHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Specializing ...")
|
fmt.Println("Specializing ...")
|
||||||
userFunc = loadPlugin()
|
userFunc = loadPlugin(CODE_PATH, "Handler")
|
||||||
|
fmt.Println("Done")
|
||||||
|
}
|
||||||
|
|
||||||
|
func specializeHandlerV2(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if userFunc != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("Not a generic container"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var loadreq FunctionLoadRequest
|
||||||
|
err = json.Unmarshal(body, &loadreq)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = os.Stat(loadreq.FilePath)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
w.Write([]byte(CODE_PATH + ": not found"))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Specializing ...")
|
||||||
|
userFunc = loadPlugin(loadreq.FilePath, loadreq.FunctionName)
|
||||||
fmt.Println("Done")
|
fmt.Println("Done")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
http.HandleFunc("/specialize", specializeHandler)
|
http.HandleFunc("/specialize", specializeHandler)
|
||||||
|
http.HandleFunc("/v2/specialize", specializeHandlerV2)
|
||||||
|
|
||||||
// Generic route -- all http requests go to the user function.
|
// Generic route -- all http requests go to the user function.
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
Reference in New Issue
Block a user