Skip to content

Commit

Permalink
Third party template support
Browse files Browse the repository at this point in the history
1. Create `faas-cli addTemplate --url <URL>` command
2. Add template.yml files for each language in the ./template dir.
3. Read fProcess from ./template/<lang> in deploy command
4. Adds mock-server test for addTemplate.go
5. Remove fprocess variable hard-coding in proxy/deploy.go

Signed-off-by: Eric Stoekl <ems5311@gmail.com>
  • Loading branch information
ericstoekl committed Sep 9, 2017
1 parent 3a2e814 commit 9543c0e
Show file tree
Hide file tree
Showing 14 changed files with 179 additions and 10 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ COPY . .

RUN GIT_COMMIT=$(git rev-list -1 HEAD) \
&& CGO_ENABLED=0 GOOS=linux go build --ldflags "-s -w -X github.com/alexellis/faas-cli/commands.GitCommit=${GIT_COMMIT}" -a -installsuffix cgo -o faas-cli .
RUN go test ./...

FROM alpine:latest
RUN apk --no-cache add ca-certificates
Expand Down
52 changes: 52 additions & 0 deletions commands/add_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Alex Ellis 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
"fmt"
"os"
"strings"

"github.com/spf13/cobra"
)

// Flags that are to be added to commands

var (
URL string
)

func init() {
// Setup flags that are used only by this command (variables defined above)
addTemplateCmd.Flags().StringVar(&URL, "url", "http://github.com/alexellis/faas-cli", "URL from which to pull git repo to grab 'template' dir from")

faasCmd.AddCommand(addTemplateCmd)
}

// addTemplateCmd represents the addTemplate command
var addTemplateCmd = &cobra.Command{
Use: "add-template [--url URL]",
Short: "Downloads templates from the specified github repo",
Long: `Downloads the compressed github repo specified by [URL], and extracts the 'template'
directory from the root of the repo, if it exists.`,
Example: "faas-cli add-template --url https://github.com/alexellis/faas-cli",
Run: runAddTemplate,
}

func runAddTemplate(cmd *cobra.Command, args []string) {
URL = strings.TrimRight(URL, "/")
URL = URL + "/archive/master.zip"

err := os.Setenv("templateUrl", URL)
if err != nil {
fmt.Printf("Error setting templateUrl env var: %v\n", err)
os.Exit(1)
}

err = fetchTemplates()
if err != nil {
fmt.Printf("Error getting templates from URL: %v\n", err)
os.Exit(1)
}
}
54 changes: 54 additions & 0 deletions commands/add_template_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) Alex Ellis, Eric Stoekl 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
package commands

import (
"testing"
"net/http"
"net/http/httptest"
"io/ioutil"
"os"

)

func Test_addTemplate(t *testing.T) {
const sampleMasterZipPath string = "../test/master.zip"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

if _, err := os.Stat(sampleMasterZipPath); os.IsNotExist(err) {
t.Error(err)
}

fileData, err := ioutil.ReadFile(sampleMasterZipPath)
if err != nil {
t.Error(err)
}

w.Write(fileData)
}))
defer ts.Close()

URL = ts.URL
faasCmd.SetArgs([]string{"add-template"})
faasCmd.Execute()

// Remove existing master.zip file if it exists
if _, err := os.Stat("master.zip"); err == nil {
t.Log("Found a master.zip file, removing it...")

err := os.Remove("master.zip")
if err != nil {
t.Fatal(err)
}
}

