+28
-25
@@ -19,11 +19,9 @@ package builder
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -33,6 +31,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/dchest/uniuri"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/fission/fission"
|
||||
)
|
||||
@@ -60,12 +60,14 @@ type (
|
||||
}
|
||||
|
||||
Builder struct {
|
||||
logger *zap.Logger
|
||||
sharedVolumePath string
|
||||
}
|
||||
)
|
||||
|
||||
func MakeBuilder(sharedVolumePath string) *Builder {
|
||||
func MakeBuilder(logger *zap.Logger, sharedVolumePath string) *Builder {
|
||||
return &Builder{
|
||||
logger: logger.Named("builder"),
|
||||
sharedVolumePath: sharedVolumePath,
|
||||
}
|
||||
}
|
||||
@@ -77,37 +79,37 @@ func (builder *Builder) VersionHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (builder *Builder) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
e := fmt.Sprintf("Method not allowed: %v", r.Method)
|
||||
log.Println(e)
|
||||
builder.reply(w, "", e, http.StatusMethodNotAllowed)
|
||||
e := "method not allowed"
|
||||
builder.logger.Error(e, zap.String("http_method", r.Method))
|
||||
builder.reply(w, "", fmt.Sprintf("%s: %s", e, r.Method), http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
defer func() {
|
||||
elapsed := time.Since(startTime)
|
||||
log.Printf("elapsed time in build request = %v", elapsed)
|
||||
builder.logger.Info("build request complete", zap.Duration("elapsed_time", elapsed))
|
||||
}()
|
||||
|
||||
// parse request
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
e := errors.New(fmt.Sprintf("Error reading request body: %v", err))
|
||||
log.Println(e.Error())
|
||||
builder.reply(w, "", e.Error(), http.StatusInternalServerError)
|
||||
e := "error reading request body"
|
||||
builder.logger.Error(e, zap.Error(err))
|
||||
builder.reply(w, "", fmt.Sprintf("%s: %s", e, err.Error()), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var req PackageBuildRequest
|
||||
err = json.Unmarshal(body, &req)
|
||||
if err != nil {
|
||||
e := errors.New(fmt.Sprintf("Error parsing json body: %v", err))
|
||||
log.Println(e.Error())
|
||||
builder.reply(w, "", e.Error(), http.StatusBadRequest)
|
||||
e := "error parsing json body"
|
||||
builder.logger.Error(e, zap.Error(err))
|
||||
builder.reply(w, "", fmt.Sprintf("%s: %s", e, err.Error()), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
log.Printf("Builder received request: %v", req)
|
||||
builder.logger.Info("builder received request", zap.Any("request", req))
|
||||
|
||||
log.Println("Starting build...")
|
||||
builder.logger.Info("starting build")
|
||||
srcPkgPath := filepath.Join(builder.sharedVolumePath, req.SrcPkgFilename)
|
||||
deployPkgFilename := fmt.Sprintf("%v-%v", req.SrcPkgFilename, strings.ToLower(uniuri.NewLen(6)))
|
||||
deployPkgPath := filepath.Join(builder.sharedVolumePath, deployPkgFilename)
|
||||
@@ -118,10 +120,11 @@ func (builder *Builder) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
buildLogs, err := builder.build(buildCmd, srcPkgPath, deployPkgPath)
|
||||
if err != nil {
|
||||
e := errors.New(fmt.Sprintf("Error building source package: %v", err))
|
||||
log.Println(e.Error())
|
||||
e := "error building source package"
|
||||
builder.logger.Error(e, zap.Error(err))
|
||||
|
||||
// append error at the end of build logs
|
||||
buildLogs += fmt.Sprintf("%v\n", e.Error())
|
||||
buildLogs += fmt.Sprintf("%s: %s\n", e, err.Error())
|
||||
builder.reply(w, deployPkgFilename, buildLogs, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -137,7 +140,7 @@ func (builder *Builder) reply(w http.ResponseWriter, pkgFilename string, buildLo
|
||||
|
||||
rBody, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
e := errors.New(fmt.Sprintf("Error encoding response body: %v", err))
|
||||
e := errors.Wrap(err, "error encoding response body")
|
||||
rBody = []byte(fmt.Sprintf(`{"buildLogs": "%v"}`, e.Error()))
|
||||
statusCode = http.StatusInternalServerError
|
||||
}
|
||||
@@ -154,7 +157,7 @@ func (builder *Builder) build(command string, srcPkgPath string, deployPkgPath s
|
||||
|
||||
fi, err := os.Stat(srcPkgPath)
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("could not find srcPkgPath: '%s'", srcPkgPath))
|
||||
return "", fmt.Errorf("could not find srcPkgPath: '%s'", srcPkgPath)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
cmd.Dir = srcPkgPath
|
||||
@@ -170,12 +173,12 @@ func (builder *Builder) build(command string, srcPkgPath string, deployPkgPath s
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("Error creating stdout pipe for cmd: %v", err.Error()))
|
||||
return "", errors.Wrap(err, "error creating stdout pipe for cmd")
|
||||
}
|
||||
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("Error creating stderr pipe for cmd: %v", err.Error()))
|
||||
return "", errors.Wrap(err, "error creating stderr pipe for cmd")
|
||||
}
|
||||
|
||||
var buildLogs string
|
||||
@@ -190,7 +193,7 @@ func (builder *Builder) build(command string, srcPkgPath string, deployPkgPath s
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("Error starting cmd: %v", err.Error()))
|
||||
return "", errors.Wrap(err, "error starting cmd")
|
||||
}
|
||||
|
||||
// Runtime logs
|
||||
@@ -201,14 +204,14 @@ func (builder *Builder) build(command string, srcPkgPath string, deployPkgPath s
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
scanErr := errors.New(fmt.Sprintf("Error reading cmd output: %v", err.Error()))
|
||||
scanErr := errors.Wrap(err, "error reading cmd output")
|
||||
fmt.Println(scanErr)
|
||||
return buildLogs, scanErr
|
||||
}
|
||||
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
cmdErr := errors.New(fmt.Sprintf("Error waiting for cmd '%v': %v", command, err.Error()))
|
||||
cmdErr := errors.Wrapf(err, "error waiting for cmd %q", command)
|
||||
fmt.Println(cmdErr)
|
||||
return buildLogs, cmdErr
|
||||
}
|
||||
|
||||
@@ -20,31 +20,35 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/fission/fission"
|
||||
builder "github.com/fission/fission/builder"
|
||||
)
|
||||
|
||||
type (
|
||||
Client struct {
|
||||
url string
|
||||
logger *zap.Logger
|
||||
url string
|
||||
}
|
||||
)
|
||||
|
||||
func MakeClient(builderUrl string) *Client {
|
||||
func MakeClient(logger *zap.Logger, builderUrl string) *Client {
|
||||
return &Client{
|
||||
url: strings.TrimSuffix(builderUrl, "/"),
|
||||
logger: logger.Named("builder_client"),
|
||||
url: strings.TrimSuffix(builderUrl, "/"),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) Build(req *builder.PackageBuildRequest) (*builder.PackageBuildResponse, error) {
|
||||
body, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "error marshaling json")
|
||||
}
|
||||
|
||||
maxRetries := 20
|
||||
@@ -62,7 +66,7 @@ func (c *Client) Build(req *builder.PackageBuildRequest) (*builder.PackageBuildR
|
||||
|
||||
if i < maxRetries-1 {
|
||||
time.Sleep(50 * time.Duration(2*i) * time.Millisecond)
|
||||
log.Printf("Error building package (%v), retrying", err)
|
||||
c.logger.Error("error building package, retrying", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -73,14 +77,14 @@ func (c *Client) Build(req *builder.PackageBuildRequest) (*builder.PackageBuildR
|
||||
|
||||
rBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Printf("Error reading resp body: %v", err)
|
||||
c.logger.Error("error reading resp body", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pkgBuildResp := builder.PackageBuildResponse{}
|
||||
err = json.Unmarshal([]byte(rBody), &pkgBuildResp)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing resp body: %v", err)
|
||||
c.logger.Error("error parsing resp body", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -21,21 +21,29 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
builder "github.com/fission/fission/builder"
|
||||
)
|
||||
|
||||
// Usage: builder <shared volume path>
|
||||
func main() {
|
||||
logger, err := zap.NewProduction()
|
||||
if err != nil {
|
||||
log.Fatalf("can't initialize zap logger: %v", err)
|
||||
}
|
||||
defer logger.Sync()
|
||||
|
||||
dir := os.Args[1]
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
err = os.MkdirAll(dir, os.ModeDir|0700)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating directory: %v", err)
|
||||
logger.Fatal("error creating directory", zap.Error(err), zap.String("directory", dir))
|
||||
}
|
||||
}
|
||||
}
|
||||
builder := builder.MakeBuilder(dir)
|
||||
builder := builder.MakeBuilder(logger, dir)
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", builder.Handler)
|
||||
mux.HandleFunc("/version", builder.VersionHandler)
|
||||
|
||||
Reference in New Issue
Block a user