build: keep "buildx install" behavior

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax 2022-11-03 23:35:45 +01:00
parent d1cabdff99
commit 997846918e
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7
2 changed files with 87 additions and 50 deletions

View File

@ -45,7 +45,7 @@ func newBuilderError(warn bool, err error) error {
//nolint:gocyclo //nolint:gocyclo
func processBuilder(dockerCli command.Cli, cmd *cobra.Command, args, osargs []string) ([]string, []string, []string, error) { func processBuilder(dockerCli command.Cli, cmd *cobra.Command, args, osargs []string) ([]string, []string, []string, error) {
var useLegacy, useBuilder bool var useLegacy, useBuilder, useAlias bool
var envs []string var envs []string
// check DOCKER_BUILDKIT env var is present and // check DOCKER_BUILDKIT env var is present and
@ -68,6 +68,7 @@ func processBuilder(dockerCli command.Cli, cmd *cobra.Command, args, osargs []st
aliasMap := dockerCli.ConfigFile().Aliases aliasMap := dockerCli.ConfigFile().Aliases
if v, ok := aliasMap[keyBuilderAlias]; ok { if v, ok := aliasMap[keyBuilderAlias]; ok {
useBuilder = true useBuilder = true
useAlias = true
builderAlias = v builderAlias = v
} }
@ -110,10 +111,11 @@ func processBuilder(dockerCli command.Cli, cmd *cobra.Command, args, osargs []st
// always create a local docker image (default context builder). This is // always create a local docker image (default context builder). This is
// for better backward compatibility in case where a user could switch to // for better backward compatibility in case where a user could switch to
// a docker container builder with "docker buildx --use foo" which does // a docker container builder with "docker buildx --use foo" which does
// not --load by default. Also makes sure that an arbitrary builder name is // not --load by default. Also makes sure that an arbitrary builder name
// not being set in the command line or in the environment before setting // is not being set in the command line or in the environment before
// the default context in env vars. // setting the default context and keep "buildx install" behavior if being
if forwarded && !hasBuilderName(args, os.Environ()) { // set (builder alias).
if forwarded && !useAlias && !hasBuilderName(args, os.Environ()) {
envs = append([]string{"BUILDX_BUILDER=" + dockerCli.CurrentContext()}, envs...) envs = append([]string{"BUILDX_BUILDER=" + dockerCli.CurrentContext()}, envs...)
} }

View File

@ -3,9 +3,11 @@ package main
import ( import (
"bytes" "bytes"
"os" "os"
"path/filepath"
"testing" "testing"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/context/store"
"github.com/docker/cli/cli/flags" "github.com/docker/cli/cli/flags"
"github.com/docker/cli/internal/test/output" "github.com/docker/cli/internal/test/output"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
@ -14,36 +16,38 @@ import (
var pluginFilename = "docker-buildx" var pluginFilename = "docker-buildx"
func TestBuildWithBuildx(t *testing.T) { func TestBuildWithBuilder(t *testing.T) {
dir := fs.NewDir(t, t.Name(), testcases := []struct {
fs.WithFile(pluginFilename, `#!/bin/sh name string
echo '{"SchemaVersion":"0.1.0","Vendor":"Docker Inc.","Version":"v0.6.3","ShortDescription":"Build with BuildKit"}'`, fs.WithMode(0777)), context string
) builder string
defer dir.Remove() alias bool
expectedEnvs []string
var b bytes.Buffer }{
{
t.Setenv("DOCKER_CONTEXT", "default") name: "default",
dockerCli, err := command.NewDockerCli(command.WithInputStream(discard), command.WithCombinedStreams(&b)) context: "default",
assert.NilError(t, err) alias: false,
assert.NilError(t, dockerCli.Initialize(flags.NewClientOptions())) expectedEnvs: []string{"BUILDX_BUILDER=default"},
dockerCli.ConfigFile().CLIPluginsExtraDirs = []string{dir.Path()} },
{
tcmd := newDockerCommand(dockerCli) name: "custom context",
tcmd.SetArgs([]string{"build", "."}) context: "foo",
alias: false,
cmd, args, err := tcmd.HandleGlobalFlags() expectedEnvs: []string{"BUILDX_BUILDER=foo"},
assert.NilError(t, err) },
{
var envs []string name: "custom builder name",
args, os.Args, envs, err = processBuilder(dockerCli, cmd, args, os.Args) builder: "mybuilder",
assert.NilError(t, err) alias: false,
assert.DeepEqual(t, []string{builderDefaultPlugin, "build", "."}, args) expectedEnvs: nil,
assert.DeepEqual(t, []string{"BUILDX_BUILDER=default"}, envs) },
} {
name: "buildx install",
func TestBuildWithBuildxAndBuilder(t *testing.T) { alias: true,
t.Setenv("BUILDX_BUILDER", "mybuilder") expectedEnvs: nil,
},
}
dir := fs.NewDir(t, t.Name(), dir := fs.NewDir(t, t.Name(),
fs.WithFile(pluginFilename, `#!/bin/sh fs.WithFile(pluginFilename, `#!/bin/sh
@ -51,25 +55,56 @@ echo '{"SchemaVersion":"0.1.0","Vendor":"Docker Inc.","Version":"v0.6.3","ShortD
) )
defer dir.Remove() defer dir.Remove()
var b bytes.Buffer for _, tt := range testcases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
if tt.builder != "" {
t.Setenv("BUILDX_BUILDER", tt.builder)
}
t.Setenv("DOCKER_CONTEXT", "default") var b bytes.Buffer
dockerCli, err := command.NewDockerCli(command.WithInputStream(discard), command.WithCombinedStreams(&b)) dockerCli, err := command.NewDockerCli(command.WithInputStream(discard), command.WithCombinedStreams(&b))
assert.NilError(t, err) assert.NilError(t, err)
assert.NilError(t, dockerCli.Initialize(flags.NewClientOptions())) assert.NilError(t, dockerCli.Initialize(flags.NewClientOptions()))
dockerCli.ConfigFile().CLIPluginsExtraDirs = []string{dir.Path()}
tcmd := newDockerCommand(dockerCli) if tt.context != "" {
tcmd.SetArgs([]string{"build", "."}) if tt.context != command.DefaultContextName {
assert.NilError(t, dockerCli.ContextStore().CreateOrUpdate(store.Metadata{
Name: tt.context,
Endpoints: map[string]interface{}{
"docker": map[string]interface{}{
"host": "unix://" + filepath.Join(t.TempDir(), "docker.sock"),
},
},
}))
}
opts := flags.NewClientOptions()
opts.Common.Context = tt.context
assert.NilError(t, dockerCli.Initialize(opts))
}
cmd, args, err := tcmd.HandleGlobalFlags() dockerCli.ConfigFile().CLIPluginsExtraDirs = []string{dir.Path()}
assert.NilError(t, err) if tt.alias {
dockerCli.ConfigFile().Aliases = map[string]string{"builder": "buildx"}
}
var envs []string tcmd := newDockerCommand(dockerCli)
args, os.Args, envs, err = processBuilder(dockerCli, cmd, args, os.Args) tcmd.SetArgs([]string{"build", "."})
assert.NilError(t, err)
assert.DeepEqual(t, []string{builderDefaultPlugin, "build", "."}, args) cmd, args, err := tcmd.HandleGlobalFlags()
assert.Check(t, len(envs) == 0) assert.NilError(t, err)
var envs []string
args, os.Args, envs, err = processBuilder(dockerCli, cmd, args, os.Args)
assert.NilError(t, err)
assert.DeepEqual(t, []string{builderDefaultPlugin, "build", "."}, args)
if tt.expectedEnvs != nil {
assert.DeepEqual(t, tt.expectedEnvs, envs)
} else {
assert.Check(t, len(envs) == 0)
}
})
}
} }
func TestBuildkitDisabled(t *testing.T) { func TestBuildkitDisabled(t *testing.T) {