Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ I don't want to go through the motions of figuring out the correct way to build

```shell
# substitute the version number as desired
go build -ldflags "-X main.Version=0.3.0
go build -ldflags "-X main.Version=0.3.0"
```

## Usage
Expand Down
8 changes: 3 additions & 5 deletions builders/dotnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (b DotnetBuilder) Detect() bool {

func (b DotnetBuilder) Execute() error {
b.Config.HandlerMap = b.GetHandlerMap()
return executeBuilder(b.script(), b.GetTaskBuildDir(), b.Config)
return executeBuilder(b.script(), b.Config)
}

func (b DotnetBuilder) GetBuildImage() string {
Expand All @@ -48,10 +48,6 @@ func (b DotnetBuilder) GetHandlerMap() map[string]string {
return map[string]string{}
}

func (b DotnetBuilder) GetTaskBuildDir() string {
return "/var/task"
}

func (b DotnetBuilder) Name() string {
return "dotnet"
}
Expand All @@ -61,6 +57,8 @@ func (b DotnetBuilder) script() string {
#!/usr/bin/env bash
set -eo pipefail

[ "$BUILDER_XTRACE" ] && set -o xtrace

indent() {
sed -u "s/^/ /"
}
Expand Down
8 changes: 3 additions & 5 deletions builders/go.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (b GoBuilder) Detect() bool {

func (b GoBuilder) Execute() error {
b.Config.HandlerMap = b.GetHandlerMap()
return executeBuilder(b.script(), b.GetTaskBuildDir(), b.Config)
return executeBuilder(b.script(), b.Config)
}

func (b GoBuilder) GetBuildImage() string {
Expand All @@ -54,10 +54,6 @@ func (b GoBuilder) GetHandlerMap() map[string]string {
}
}

func (b GoBuilder) GetTaskBuildDir() string {
return "/go/src/handler"
}

func (b GoBuilder) Name() string {
return "go"
}
Expand All @@ -67,6 +63,8 @@ func (b GoBuilder) script() string {
#!/usr/bin/env bash
set -eo pipefail

[ "$BUILDER_XTRACE" ] && set -o xtrace

indent() {
sed -u "s/^/ /"
}
Expand Down
79 changes: 46 additions & 33 deletions builders/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package builders

import (
"bytes"
"context"
"fmt"
"html/template"
"io/ioutil"
Expand All @@ -11,6 +13,7 @@ import (
"lambda-builder/io"

execute "github.com/alexellis/go-execute/pkg/v1"
extract "github.com/codeclysm/extract/v3"
"gopkg.in/yaml.v2"
)

Expand All @@ -20,7 +23,6 @@ type Builder interface {
GetBuildImage() string
GetConfig() Config
GetHandlerMap() map[string]string
GetTaskBuildDir() string
Name() string
}

Expand Down Expand Up @@ -57,56 +59,74 @@ type LambdaYML struct {
RunImage string `yaml:"run_image"`
}

func executeBuilder(script string, taskBuildDir string, config Config) error {
tmp, err := os.MkdirTemp("", "lambda-builder")
defer func() {
os.RemoveAll(tmp)
}()
func executeBuilder(script string, config Config) error {
if err := executeBuildContainer(script, config); err != nil {
return err
}

taskHostBuildDir, err := os.MkdirTemp("", "lambda-builder")
if err != nil {
return fmt.Errorf("error preparing temporary build directory: %s", err.Error())
return fmt.Errorf("error creating build dir: %w", err)
}

if err := executeBuildContainer(tmp, script, taskBuildDir, config); err != nil {
return err
defer func() {
os.RemoveAll(taskHostBuildDir)
}()

fmt.Printf("-----> Extracting lambda.zip into build context dir\n")
zipPath := filepath.Join(config.WorkingDirectory, "lambda.zip")
data, _ := ioutil.ReadFile(zipPath)
buffer := bytes.NewBuffer(data)
if err := extract.Zip(context.Background(), buffer, taskHostBuildDir, nil); err != nil {
return fmt.Errorf("error extracting lambda.zip into build context dir: %w", err)
}

handler := getFunctionHandler(tmp, config)
if config.WriteProcfile && !io.FileExistsInDirectory(tmp, "Procfile") {
handler := getFunctionHandler(taskHostBuildDir, config)
if config.WriteProcfile && !io.FileExistsInDirectory(taskHostBuildDir, "Procfile") {
if handler == "" {
fmt.Printf(" ! Unable to detect handler in build directory\n")
} else {
fmt.Printf("=====> Writing Procfile from handler: %s\n", handler)

fmt.Printf(" Writing to working directory\n")
if err := writeProcfile(handler, config.WorkingDirectory); err != nil {
return fmt.Errorf("error writing Procfile to working directory: %s", err.Error())
return fmt.Errorf("error writing Procfile to working directory: %w", err)
}

fmt.Printf(" Writing to build directory\n")
if err := writeProcfile(handler, tmp); err != nil {
return fmt.Errorf("error writing Procfile to temporary build directory: %s", err.Error())
if err := writeProcfile(handler, taskHostBuildDir); err != nil {
return fmt.Errorf("error writing Procfile to temporary build directory: %w", err)
}
}
}

if config.GenerateImage {
fmt.Printf("=====> Building image\n")
fmt.Printf(" Generating temporary Dockerfile\n")
if err := generateDockerfile(handler, tmp, config); err != nil {

dockerfilePath, err := ioutil.TempFile("", "lambda-builder")
defer func() {
os.Remove(dockerfilePath.Name())
}()

if err != nil {
return fmt.Errorf("error generating temporary Dockerfile: %w", err)
}

if err := generateDockerfile(handler, config, dockerfilePath); err != nil {
return err
}

fmt.Printf(" Executing build of %s\n", config.GetImageTag())
if err := buildDockerImage(tmp, config); err != nil {
if err := buildDockerImage(taskHostBuildDir, config, dockerfilePath); err != nil {
return err
}
}

return nil
}

func executeBuildContainer(tmp string, script string, taskBuildDir string, config Config) error {
func executeBuildContainer(script string, config Config) error {
args := []string{
"container",
"run",
Expand All @@ -115,7 +135,6 @@ func executeBuildContainer(tmp string, script string, taskBuildDir string, confi
"--label", "com.dokku.lambda-builder/executor=true",
"--name", fmt.Sprintf("lambda-builder-executor-%s", config.Identifier),
"--volume", fmt.Sprintf("%s:/tmp/task", config.WorkingDirectory),
"--volume", fmt.Sprintf("%s:%s", tmp, taskBuildDir),
}

for _, envPair := range config.BuildEnv {
Expand All @@ -132,7 +151,7 @@ func executeBuildContainer(tmp string, script string, taskBuildDir string, confi

res, err := cmd.Execute()
if err != nil {
return fmt.Errorf("error executing builder: %s", err.Error())
return fmt.Errorf("error executing builder: %w", err)
}

if res.ExitCode != 0 {
Expand All @@ -142,13 +161,7 @@ func executeBuildContainer(tmp string, script string, taskBuildDir string, confi
return nil
}

func generateDockerfile(cmd string, directory string, config Config) error {
dockerfileName := filepath.Join(directory, fmt.Sprintf("%s.Dockerfile", config.Identifier))
f, err := os.Create(dockerfileName)
if err != nil {
return fmt.Errorf("error creating Dockerfile: %s", err)
}

func generateDockerfile(cmd string, config Config, dockerfilePath *os.File) error {
tpl, err := template.New("t1").Parse(`
FROM {{ .run_image }}
{{ if ne .port "-1" }}
Expand All @@ -174,18 +187,18 @@ COPY . /var/task
"run_image": config.BuilderRunImage,
}

if err := tpl.Execute(f, data); err != nil {
if err := tpl.Execute(dockerfilePath, data); err != nil {
return fmt.Errorf("error writing Dockerfile: %s", err)
}

return nil
}

func buildDockerImage(directory string, config Config) error {
func buildDockerImage(directory string, config Config, dockerfilePath *os.File) error {
args := []string{
"image",
"build",
"--file", filepath.Join(directory, fmt.Sprintf("%s.Dockerfile", config.Identifier)),
"--file", dockerfilePath.Name(),
"--progress", "plain",
"--tag", config.GetImageTag(),
}
Expand All @@ -205,7 +218,7 @@ func buildDockerImage(directory string, config Config) error {

res, err := cmd.Execute()
if err != nil {
return fmt.Errorf("error building image: %s", err.Error())
return fmt.Errorf("error building image: %w", err)
}

if res.ExitCode != 0 {
Expand All @@ -223,17 +236,17 @@ func ParseLambdaYML(config Config) (LambdaYML, error) {

f, err := os.Open(filepath.Join(config.WorkingDirectory, "lambda.yml"))
if err != nil {
return lambdaYML, fmt.Errorf("error opening lambda.yml: %s", err.Error())
return lambdaYML, fmt.Errorf("error opening lambda.yml: %w", err)
}
defer f.Close()

bytes, err := ioutil.ReadAll(f)
if err != nil {
return lambdaYML, fmt.Errorf("error reading lambda.yml: %s", err.Error())
return lambdaYML, fmt.Errorf("error reading lambda.yml: %w", err)
}

if err := yaml.Unmarshal(bytes, &lambdaYML); err != nil {
return lambdaYML, fmt.Errorf("error unmarshaling lambda.yml: %s", err.Error())
return lambdaYML, fmt.Errorf("error unmarshaling lambda.yml: %w", err)
}

return lambdaYML, nil
Expand Down
8 changes: 3 additions & 5 deletions builders/nodejs.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (b NodejsBuilder) Detect() bool {

func (b NodejsBuilder) Execute() error {
b.Config.HandlerMap = b.GetHandlerMap()
return executeBuilder(b.script(), b.GetTaskBuildDir(), b.Config)
return executeBuilder(b.script(), b.Config)
}

func (b NodejsBuilder) GetBuildImage() string {
Expand All @@ -51,10 +51,6 @@ func (b NodejsBuilder) GetHandlerMap() map[string]string {
}
}

func (b NodejsBuilder) GetTaskBuildDir() string {
return "/var/task"
}

func (b NodejsBuilder) Name() string {
return "nodejs"
}
Expand All @@ -64,6 +60,8 @@ func (b NodejsBuilder) script() string {
#!/usr/bin/env bash
set -eo pipefail

[ "$BUILDER_XTRACE" ] && set -o xtrace

indent() {
sed -u "s/^/ /"
}
Expand Down
Loading