Golang v2 environment -- runtime and builder (#427)

v2 environment for Go; includes runtime and builder.
This commit is contained in:
Soam Vasani
2017-12-06 23:03:05 -06:00
committed by GitHub
parent eed3018458
commit 1e6b7a4fc8
5 changed files with 99 additions and 18 deletions
+3 -1
View File
@@ -1,4 +1,6 @@
FROM golang:1.8.1
ARG GO_VERSION=1.9.2
FROM golang:${GO_VERSION}
ENV GOPATH /usr
ENV APP ${GOPATH}/src/github.com/fission/fission/environments/go
+10 -1
View File
@@ -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
RUN go get github.com/fission/fission
ADD build.sh /usr/local/bin/build
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
cd ${SRC_PKG}
go build -buildmode=plugin -i -o ${DEPLOY_PKG} .
-11
View File
@@ -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."
+82 -5
View File
@@ -1,9 +1,12 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"plugin"
"github.com/fission/fission/environments/go/context"
@@ -13,14 +16,52 @@ const (
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
func loadPlugin() http.HandlerFunc {
p, err := plugin.Open(CODE_PATH)
func loadPlugin(codePath, entrypoint string) http.HandlerFunc {
// if codepath's a directory, load the file inside it
info, err := os.Stat(codePath)
if err != nil {
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 {
panic("Entry point not found")
}
@@ -44,7 +85,7 @@ func loadPlugin() http.HandlerFunc {
func specializeHandler(w http.ResponseWriter, r *http.Request) {
if userFunc != nil {
w.WriteHeader(400)
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Not a generic container"))
return
}
@@ -61,12 +102,48 @@ func specializeHandler(w http.ResponseWriter, r *http.Request) {
}
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")
}
func main() {
http.HandleFunc("/specialize", specializeHandler)
http.HandleFunc("/v2/specialize", specializeHandlerV2)
// Generic route -- all http requests go to the user function.
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {