Skip to content

Commit

Permalink
feat: set builder images in templates and .faas.yaml (#136)
Browse files Browse the repository at this point in the history
This commit adds a .builder.yaml file to each template directory. In the file
there is at the moment a single key/value pair, "default: <image>", where the
actual builder image name is <image>. Using a mapping allows the future
possibility that a user may specify a builder image by name via a flag on the
command line. For example,

```console
faas build --builder native
```

When a project is initialized, the .builder.yaml file is read, and the default
builder is saved in the project's .faas.yaml file. The .faas.yaml file is then
consulted when building an image with `faas build`. If the builder image is
specified, then the builder will use it. Otherwise, it will fallback to the
defaults. This allows developers to create custom builders, and specify them
in the configuration file.

After extracting the builder image from .builder.yaml in the project directory,
this file is deleted.

This commit also adds Verbose to the init command.
  • Loading branch information
lance committed Sep 24, 2020
1 parent 05efee8 commit d6e131f
Show file tree
Hide file tree
Showing 13 changed files with 70 additions and 20 deletions.
17 changes: 12 additions & 5 deletions buildpacks/builder.go
Expand Up @@ -22,18 +22,25 @@ func NewBuilder() *Builder {
return &Builder{}
}

var Runtimes = map[string]string{
var RuntimeToBuildpack = map[string]string{
"quarkus": "quay.io/boson/faas-quarkus-builder",
"node": "quay.io/boson/faas-nodejs-builder",
"go": "quay.io/boson/faas-go-builder",
}

// Build the Function at path.
func (builder *Builder) Build(f faas.Function) (err error) {
// dervive the builder from the specificed runtime
packBuilder, ok := Runtimes[f.Runtime]
if !ok {
return errors.New(fmt.Sprint("unsupported runtime: ", f.Runtime))

// Use the builder found in the Function configuration file
// If one isn't found, use the defaults
var packBuilder string
if f.Builder != "" {
packBuilder = f.Builder
} else {
packBuilder = RuntimeToBuildpack[f.Runtime]
if packBuilder == "" {
return errors.New(fmt.Sprint("unsupported runtime: ", f.Runtime))
}
}

// Build options for the pack client.
Expand Down
49 changes: 37 additions & 12 deletions client.go
Expand Up @@ -4,13 +4,17 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"

"gopkg.in/yaml.v2"
)

const (
DefaultRegistry = "docker.io"
DefaultRuntime = "go"
DefaultTrigger = "http"
DefaultRegistry = "docker.io"
DefaultRuntime = "go"
DefaultTrigger = "http"
)

// Client for managing Function instances.
Expand Down Expand Up @@ -117,15 +121,15 @@ type DNSProvider interface {
func New(options ...Option) *Client {
// Instantiate client with static defaults.
c := &Client{
builder: &noopBuilder{output: os.Stdout},
pusher: &noopPusher{output: os.Stdout},
deployer: &noopDeployer{output: os.Stdout},
updater: &noopUpdater{output: os.Stdout},
runner: &noopRunner{output: os.Stdout},
remover: &noopRemover{output: os.Stdout},
lister: &noopLister{output: os.Stdout},
dnsProvider: &noopDNSProvider{output: os.Stdout},
progressListener: &noopProgressListener{},
builder: &noopBuilder{output: os.Stdout},
pusher: &noopPusher{output: os.Stdout},
deployer: &noopDeployer{output: os.Stdout},
updater: &noopUpdater{output: os.Stdout},
runner: &noopRunner{output: os.Stdout},
remover: &noopRemover{output: os.Stdout},
lister: &noopLister{output: os.Stdout},
dnsProvider: &noopDNSProvider{output: os.Stdout},
progressListener: &noopProgressListener{},
}

// Apply passed options, which take ultimate precidence.
Expand Down Expand Up @@ -345,6 +349,27 @@ func (c *Client) Initialize(cfg Function) (err error) {
return
}

// Check if template specifies a builder image. If so, add to configuration
builderFilePath := filepath.Join(f.Root, ".builders.yaml")
if builderConfig, err := ioutil.ReadFile(builderFilePath); err == nil {
// A .builder file was found. Read the default builder and set in the config file
// TODO: A command line flag could be used to specify non-default builders
builders := make(map[string]string)
if err := yaml.Unmarshal(builderConfig, builders); err == nil {
f.Builder = builders["default"]
if c.verbose {
fmt.Printf("Builder: %s\n", f.Builder)
}
}
// Remove the builders.yaml file so the user is not confused by a
// configuration file that is only used for project creation/initialization
if err := os.Remove(builderFilePath); err != nil {
if c.verbose {
fmt.Printf("Cannot remove %v. %v\n", builderFilePath, err)
}
}
}

// Write out the config.
if err = writeConfig(f); err != nil {
return
Expand Down
2 changes: 1 addition & 1 deletion cmd/completion_util.go
Expand Up @@ -28,7 +28,7 @@ func CompleteFunctionList(cmd *cobra.Command, args []string, toComplete string)
}
func CompleteRuntimeList(cmd *cobra.Command, args []string, toComplete string) (strings []string, directive cobra.ShellCompDirective) {
strings = []string{}
for lang := range buildpacks.Runtimes {
for lang := range buildpacks.RuntimeToBuildpack {
strings = append(strings, lang)
}
directive = cobra.ShellCompDirectiveDefault
Expand Down
8 changes: 7 additions & 1 deletion cmd/init.go
Expand Up @@ -55,7 +55,9 @@ func runInit(cmd *cobra.Command, args []string) error {
Trigger: config.Trigger,
}

client := faas.New(faas.WithTemplates(config.Templates))
client := faas.New(
faas.WithTemplates(config.Templates),
faas.WithVerbose(config.Verbose))

return client.Initialize(function)
}
Expand All @@ -82,6 +84,9 @@ type initConfig struct {
// Function which will be invoked with CloudEvents.
Trigger string

// Verbose output
Verbose bool

// Confirm: confirm values arrived upon from environment plus flags plus defaults,
// with interactive prompting (only applicable when attached to a TTY).
Confirm bool
Expand All @@ -103,6 +108,7 @@ func newInitConfig(args []string) initConfig {
Templates: viper.GetString("templates"),
Trigger: viper.GetString("trigger"),
Confirm: viper.GetBool("confirm"),
Verbose: viper.GetBool("verbose"),
}
}

Expand Down
3 changes: 3 additions & 0 deletions config.go
Expand Up @@ -19,6 +19,7 @@ type config struct {
Runtime string `yaml:"runtime"`
Image string `yaml:"image"`
Trigger string `yaml:"trigger"`
Builder string `yaml:"builder"`
// Add new values to the toConfig/fromConfig functions.
}

Expand Down Expand Up @@ -53,6 +54,7 @@ func fromConfig(c config) (f Function) {
Runtime: c.Runtime,
Image: c.Image,
Trigger: c.Trigger,
Builder: c.Builder,
}
}

Expand All @@ -64,6 +66,7 @@ func toConfig(f Function) config {
Runtime: f.Runtime,
Image: f.Image,
Trigger: f.Trigger,
Builder: f.Builder,
}
}

Expand Down
3 changes: 3 additions & 0 deletions function.go
Expand Up @@ -40,6 +40,9 @@ type Function struct {
// If Image is provided, it overrides the default of concatenating
// "Repo+Name:latest" to derive the Image.
Image string

// Builder represents the CNCF Buildpack builder image for a function
Builder string
}

// NewFunction loads a Function from a path on disk. use .Initialized() to determine if
Expand Down
2 changes: 1 addition & 1 deletion pkged.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions templates/go/events/.builders.yaml
@@ -0,0 +1 @@
default: quay.io/boson/faas-go-builder
1 change: 1 addition & 0 deletions templates/go/http/.builders.yaml
@@ -0,0 +1 @@
default: quay.io/boson/faas-go-builder
1 change: 1 addition & 0 deletions templates/node/events/.builders.yaml
@@ -0,0 +1 @@
default: quay.io/boson/faas-nodejs-builder
1 change: 1 addition & 0 deletions templates/node/http/.builders.yaml
@@ -0,0 +1 @@
default: quay.io/boson/faas-nodejs-builder
1 change: 1 addition & 0 deletions templates/quarkus/events/.builders.yaml
@@ -0,0 +1 @@
default: quay.io/boson/faas-quarkus-builder
1 change: 1 addition & 0 deletions templates/quarkus/http/.builders.yaml
@@ -0,0 +1 @@
default: quay.io/boson/faas-quarkus-builder

0 comments on commit d6e131f

Please sign in to comment.