bake: initial implementation

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi
2019-04-05 00:04:19 -07:00
parent 9129a49409
commit a932d52e35
127 changed files with 23933 additions and 95 deletions

104
commands/bake.go Normal file
View File

@ -0,0 +1,104 @@
package commands
import (
"encoding/json"
"fmt"
"os"
"github.com/docker/cli/cli/command"
"github.com/moby/buildkit/util/appcontext"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/tonistiigi/buildx/bake"
)
type bakeOptions struct {
files []string
printOnly bool
overrides []string
commonOptions
}
func runBake(dockerCli command.Cli, targets []string, in bakeOptions) error {
ctx := appcontext.Context()
if len(in.files) == 0 {
files, err := defaultFiles()
if err != nil {
return err
}
if len(files) == 0 {
return errors.Errorf("no compose.yml or dockerbuild.hcl found, speficy build file with -f/--file")
}
in.files = files
}
if len(targets) == 0 {
targets = []string{"default"}
}
m, err := bake.ReadTargets(ctx, in.files, targets, in.overrides)
if err != nil {
return err
}
if in.printOnly {
dt, err := json.MarshalIndent(map[string]map[string]bake.Target{"target": m}, "", " ")
if err != nil {
return err
}
fmt.Fprintln(dockerCli.Out(), string(dt))
return nil
}
bo, err := bake.TargetsToBuildOpt(m)
if err != nil {
return err
}
return buildTargets(ctx, dockerCli, bo, in.progress)
}
func defaultFiles() ([]string, error) {
fns := []string{
"compose.yml", // support app
"dockerbuild.json",
"dockerbuild-override.json",
"dockerbuild.hcl",
"dockerbuild-override.hcl",
}
out := make([]string, 0, len(fns))
for _, f := range fns {
if _, err := os.Stat(f); err != nil {
if os.IsNotExist(errors.Cause(err)) {
continue
}
return nil, err
}
out = append(out, f)
}
return out, nil
}
func bakeCmd(dockerCli command.Cli) *cobra.Command {
var options bakeOptions
cmd := &cobra.Command{
Use: "bake [OPTIONS] [TARGET...]",
Aliases: []string{"f"},
Short: "Build from a file",
RunE: func(cmd *cobra.Command, args []string) error {
return runBake(dockerCli, args, options)
},
}
flags := cmd.Flags()
flags.StringArrayVarP(&options.files, "file", "f", []string{}, "Build definition file")
flags.BoolVar(&options.printOnly, "print", false, "Print the options without building")
flags.StringArrayVar(&options.overrides, "set", nil, "Override target value (eg: target.key=value)")
commonFlags(&options.commonOptions, flags)
return cmd
}

View File

@ -10,12 +10,14 @@ import (
"github.com/moby/buildkit/session/auth/authprovider"
"github.com/moby/buildkit/util/appcontext"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/tonistiigi/buildx/build"
"github.com/tonistiigi/buildx/driver"
"github.com/tonistiigi/buildx/util/progress"
)
type buildOptions struct {
commonOptions
contextPath string
dockerfileName string
tags []string
@ -34,9 +36,6 @@ type buildOptions struct {
// cgroupParent string
// isolation string
// quiet bool
noCache bool
progress string
pull bool
cacheFrom []string
// compress bool
// securityOpt []string
@ -51,6 +50,12 @@ type buildOptions struct {
outputs []string
}
type commonOptions struct {
noCache bool
progress string
pull bool
}
func runBuild(dockerCli command.Cli, in buildOptions) error {
ctx := appcontext.Context()
@ -94,6 +99,10 @@ func runBuild(dockerCli command.Cli, in buildOptions) error {
}
opts.Exports = outputs
return buildTargets(ctx, dockerCli, map[string]build.Options{"default": opts}, in.progress)
}
func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode string) error {
d, err := driver.GetDriver(ctx, "buildx-buildkit-default", nil, dockerCli.Client())
if err != nil {
return err
@ -101,10 +110,9 @@ func runBuild(dockerCli command.Cli, in buildOptions) error {
ctx2, cancel := context.WithCancel(context.TODO())
defer cancel()
pw := progress.NewPrinter(ctx2, os.Stderr, in.progress)
pw := progress.NewPrinter(ctx2, os.Stderr, progressMode)
_, err = build.Build(ctx, []driver.Driver{d}, opts, pw)
return err
}
@ -139,9 +147,7 @@ func buildCmd(dockerCli command.Cli) *cobra.Command {
// flags.StringVar(&options.cgroupParent, "cgroup-parent", "", "Optional parent cgroup for the container")
// flags.StringVar(&options.isolation, "isolation", "", "Container isolation technology")
flags.StringArrayVar(&options.labels, "label", []string{}, "Set metadata for an image")
flags.BoolVar(&options.noCache, "no-cache", false, "Do not use cache when building the image")
// flags.BoolVarP(&options.quiet, "quiet", "q", false, "Suppress the build output and print image ID on success")
flags.BoolVar(&options.pull, "pull", false, "Always attempt to pull a newer version of the image")
flags.StringSliceVar(&options.cacheFrom, "cache-from", []string{}, "Images to consider as cache sources")
// flags.BoolVar(&options.compress, "compress", false, "Compress the build context using gzip")
@ -158,18 +164,23 @@ func buildCmd(dockerCli command.Cli) *cobra.Command {
flags.StringArrayVar(&options.platforms, "platform", platformsDefault, "Set target platform for build")
// flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
flags.StringVar(&options.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
flags.StringArrayVar(&options.secrets, "secret", []string{}, "Secret file to expose to the build: id=mysecret,src=/local/secret")
flags.StringArrayVar(&options.ssh, "ssh", []string{}, "SSH agent socket or keys to expose to the build (format: default|<id>[=<socket>|<key>[,<key>]])")
flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, "Output destination (format: type=local,dest=path)")
commonFlags(&options.commonOptions, flags)
return cmd
}
func commonFlags(options *commonOptions, flags *pflag.FlagSet) {
flags.BoolVar(&options.noCache, "no-cache", false, "Do not use cache when building the image")
flags.StringVar(&options.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
flags.BoolVar(&options.pull, "pull", false, "Always attempt to pull a newer version of the image")
}
func listToMap(values []string) map[string]string {
result := make(map[string]string, len(values))
for _, value := range values {

View File

@ -21,5 +21,6 @@ func NewRootCmd(dockerCli command.Cli) *cobra.Command {
func addCommands(cmd *cobra.Command, dockerCli command.Cli) {
cmd.AddCommand(
buildCmd(dockerCli),
bakeCmd(dockerCli),
)
}