// Remove existing templates folder, if it exist
if _, err := os.Stat("template/"); err == nil {
t.Log("Found a template/ directory, removing it...")

err := os.RemoveAll("template/")
if err != nil {
t.Fatal(err)
}
}
}
23 changes: 22 additions & 1 deletion commands/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,32 @@ func runDeploy(cmd *cobra.Command, args []string) {

for k, function := range services.Functions {
function.Name = k
fmt.Printf("Deploying: %s.\n", function.Name)
if function.Constraints != nil {
constraints = *function.Constraints
}

// Get FProcess to use from the ./template/template.yml, if a template is being used
if function.Language != "" && function.Language != "Dockerfile" && function.Language != "dockerfile" {
pathToTemplateYAML := "./template/" + function.Language + "/template.yml"
if _, err := os.Stat(pathToTemplateYAML); os.IsNotExist(err) {
log.Fatalln(err.Error())
return
}

var langTemplate stack.LanguageTemplate
parsedLangTemplate, err := stack.ParseYAMLForLanguageTemplate(pathToTemplateYAML)

if err != nil {
log.Fatalln(err.Error())
return
}

if parsedLangTemplate != nil {
langTemplate = *parsedLangTemplate
function.FProcess = langTemplate.FProcess
}
}

proxy.DeployFunction(function.FProcess, services.Provider.GatewayURL, function.Name, function.Image, function.Language, replace, function.Environment, services.Provider.Network, constraints)
}
} else {
Expand Down
1 change: 0 additions & 1 deletion commands/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ var (

func init() {
// Setup flags that are used by multiple commands (variables defined in faas.go)
listCmd.Flags().StringVar(&fprocess, "fprocess", "", "Fprocess to be run by the watchdog")
listCmd.Flags().StringVar(&gateway, "gateway", "http://localhost:8080", "Gateway URI")
listCmd.Flags().StringVar(&handler, "handler", "", "Directory with handler for function, e.g. handler.js")
listCmd.Flags().StringVar(&image, "image", "", "Docker image name to build")
Expand Down
10 changes: 2 additions & 8 deletions proxy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,8 @@ func DeployFunction(fprocess string, gateway string, functionName string, image
var fprocessTemplate string
if len(fprocess) > 0 {
fprocessTemplate = fprocess
} else if language == "python" {
fprocessTemplate = "python index.py"
} else if language == "node" {
fprocessTemplate = "node index.js"
} else if language == "ruby" {
fprocessTemplate = "ruby index.rb"
} else if language == "csharp" {
fprocessTemplate = "dotnet ./root.dll"
} else {
fmt.Printf("Command to be invoked for function %s not found.\n", functionName)
}

gateway = strings.TrimRight(gateway, "/")
Expand Down
31 changes: 31 additions & 0 deletions stack/language_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Alex Ellis 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package stack

import (
"fmt"
"io/ioutil"

yaml "gopkg.in/yaml.v2"
)

// ParseYAML parse a YAML file into a LanguageTemplate struct.
func ParseYAMLForLanguageTemplate(yamlFile string) (*LanguageTemplate, error) {
var langTemplate LanguageTemplate
var err error
var fileData []byte

fileData, err = ioutil.ReadFile(yamlFile)
if err != nil {
return nil, err
}

err = yaml.Unmarshal(fileData, &langTemplate)
if err != nil {
fmt.Printf("Error with YAML file\n")
return nil, err
}

return &langTemplate, err
}
5 changes: 5 additions & 0 deletions stack/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ type Services struct {
Functions map[string]Function `yaml:"functions,omitempty"`
Provider Provider `yaml:"provider,omitempty"`
}

type LanguageTemplate struct {
Language string `yaml:"lang"`
FProcess string `yaml:"fprocess"`
}
2 changes: 2 additions & 0 deletions template/csharp/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language: csharp
fprocess: dotnet ./root.dll
2 changes: 2 additions & 0 deletions template/node-armhf/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language: node
fprocess: node index.js
2 changes: 2 additions & 0 deletions template/node/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language: node
fprocess: node index.js
2 changes: 2 additions & 0 deletions template/python-armhf/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language: python
fprocess: python index.py
2 changes: 2 additions & 0 deletions template/python/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language: python
fprocess: python index.py
2 changes: 2 additions & 0 deletions template/ruby/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language: ruby
fprocess: ruby index.rb

0 comments on commit 9543c0e

Please sign in to comment.