mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
bake: initial implementation
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
104
commands/bake.go
Normal file
104
commands/bake.go
Normal 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
|
||||
}
|
@ -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 {
|
||||
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user